1
2
3
4
5
6
7 package workcmd
8
9 import (
10 "cmd/go/internal/base"
11 "cmd/go/internal/imports"
12 "cmd/go/internal/modload"
13 "context"
14
15 "golang.org/x/mod/module"
16 )
17
18 var cmdSync = &base.Command{
19 UsageLine: "go work sync",
20 Short: "sync workspace build list to modules",
21 Long: `Sync syncs the workspace's build list back to the
22 workspace's modules
23
24 The workspace's build list is the set of versions of all the
25 (transitive) dependency modules used to do builds in the workspace. go
26 work sync generates that build list using the Minimal Version Selection
27 algorithm, and then syncs those versions back to each of modules
28 specified in the workspace (with use directives).
29
30 The syncing is done by sequentially upgrading each of the dependency
31 modules specified in a workspace module to the version in the build list
32 if the dependency module's version is not already the same as the build
33 list's version. Note that Minimal Version Selection guarantees that the
34 build list's version of each module is always the same or higher than
35 that in each workspace module.
36
37 See the workspaces reference at https://go.dev/ref/mod#workspaces
38 for more information.
39 `,
40 Run: runSync,
41 }
42
43 func init() {
44 base.AddModCommonFlags(&cmdSync.Flag)
45 }
46
47 func runSync(ctx context.Context, cmd *base.Command, args []string) {
48 modload.ForceUseModules = true
49 modload.InitWorkfile()
50 if modload.WorkFilePath() == "" {
51 base.Fatalf("go: no go.work file found\n\t(run 'go work init' first or specify path using GOWORK environment variable)")
52 }
53
54 workGraph := modload.LoadModGraph(ctx, "")
55 _ = workGraph
56 mustSelectFor := map[module.Version][]module.Version{}
57
58 mms := modload.MainModules
59
60 opts := modload.PackageOpts{
61 Tags: imports.AnyTags(),
62 VendorModulesInGOROOTSrc: true,
63 ResolveMissingImports: false,
64 LoadTests: true,
65 AllowErrors: true,
66 SilencePackageErrors: true,
67 SilenceUnmatchedWarnings: true,
68 }
69 for _, m := range mms.Versions() {
70 opts.MainModule = m
71 _, pkgs := modload.LoadPackages(ctx, opts, "all")
72 opts.MainModule = module.Version{}
73
74 var (
75 mustSelect []module.Version
76 inMustSelect = map[module.Version]bool{}
77 )
78 for _, pkg := range pkgs {
79 if r := modload.PackageModule(pkg); r.Version != "" && !inMustSelect[r] {
80
81 mustSelect = append(mustSelect, r)
82 inMustSelect[r] = true
83 }
84 }
85 module.Sort(mustSelect)
86 mustSelectFor[m] = mustSelect
87 }
88
89 workFilePath := modload.WorkFilePath()
90
91 for _, m := range mms.Versions() {
92 if mms.ModRoot(m) == "" && m.Path == "command-line-arguments" {
93
94
95
96 continue
97 }
98
99
100
101 modload.EnterModule(ctx, mms.ModRoot(m))
102
103
104
105 changed, err := modload.EditBuildList(ctx, nil, mustSelectFor[m])
106 if err != nil {
107 base.Errorf("go: %v", err)
108 }
109 if !changed {
110 continue
111 }
112
113 modload.LoadPackages(ctx, modload.PackageOpts{
114 Tags: imports.AnyTags(),
115 Tidy: true,
116 VendorModulesInGOROOTSrc: true,
117 ResolveMissingImports: false,
118 LoadTests: true,
119 AllowErrors: true,
120 SilenceMissingStdImports: true,
121 SilencePackageErrors: true,
122 }, "all")
123 modload.WriteGoMod(ctx)
124 }
125
126 wf, err := modload.ReadWorkFile(workFilePath)
127 if err != nil {
128 base.Fatalf("go: %v", err)
129 }
130 modload.UpdateWorkFile(wf)
131 if err := modload.WriteWorkFile(workFilePath, wf); err != nil {
132 base.Fatalf("go: %v", err)
133 }
134 }
135
View as plain text