]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: add go work use command
authorMichael Matloob <matloob@golang.org>
Thu, 28 Oct 2021 20:28:32 +0000 (16:28 -0400)
committerMichael Matloob <matloob@golang.org>
Fri, 12 Nov 2021 23:34:09 +0000 (23:34 +0000)
For #45713, #48257

Change-Id: I7e9248f22fe7ab33b151e07cc296d64c194154e2
Reviewed-on: https://go-review.googlesource.com/c/go/+/359534
Trust: Michael Matloob <matloob@golang.org>
Run-TryBot: Michael Matloob <matloob@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
src/cmd/go/alldocs.go
src/cmd/go/internal/workcmd/use.go [new file with mode: 0644]
src/cmd/go/internal/workcmd/work.go
src/cmd/go/testdata/script/work_use.txt [new file with mode: 0644]

index dfb88ab78d34a88c5de2b7a93c5effe877494fdc..a53ff7c66dba3bdb0e23267c6e6341ef5e3b73fe 100644 (file)
 //     edit        edit go.work from tools or scripts
 //     init        initialize workspace file
 //     sync        sync workspace build list to modules
+//     use         add modules to workspace file
 //
 // Use "go help work <command>" for more information about a command.
 //
 // go work sync
 //
 //
+// Add modules to workspace file
+//
+// Usage:
+//
+//     go work use [-r] [moddirs]
+//
+// Use provides a command-line interface for adding directories,
+// optionally recursively, to a go.work file.
+//
+// The -r flag searches recursively for modules in the argument directories.
+//
+//
 // Compile and run Go program
 //
 // Usage:
diff --git a/src/cmd/go/internal/workcmd/use.go b/src/cmd/go/internal/workcmd/use.go
new file mode 100644 (file)
index 0000000..10c25da
--- /dev/null
@@ -0,0 +1,129 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// go work use
+
+package workcmd
+
+import (
+       "cmd/go/internal/base"
+       "cmd/go/internal/fsys"
+       "cmd/go/internal/lockedfile"
+       "cmd/go/internal/modload"
+       "context"
+       "io/fs"
+       "io/ioutil"
+       "os"
+       "path/filepath"
+
+       "golang.org/x/mod/modfile"
+)
+
+var _ = modload.TODOWorkspaces("Add more documentation below. Though this is" +
+       "enough for those trying workspaces out, there should be more through" +
+       "documentation if the proposal is accepted and released.")
+
+var cmdUse = &base.Command{
+       UsageLine: "go work use [-r] [moddirs]",
+       Short:     "add modules to workspace file",
+       Long: `Use provides a command-line interface for adding directories,
+optionally recursively, to a go.work file.
+
+The -r flag searches recursively for modules in the argument directories.`,
+}
+
+var useR = cmdUse.Flag.Bool("r", false, "")
+
+func init() {
+       cmdUse.Run = runUse // break init cycle
+
+       base.AddModCommonFlags(&cmdUse.Flag)
+       base.AddWorkfileFlag(&cmdUse.Flag)
+}
+
+func runUse(ctx context.Context, cmd *base.Command, args []string) {
+       modload.InitWorkfile()
+
+       modload.ForceUseModules = true
+
+       var gowork string
+       modload.InitWorkfile()
+       gowork = modload.WorkFilePath()
+
+       data, err := lockedfile.Read(gowork)
+       if err != nil {
+               base.Fatalf("goX: %v", err)
+       }
+
+       workFile, err := modfile.ParseWork(gowork, data, nil)
+       if err != nil {
+               base.Fatalf("go: errors parsing %s:\n%s", base.ShortPath(gowork), err)
+       }
+
+       haveDirs := make(map[string]bool)
+       for _, dir := range workFile.Directory {
+               haveDirs[filepath.Join(filepath.Dir(gowork), filepath.FromSlash(dir.Path))] = true
+       }
+
+       addDirs := make(map[string]bool)
+       removeDirs := make(map[string]bool)
+       lookDir := func(dir string) {
+               absDir := filepath.Join(base.Cwd(), dir)
+               // If the path is absolute, keep it absolute. If it's relative,
+               // make it relative to the go.work file rather than the working directory.
+               if !filepath.IsAbs(dir) {
+                       rel, err := filepath.Rel(filepath.Dir(gowork), absDir)
+                       if err == nil {
+                               dir = rel
+                       }
+               }
+               fi, err := os.Stat(filepath.Join(dir, "go.mod"))
+               if err != nil {
+                       if os.IsNotExist(err) {
+
+                               if haveDirs[absDir] {
+                                       removeDirs[dir] = true
+                               }
+                               return
+                       }
+                       base.Errorf("go: %v", err)
+               }
+
+               if !fi.Mode().IsRegular() {
+                       base.Errorf("go: %v is not regular", filepath.Join(dir, "go.mod"))
+               }
+
+               if !haveDirs[absDir] {
+                       addDirs[dir] = true
+               }
+       }
+
+       for _, useDir := range args {
+               if *useR {
+                       fsys.Walk(useDir, func(path string, info fs.FileInfo, err error) error {
+                               if !info.IsDir() {
+                                       return nil
+                               }
+                               lookDir(path)
+                               return nil
+                       })
+                       continue
+               }
+               lookDir(useDir)
+       }
+
+       for dir := range removeDirs {
+               workFile.DropDirectory(filepath.ToSlash(dir))
+       }
+       for dir := range addDirs {
+               workFile.AddDirectory(filepath.ToSlash(dir), "")
+       }
+       workFile.SortBlocks()
+       workFile.Cleanup() // clean file after edits
+       out := modfile.Format(workFile.Syntax)
+
+       if err := ioutil.WriteFile(gowork, out, 0666); err != nil {
+               base.Fatalf("go: %v", err)
+       }
+}
index dc1164fb777a4747a9bfc045767115e20113fb14..98d5a01de635ca8ac9785e259203ac231a4d4e04 100644 (file)
@@ -25,5 +25,6 @@ which workspaces are a part.
                cmdEdit,
                cmdInit,
                cmdSync,
+               cmdUse,
        },
 }
diff --git a/src/cmd/go/testdata/script/work_use.txt b/src/cmd/go/testdata/script/work_use.txt
new file mode 100644 (file)
index 0000000..dddce0f
--- /dev/null
@@ -0,0 +1,32 @@
+go work use -r foo
+cmp go.work go.want_work_r
+
+go work use other
+cmp go.work go.want_work_other
+-- go.work --
+go 1.18
+
+directory (
+       foo
+       foo/bar // doesn't exist
+)
+-- go.want_work_r --
+go 1.18
+
+directory (
+       foo
+       foo/bar/baz
+)
+-- go.want_work_other --
+go 1.18
+
+directory (
+       foo
+       foo/bar/baz
+       other
+)
+-- foo/go.mod --
+module foo
+-- foo/bar/baz/go.mod --
+module baz
+-- other/go.mod --