github.com/cosmos/cosmos-sdk@v0.50.10/docs/architecture/adr-053-go-module-refactoring.md (about)

     1  # ADR 053: Go Module Refactoring
     2  
     3  ## Changelog
     4  
     5  * 2022-04-27: First Draft
     6  
     7  ## Status
     8  
     9  PROPOSED
    10  
    11  ## Abstract
    12  
    13  The current SDK is built as a single monolithic go module. This ADR describes
    14  how we refactor the SDK into smaller independently versioned go modules
    15  for ease of maintenance.
    16  
    17  ## Context
    18  
    19  Go modules impose certain requirements on software projects with respect to
    20  stable version numbers (anything above 0.x) in that [any API breaking changes
    21  necessitate a major version](https://go.dev/doc/modules/release-workflow#breaking)
    22  increase which technically creates a new go module
    23  (with a v2, v3, etc. suffix).
    24  
    25  [Keeping modules API compatible](https://go.dev/blog/module-compatibility) in
    26  this way requires a fair amount of fair thought and discipline.
    27  
    28  The Cosmos SDK is a fairly large project which originated before go modules
    29  came into existence and has always been under a v0.x release even though
    30  it has been used in production for years now, not because it isn't production
    31  quality software, but rather because the API compatibility guarantees required
    32  by go modules are fairly complex to adhere to with such a large project.
    33  Up to now, it has generally been deemed more important to be able to break the
    34  API if needed rather than require all users update all package import paths
    35  to accommodate breaking changes causing v2, v3, etc. releases. This is in
    36  addition to the other complexities related to protobuf generated code that will
    37  be addressed in a separate ADR.
    38  
    39  Nevertheless, the desire for semantic versioning has been [strong in the
    40  community](https://github.com/cosmos/cosmos-sdk/discussions/10162) and the
    41  single go module release process has made it very hard to
    42  release small changes to isolated features in a timely manner. Release cycles
    43  often exceed six months which means small improvements done in a day or
    44  two get bottle-necked by everything else in the monolithic release cycle.
    45  
    46  ## Decision
    47  
    48  To improve the current situation, the SDK is being refactored into multiple
    49  go modules within the current repository. There has been a [fair amount of
    50  debate](https://github.com/cosmos/cosmos-sdk/discussions/10582#discussioncomment-1813377)
    51  as to how to do this, with some developers arguing for larger vs smaller
    52  module scopes. There are pros and cons to both approaches (which will be
    53  discussed below in the [Consequences](#consequences) section), but the
    54  approach being adopted is the following:
    55  
    56  * a go module should generally be scoped to a specific coherent set of
    57  functionality (such as math, errors, store, etc.)
    58  * when code is removed from the core SDK and moved to a new module path, every 
    59  effort should be made to avoid API breaking changes in the existing code using
    60  aliases and wrapper types (as done in https://github.com/cosmos/cosmos-sdk/pull/10779
    61  and https://github.com/cosmos/cosmos-sdk/pull/11788)
    62  * new go modules should be moved to a standalone domain (`cosmossdk.io`) before
    63  being tagged as `v1.0.0` to accommodate the possibility that they may be
    64  better served by a standalone repository in the future
    65  * all go modules should follow the guidelines in https://go.dev/blog/module-compatibility
    66  before `v1.0.0` is tagged and should make use of `internal` packages to limit
    67  the exposed API surface
    68  * the new go module's API may deviate from the existing code where there are
    69  clear improvements to be made or to remove legacy dependencies (for instance on
    70  amino or gogo proto), as long the old package attempts
    71  to avoid API breakage with aliases and wrappers
    72  * care should be taken when simply trying to turn an existing package into a
    73  new go module: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository.
    74  In general, it seems safer to just create a new module path (appending v2, v3, etc.
    75  if necessary), rather than trying to make an old package a new module.
    76  
    77  ## Consequences
    78  
    79  ### Backwards Compatibility
    80  
    81  If the above guidelines are followed to use aliases or wrapper types pointing
    82  in existing APIs that point back to the new go modules, there should be no or
    83  very limited breaking changes to existing APIs.
    84  
    85  ### Positive
    86  
    87  * standalone pieces of software will reach `v1.0.0` sooner
    88  * new features to specific functionality will be released sooner 
    89  
    90  ### Negative
    91  
    92  * there will be more go module versions to update in the SDK itself and
    93  per-project, although most of these will hopefully be indirect
    94  
    95  ### Neutral
    96  
    97  ## Further Discussions
    98  
    99  Further discussions are occurring in primarily in
   100  https://github.com/cosmos/cosmos-sdk/discussions/10582 and within
   101  the Cosmos SDK Framework Working Group.
   102  
   103  ## References
   104  
   105  * https://go.dev/doc/modules/release-workflow
   106  * https://go.dev/blog/module-compatibility
   107  * https://github.com/cosmos/cosmos-sdk/discussions/10162
   108  * https://github.com/cosmos/cosmos-sdk/discussions/10582
   109  * https://github.com/cosmos/cosmos-sdk/pull/10779
   110  * https://github.com/cosmos/cosmos-sdk/pull/11788