Skip to content

Commit fdee1b2

Browse files
committed
cmd/go: add go work use command
For #45713, #48257 Change-Id: I7e9248f22fe7ab33b151e07cc296d64c194154e2 Reviewed-on: https://go-review.googlesource.com/c/go/+/359534 Trust: Michael Matloob <[email protected]> Run-TryBot: Michael Matloob <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Bryan C. Mills <[email protected]>
1 parent 3a4b950 commit fdee1b2

File tree

4 files changed

+175
-0
lines changed

4 files changed

+175
-0
lines changed

src/cmd/go/alldocs.go

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/cmd/go/internal/workcmd/use.go

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
// Copyright 2021 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
// go work use
6+
7+
package workcmd
8+
9+
import (
10+
"cmd/go/internal/base"
11+
"cmd/go/internal/fsys"
12+
"cmd/go/internal/lockedfile"
13+
"cmd/go/internal/modload"
14+
"context"
15+
"io/fs"
16+
"io/ioutil"
17+
"os"
18+
"path/filepath"
19+
20+
"golang.org/x/mod/modfile"
21+
)
22+
23+
var _ = modload.TODOWorkspaces("Add more documentation below. Though this is" +
24+
"enough for those trying workspaces out, there should be more through" +
25+
"documentation if the proposal is accepted and released.")
26+
27+
var cmdUse = &base.Command{
28+
UsageLine: "go work use [-r] [moddirs]",
29+
Short: "add modules to workspace file",
30+
Long: `Use provides a command-line interface for adding directories,
31+
optionally recursively, to a go.work file.
32+
33+
The -r flag searches recursively for modules in the argument directories.`,
34+
}
35+
36+
var useR = cmdUse.Flag.Bool("r", false, "")
37+
38+
func init() {
39+
cmdUse.Run = runUse // break init cycle
40+
41+
base.AddModCommonFlags(&cmdUse.Flag)
42+
base.AddWorkfileFlag(&cmdUse.Flag)
43+
}
44+
45+
func runUse(ctx context.Context, cmd *base.Command, args []string) {
46+
modload.InitWorkfile()
47+
48+
modload.ForceUseModules = true
49+
50+
var gowork string
51+
modload.InitWorkfile()
52+
gowork = modload.WorkFilePath()
53+
54+
data, err := lockedfile.Read(gowork)
55+
if err != nil {
56+
base.Fatalf("goX: %v", err)
57+
}
58+
59+
workFile, err := modfile.ParseWork(gowork, data, nil)
60+
if err != nil {
61+
base.Fatalf("go: errors parsing %s:\n%s", base.ShortPath(gowork), err)
62+
}
63+
64+
haveDirs := make(map[string]bool)
65+
for _, dir := range workFile.Directory {
66+
haveDirs[filepath.Join(filepath.Dir(gowork), filepath.FromSlash(dir.Path))] = true
67+
}
68+
69+
addDirs := make(map[string]bool)
70+
removeDirs := make(map[string]bool)
71+
lookDir := func(dir string) {
72+
absDir := filepath.Join(base.Cwd(), dir)
73+
// If the path is absolute, keep it absolute. If it's relative,
74+
// make it relative to the go.work file rather than the working directory.
75+
if !filepath.IsAbs(dir) {
76+
rel, err := filepath.Rel(filepath.Dir(gowork), absDir)
77+
if err == nil {
78+
dir = rel
79+
}
80+
}
81+
fi, err := os.Stat(filepath.Join(dir, "go.mod"))
82+
if err != nil {
83+
if os.IsNotExist(err) {
84+
85+
if haveDirs[absDir] {
86+
removeDirs[dir] = true
87+
}
88+
return
89+
}
90+
base.Errorf("go: %v", err)
91+
}
92+
93+
if !fi.Mode().IsRegular() {
94+
base.Errorf("go: %v is not regular", filepath.Join(dir, "go.mod"))
95+
}
96+
97+
if !haveDirs[absDir] {
98+
addDirs[dir] = true
99+
}
100+
}
101+
102+
for _, useDir := range args {
103+
if *useR {
104+
fsys.Walk(useDir, func(path string, info fs.FileInfo, err error) error {
105+
if !info.IsDir() {
106+
return nil
107+
}
108+
lookDir(path)
109+
return nil
110+
})
111+
continue
112+
}
113+
lookDir(useDir)
114+
}
115+
116+
for dir := range removeDirs {
117+
workFile.DropDirectory(filepath.ToSlash(dir))
118+
}
119+
for dir := range addDirs {
120+
workFile.AddDirectory(filepath.ToSlash(dir), "")
121+
}
122+
workFile.SortBlocks()
123+
workFile.Cleanup() // clean file after edits
124+
out := modfile.Format(workFile.Syntax)
125+
126+
if err := ioutil.WriteFile(gowork, out, 0666); err != nil {
127+
base.Fatalf("go: %v", err)
128+
}
129+
}

src/cmd/go/internal/workcmd/work.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,6 @@ which workspaces are a part.
2525
cmdEdit,
2626
cmdInit,
2727
cmdSync,
28+
cmdUse,
2829
},
2930
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
go work use -r foo
2+
cmp go.work go.want_work_r
3+
4+
go work use other
5+
cmp go.work go.want_work_other
6+
-- go.work --
7+
go 1.18
8+
9+
directory (
10+
foo
11+
foo/bar // doesn't exist
12+
)
13+
-- go.want_work_r --
14+
go 1.18
15+
16+
directory (
17+
foo
18+
foo/bar/baz
19+
)
20+
-- go.want_work_other --
21+
go 1.18
22+
23+
directory (
24+
foo
25+
foo/bar/baz
26+
other
27+
)
28+
-- foo/go.mod --
29+
module foo
30+
-- foo/bar/baz/go.mod --
31+
module baz
32+
-- other/go.mod --

0 commit comments

Comments
 (0)