blob: 7b3ee49ef29d3fc548cedd31bddeb62d2411486a [file] [log] [blame] [view]
Russ Coxe58eda12018-03-20 13:16:16 -04001# Proposal: Versioned Go Modules
2
3Author: Russ Cox\
4Last Updated: March 20, 2018\
5Discussion: https://golang.org/issue/24301
6
7## Abstract
8
9We propose to add awareness of package versions to the Go toolchain, especially the `go` command.
10
11## Background
12
13The first half of the blog post [Go += Package Versioning](https://research.swtch.com/vgo-intro) presents detailed background for this change.
14In short, it is long past time to add versions to the working vocabulary of both Go developers and our tools,
15and this proposal describes a way to do that.
16
17[Semantic versioning](https://semver.org) is the name given to an established convention for assigning version numbers
18to projects.
19In its simplest form, a version number is MAJOR.MINOR.PATCH, where MAJOR, MINOR, and PATCH
20are decimal numbers.
21The syntax used in this proposal follows the widespread convention of
22adding a “v” prefix: vMAJOR.MINOR.PATCH.
23Incrementing MAJOR indicates an expected breaking change.
24Otherwise, a later version is expected to be backwards compatible
25with earlier versions within the same MAJOR version sequence.
26Incrementing MINOR indicates a significant change or new features.
27Incrementing PATCH is meant to be reserved for very small, very safe changes,
28such as small bug fixes or critical security patches.
29
30The sequence of [vgo-related blog posts](https://research.swtch.com/vgo) presents more detail
31about the proposal.
32
33## Proposal
34
35I propose to add versioning to Go using the following approach.
36
371. Introduce the concept of a _Go module_, which is a group of
38 packages that share a common prefix, the _module path_, and are versioned together as a single unit.
39 Most projects will adopt a workflow in which a version-control repository
40 corresponds exactly to a single module.
41 Larger projects may wish to adopt a workflow in which a
42 version-control repository can hold multiple modules.
43 Both workflows will be supported.
44
452. Assign version numbers to modules by tagging specific commits
46 with [semantic versions](https://semver.org) such as `v1.2.0`.
47 (See
He Liue71fd132018-03-25 18:20:57 +000048 the [Defining Go Modules](https://research.swtch.com/vgo-module) post
Russ Coxe58eda12018-03-20 13:16:16 -040049 for details, including how to tag multi-module repositories.)
50
513. Adopt [semantic import versioning](https://research.swtch.com/vgo-import),
52 in which each major version has a distinct import path.
53 Specifically, an import path contains a module path, a version number,
54 and the the path to a specific package inside the module.
55 If the major version is v0 or v1, then the version number element
56 must be omitted; otherwise it must be included.
57
58 <p style="text-align:center">
59 <img width=343 height=167 src="24301/impver.png" srcset="24301/impver.png 1x, 24301/[email protected] 1.5x, 24301/[email protected] 2x, 24301/[email protected] 3x, 24301/[email protected] 4x">
60 </p>
61
62 The packages imported as `my/thing/sub/pkg`, `my/thing/v2/sub/pkg`, and `my/thing/v3/sub/pkg`
63 come from major versions v1, v2, and v3 of the module `my/thing`,
64 but the build treats them simply as three different packages.
65 A program that imports all three will have all three linked into the final binary,
66 just as if they were `my/red/pkg`, `my/green/pkg`, and `my/blue/pkg`
67 or any other set of three different import paths.
68
69 Note that only the major version appears in the import path: `my/thing/v1.2/sub/pkg` is not allowed.
70
71
724. Explicitly adopt the “import compatibility rule”:
73
74 > _If an old package and a new package have the same import path,_\
75 > _the new package must be backwards compatible with the old package._
76
77 The Go project has encouraged this convention from the start
78 of the project, but this proposal gives it more teeth:
79 upgrades by package users will succeed or fail
80 only to the extent that package authors follow the import
81 compatibility rule.
82
83 The import compatibility rule only applies to tagged
84 releases starting at v1.0.0.
85 Prerelease (vX.Y.Z-anything) and v0.Y.Z versions
86 need not follow compatibility with earlier versions,
87 nor do they impose requirements on future versions.
88 In contrast, tagging a commit vX.Y.Z for X ≥ 1 explicitly
89 indicates “users can expect this module to be stable.”
90
91 In general, users should expect a module to follow
92 the [Go 1 compatibility rules](https://golang.org/doc/go1compat#expectations)
93 once it reaches v1.0.0,
94 unless the module's documentation clearly states exceptions.
95
965. Record each module's path and dependency requirements in a
97 [`go.mod` file](XXX) stored in the root of the module's file tree.
98
996. To decide which module versions to use in a given build,
100 apply [minimal version selection](https://research.swtch.com/vgo-mvs):
101 gather the transitive closure of all the listed requirements
102 and then remove duplicates of a given major version of a module
103 by keeping the maximum requested version,
104 which is also the minimum version satisfying all listed requirements.
105
106 Minimal version selection has two critical properties.
107 First, it is trivial to implement and understand.
108 Second, it never chooses a module version not listed in some `go.mod` file
109 involved in the build: new versions are not incorporated
110 simply because they have been published.
111 The second property produces [high-fidelity builds](XXX)
112 and makes sure that upgrades only happen when
113 developers request them, never unexpectedly.
114
1157. Define a specific zip file structure as the
116 “interchange format” for Go modules.
117 The vast majority of developers will work directly with
118 version control and never think much about these zip files,
119 if at all, but having a single representation
120 enables proxies, simplifies analysis sites like godoc.org
121 or continuous integration, and likely enables more
122 interesting tooling not yet envisioned.
123
1248. Define a URL schema for fetching Go modules from proxies,
125 used both for installing modules using custom domain names
126 and also when the `$GOPROXY` environment variable is set.
127 The latter allows companies and individuals to send all
128 module download requests through a proxy for security,
129 availability, or other reasons.
130
1319. Allow running the `go` command in file trees outside GOPATH,
132 provided there is a `go.mod` in the current directory or a
133 parent directory.
134 That `go.mod` file defines the mapping from file system to import path
135 as well as the specific module versions used in the build.
136 See the [Versioned Go Commands](https://research.swtch.com/vgo-cmd) post for details.
137
13810. Disallow use of `vendor` directories, except in one limited use:
139 a `vendor` directory at the top of the file tree of the top-level module
140 being built is still applied to the build,
141 to continue to allow self-contained application repositories.
142 (Ignoring other `vendor` directories ensures that
143 Go returns to builds in which each import path has the same
144 meaning throughout the build
145 and establishes that only one copy of a package with a given import
146 path is used in a given build.)
147
148The “[Tour of Versioned Go](https://research.swtch.com/vgo-tour)”
149blog post demonstrates how most of this fits together to create a smooth user experience.
150
151## Rationale
152
153Go has struggled with how to incorporate package versions since `goinstall`,
154the predecessor to `go get`, was released eight years ago.
155This proposal is the result of eight years of experience with `goinstall` and `go get`,
156careful examination of how other languages approach the versioning problem,
157and lessons learned from Dep, the experimental Go package management tool released in January 2017.
158
159A few people have asked why we should add the concept of versions to our tools at all.
160Packages do have versions, whether the tools understand them or not.
161Adding explicit support for versions
162lets tools and developers communicate more clearly when
163specifying a program to be built, run, or analyzed.
164
165At the start of the process that led to this proposal, almost two years ago,
166we all believed the answer would be to follow the package versioning approach
167exemplified by Ruby's Bundler and then Rust's Cargo:
168tagged semantic versions,
169a hand-edited dependency constraint file known as a manifest,
170a machine-generated transitive dependency description known as a lock file,
171a version solver to compute a lock file satisfying the manifest,
172and repositories as the unit of versioning.
173Dep, the community effort led by Sam Boyer, follows this plan almost exactly
174and was originally intended to serve as the model for `go` command
175integration.
176Dep has been a significant help for Go developers
177and a positive step for the Go ecosystem.
178
179Early on, we talked about Dep simply becoming `go dep`,
180serving as the prototype of `go` command integration.
181However, the more I examined the details of the Bundler/Cargo/Dep
182approach and what they would mean for Go, especially built into the `go` command,
183a few of the details seemed less and less a good fit.
184This proposal adjusts those details in the hope of
185shipping a system that is easier for developers to understand
186and to use.
187
188### Semantic versions, constraints, and solvers
189
190Semantic versions are a reasonable convention for
191specifying software versions,
192and version control tags written as semantic versions
193have a clear meaning,
194but the [semver spec](https://semver.org/) critically does not
195prescribe how to build a system using them.
196What tools should do with the version information?
197Dave Cheney's 2015 [proposal to adopt semantic versioning](https://golang.org/issue/12302)
198was eventually closed exactly because, even though everyone
199agreed semantic versions seemed like a good idea,
200we didn't know the answer to the question of what to do with them.
201
202The Bundler/Cargo/Dep approach is one answer.
203Allow authors to specify arbitrary constraints on their dependencies.
204Build a given target by collecting all its dependencies
205recursively and finding a configuration satisfying all those
206constraints.
207
208Unfortunately, the arbitrary constraints make finding a
209satisfying configuration very difficult.
210There may be many satisfying configurations, with no clear way to choose just one.
211For example, if the only two ways to build A are by using B 1 and C 2
212or by using B 2 and C 1, which should be preferred, and how should developers remember?
213Or there may be no satisfying configuration.
214Also, it can be very difficult to tell whether there are many, one, or no
215satisfying configurations:
216allowing arbitrary constraints makes
217version solving problem an NP-complete problem,
218[equivalent to solving SAT](https://research.swtch.com/version-sat).
219In fact, most package managers now rely on SAT solvers
220to decide which packages to install.
221But the general problem remains:
222there may be many equally good configurations,
223with no clear way to choose between them,
224there may be a single best configuration,
225or there may be no good configurations,
226and it can be very expensive to determine
227which is the case in a given build.
228
229This proposal's approach is a new answer, in which authors can specify
230only limited constraints on dependencies: only the minimum required versions.
231Like in Bundler/Cargo/Dep, this proposal builds a given target by
232collecting all dependencies recursively and then finding
233a configuration satisfying all constraints.
234However, unlike in Bundler/Cargo/Dep, the process of finding a
235satisfying configuration is trivial.
236As explained in the [minimal version selection](https://research.swtch.com/vgo-mvs) post,
237a satisfying configuration always exists,
238and the set of satisfying configurations forms a lattice with
239a unique minimum.
240That unique minimum is the configuration that uses exactly the
241specified version of each module, resolving multiple constraints
242for a given module by selecting the maximum constraint,
243or equivalently the minimum version that satisfies all constraints.
244That configuration is trivial to compute and easy for developers
245to understand and predict.
246
247### Build Control
248
249A module's dependencies must clearly be given some control over that module's build.
250For example, if A uses dependency B, which uses a feature of dependency C introduced in C 1.5,
251B must be able to ensure that A's build uses C 1.5 or later.
252
253At the same time, for builds to remain predictable and understandable,
254a build system cannot give dependencies arbitrary, fine-grained control
255over the top-level build.
256That leads to conflicts and surprises.
257For example, suppose B declares that it requires an even version of D, while C declares that it requires a prime version of D.
258D is frequently updated and is up to D 1.99.
259Using B or C in isolation, it's always possible to use a relatively recent version of D (D 1.98 or D 1.97, respectively).
260But when A uses both B and C,
261a SAT solver-based build silently selects the much older (and buggier) D 1.2 instead.
262To the extent that SAT solver-based build systems actually work,
263it is because dependencies don't choose to exercise this level of control.
264But then why allow them that control in the first place?
265
266Although the hypothetical about prime and even versions is clearly unlikely,
267real problems do arise.
268For example, issue [kubernetes/client-go#325](https://github.com/kubernetes/client-go/issues/325) was filed in November 2017,
269complaining that the Kubernetes Go client pinned builds to a specific version of `gopkg.in/yaml.v2` from
270September 2015, two years earlier.
271When a developer tried to use
272a new feature of that YAML library in a program that already
273used the Kubernetes Go client,
274even after attempting to upgrade to the latest possible version,
275code using the new feature failed to compile,
276because “latest” had been constrained by the Kubernetes requirement.
277In this case, the use of a two-year-old YAML library version may be entirely reasonable within the context of the Kubernetes code base,
278and clearly the Kubernetes authors should have complete
279control over their own builds,
280but that level of control does not make sense to extend to other developers' builds.
281The issue was closed after a change in February 2018
282to update the specific YAML version pinned to one from July 2017.
283But the issue is not really “fixed”:
284Kubernetes still pins a specific, increasingly old version of the YAML library.
285The fundamental problem is that the build system
286allows the Kubernetes Go client to do this at all,
287at least when used as a dependency in a larger build.
288
289This proposal aims to balance
290allowing dependencies enough control to ensure a successful
291build with not allowing them so much control that they break the build.
292Minimum requirements combine without conflict,
293so it is feasible (even easy) to gather them from all dependencies,
294and they make it impossible to pin older versions,
295as Kubernetes does.
296Minimal version selection gives
297the top-level module in the build additional control,
298allowing it to exclude specific module versions
299or replace others with different code,
300but those exclusions and replacements only apply
301when found in the top-level module, not when the module
302is a dependency in a larger build.
303
304A module author is therefore in complete control of
305that module's build when it is the main program being built,
306but not in complete control of other users' builds that depend on the module.
307I believe this distinction will make this proposal
308scale to much larger, more distributed code bases than
309the Bundler/Cargo/Dep approach.
310
311### Ecosystem Fragmentation
312
313Allowing all modules involved in a build to impose arbitrary
314constraints on the surrounding build harms not just that build
315but the entire language ecosystem.
316If the author of popular package P finds that
317dependency D 1.5 has introduced a change that
318makes P no longer work,
319other systems encourage the author of P to issue
320a new version that explicitly declares it needs D < 1.5.
321Suppose also that popular package Q is eager to take
322advantage of a new feature in D 1.5
323and issues a new version that explicitly declares it needs D ≥ 1.6.
324Now the ecosystem is divided, and programs must choose sides:
325are they P-using or Q-using? They cannot be both.
326
327In contrast, being allowed to specify only a minimum required version
328for a dependency makes clear that P's author must either
329(1) release a new, fixed version of P;
330(2) contact D's author to issue a fixed D 1.6 and then release a new P declaring a requirement on D 1.6 or later;
331or else (3) start using a fork of D 1.4 with a different import path.
332Note the difference between a new P that requires “D before 1.5”
333compared to “D 1.6 or later.”
334Both avoid D 1.5, but “D before 1.5” explains only which builds fail,
335while “D 1.6 or later” explains how to make a build succeed.
336
337### Semantic Import Versions
338
339The example of ecosystem fragmentation in the previous section
340is worse when it involves major versions.
341Suppose the author of popular package P has used D 1.X as a dependency,
342and then popular package Q decides to update to D 2.X because it
343is a nicer API.
344If we adopt Dep's semantics,
345now the ecosystem is again divided, and programs must again choose sides:
346are they P-using (D 1.X-using) or Q-using (D 2.X-using)?
347They cannot be both.
348Worse,
349in this case, because D 1.X and D 2.X are different major versions
350with different APIs, it is completely reasonable for the author of P
351to continue to use D 1.X, which might even continue to be updated with
352features and bug fixes.
353That continued usage only prolongs the divide.
354The end result is that
355a widely-used package like D would in practice either
356be practically prohibited from issue version 2 or
357else split the ecosystem in half by doing so.
358Neither outcome is desirable.
359
360Rust's Cargo makes a different choice from Dep.
361Cargo allows each package to specify whether
362a reference to D means D 1.X or D 2.X.
363Then, if needed, Cargo links both a D 1.X and a D 2.X into the final binary.
364This approach works better than Dep's,
365but users can still get stuck.
366If P exposes D 1.X in its own API and Q exposes D 2.X in its own API,
367then a single client package C cannot use both P and Q,
368because it will not be able to refer to both D 1.X (when using P)
369and D 2.X (when using Q).
370The [dependency story](https://research.swtch.com/vgo-import) in the semantic import versioning post
371presents an equivalent scenario in more detail.
372In that story, the base package manager starts out being like Dep,
373and the `-fmultiverse` flag makes it more like Cargo.
374
375If Cargo is one step away from Dep, semantic import versioning is two steps away.
376In addition to allowing different major versions to be used
377in a single build,
378semantic import versioning gives the different major versions different names,
379so that there's never any ambiguity
380about which is meant in a given program file.
381Making the import paths precise about the expected
382semantics of the thing being imported (is it v1 or v2?)
383eliminates the possibility of problems like those client C experienced
384in the previous example.
385
386More generally, in semantic import versioning,
387an import of `my/thing` asks for the semantics of v1.X of `my/thing`.
388As long as `my/thing` is following the import compatibility rule,
389that's a well-defined set of functionality,
390satisfied by the latest v1.X and possibly earlier ones
391(as constrained by `go.mod`).
392Similarly, an import of `my/thing/v2` asks for the semantics of v2.X of `my/thing`,
393satisfied by the latest v2.X and possibly earlier ones
394(again constrained by `go.mod`).
395The meaning of the imports is clear, to both people and tools,
396from reading only the Go source code,
397without reference to `go.mod`.
398If instead we followed the Cargo approach, both imports would be `my/thing`, and the
399meaning of that import would be ambiguous from the source code alone,
400resolved only by reading `go.mod`.
401
402Our article “[About the go command](https://golang.org/doc/articles/go_command.html)” explains:
403
404> An explicit goal for Go from the beginning was to be able to build Go code
405> using only the information found in the source itself, not needing to write
406> a makefile or one of the many modern replacements for makefiles.
407> If Go needed a configuration file to explain how to build your program,
408> then Go would have failed.
409
410It is an explicit goal of this proposal's design to preserve this property,
411to avoid making the general semantics of a Go source file change depending on
412the contents of `go.mod`.
413With semantic import versioning, if `go.mod` is deleted and
414recreated from scratch, the effect is only to possibly update
415to newer versions of imported packages, but still ones that are
416still expected to work, thanks to import compatibility.
417In contrast, if we take the Cargo approach, in which the `go.mod` file
418must disambiguate between the arbitrarily different semantics of
419v1 and v2 of `my/thing`, then `go.mod` becomes a required configuration file,
420violating the original goal.
421
422More generally, the main objection to adding `/v2/` to import paths is that
423it's a bit longer, a bit ugly, and it makes explicit a semantically important
424detail that other systems abstract away, which in turn induces more work for authors,
425compared to other systems, when they change that detail.
426But all of these were true when we introduced `goinstall`'s URL-like import paths,
427and they've been a clear success.
428Before `goinstall`, programmers wrote things like `import "igo/set"`.
429To make that import work, you had to know to first check out `github.com/jacobsa/igo` into `$GOPATH/src/igo`.
430The abbreviated paths had the benefit that if you preferred
431a different version of `igo`, you could check your variant into
432`$GOPATH/src/igo` instead, without updating any imports.
433But the abbreviated imports also had the very real drawbacks that a build trying to use
434both `igo/set` variants could not, and also that the Go source code did not record
435anywhere exactly which `igo/set` it meant.
436When `goinstall` introduced `import "github.com/jacobsa/igo/set"` instead,
437that made the imports a bit longer and a bit ugly,
438but it also made explicit a semantically important detail:
439exactly which `igo/set` was meant.
440The longer paths created a little more work for authors compared
441to systems that stashed that information in a single configuration file.
442But eight years later, no one notices the longer import paths,
443we've stopped seeing them as ugly,
444and we now rely on the benefits of being explicit about
445exactly which package is meant by a given import.
446I expect that once `/v2/` elements in import paths are
447common in Go source files, the same will happen:
448we will no longer notice the longer paths,
449we will stop seeing them as ugly, and we will rely on the benefits of
450being explicit about exactly which semantics are meant by a given import.
451
452### Update Timing & High-Fidelity Builds
453
454In the Bundler/Cargo/Dep approach, the package manager always prefers
455to use the latest version of any dependency.
456These systems use the lock file to override that behavior,
457holding the updates back.
458But lock files only apply to whole-program builds,
459not to newly imported libraries.
460If you are working on module A, and you add a new requirement on module B, which in turn requires module C,
461these systems will fetch the latest of B and then also the latest of C.
462In contrast, this proposal still fetches the latest of B (because it is
463what you are adding to the project explicitly, and the default is to
464take the latest of explicit additions) but then prefers to use the
465exact version of C that B requires.
466Although newer versions of C should work, it is safest to
467use the one that B did.
468Of course, if the build has a different reason to use a newer version of C, it can do that.
469For example, if A also imports D, which requires a newer C, then the build should and will use that newer version.
470But in the absence of such an overriding requirement,
471minimal version selection will build A using the exact version of C requested by B.
472If, later, a new version of B is released requesting a newer version of C,
473then when A updates to that newer B,
474C will be updated only to the version that the new B requires, not farther.
475The [minimal version selection](https://research.swtch.com/vgo-mvs) blog post
476refers to this kind of build as a “high-fidelity build.”
477
478Minimal version selection has the key property that a recently-published version of C
479is never used automatically.
480It is only used when a developer asks for it explicitly.
481For example, the developer of A could ask for all dependencies, including transitive dependencies, to be updated.
482Or, less directly, the developer of B could update C and release a new B,
483and then the developer of A could update B.
484But either way, some developer working on some package in the build must
485take an explicit action asking for C to be updated,
486and then the update does not take effect in A's build until
487a developer working on A updates some dependency leading to C.
488Waiting until an update is requested ensures that updates only happen
489when developers are ready to test them and deal with the possibility
490of breakage.
491
492Many developers recoil at the idea that adding the latest B would not
493automatically also add the latest C,
494but if C was just released, there's no guarantee it works in this build.
495The more conservative position is to avoid using it until the user asks.
496For comparison, the Go 1.9 go command does not automatically start using Go 1.10
497the day Go 1.10 is released.
498Instead, users are expected to update on their own
499schedule,
500so that they can control when they take on the risk of things breaking.
501The reasons not to update automatically to the latest Go release
502applies even more to individual packages:
503there are more of them,
504and most are not tested for backwards compatibility
505as extensively as Go releases are.
506
507If a developer does want to update all dependencies to the latest version,
508that's easy: `go get -u`.
509We may also add a `go get -p` that updates all dependencies to their
510latest patch versions, so that C 1.2.3 might be updated to C 1.2.5 but not to C 1.3.0.
511If the Go community as a whole reserved patch versions only for very safe
512or security-critical changes, then that `-p` behavior might be useful.
513
514## Compatibility
515
516The work in this proposal is not constrained by
517the [compatibility guidelines](https://golang.org/doc/go1compat) at all.
518Those guidelines apply to the language and standard library APIs, not tooling.
519Even so, compatibility more generally is a critical concern.
520It would be a serious mistake to deploy changes to the `go` command
521in a way that breaks all existing Go code or splits the ecosystem into
522module-aware and non-module-aware packages.
523On the contrary, we must make the transition as smooth and seamless as possible.
524
525Module-aware builds can import non-module-aware packages
526(those outside a tree with a `go.mod` file)
527provided they are tagged with a v0 or v1 semantic version.
528They can also refer to any specific commit using a “pseudo-version”
529of the form v0.0.0-*yyyymmddhhmmss*-*commit*.
530The pseudo-version form allows referring to untagged commits
531as well as commits that are tagged with semantic versions at v2 or above
532but that do not follow the semantic import versioning convention.
533
534Module-aware builds can also consume requirement information
535not just from `go.mod` files but also from all known pre-existing
536version metadata files in the Go ecosystem:
537`GLOCKFILE`, `Godeps/Godeps.json`, `Gopkg.lock`, `dependencies.tsv`,
538`glide.lock`, `vendor.conf`, `vendor.yml`, `vendor/manifest`,
539and `vendor/vendor.json`.
540
541Existing tools like `dep` should have no trouble consuming
542Go modules, simply ignoring the `go.mod` file.
543It may also be helpful to add support to `dep` to read `go.mod` files in
544dependencies, so that `dep` users are unaffected as their
545dependencies move from `dep` to the new module support.
546
547## Implementation
548
549A prototype of the proposal is implemented in a fork of the `go` command called `vgo`,
550available using `go get -u golang.org/x/vgo`.
551We will refine this implementation during the Go 1.11 cycle and
552merge it back into `cmd/go` in the main repository.
553
554The plan, subject to proposal approval,
555is to release module support in Go 1.11
556as an optional feature that may still change.
557The Go 1.11 release will give users a chance to use modules “for real”
558and provide critical feedback.
559Even though the details may change, future releases will
560be able to consume Go 1.11-compatible source trees.
561For example, Go 1.12 will understand how to consume
562the Go 1.11 `go.mod` file syntax, even if by then the
563file syntax or even the file name has changed.
564In a later release (say, Go 1.12), we will declare the module support completed.
565In a later release (say, Go 1.13), we will end support for `go` `get` of non-modules.
566Support for working in GOPATH will continue indefinitely.
567
568## Open issues (if applicable)
569
570We have not yet converted large, complex repositories to use modules.
571We intend to work with the Kubernetes team and others (perhaps CoreOS, Docker)
572to convert their use cases.
573It is possible those conversions will turn up reasons for adjustments
574to the proposal as described here.
575