From: Michael Matloob Date: Thu, 28 Oct 2021 20:28:32 +0000 (-0400) Subject: cmd/go: add go work use command X-Git-Tag: go1.18beta1~345 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=fdee1b297438a64c553ecc7468a7647f5a070404;p=gostls13.git 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 Run-TryBot: Michael Matloob TryBot-Result: Go Bot Reviewed-by: Bryan C. Mills --- diff --git a/src/cmd/go/alldocs.go b/src/cmd/go/alldocs.go index dfb88ab78d..a53ff7c66d 100644 --- a/src/cmd/go/alldocs.go +++ b/src/cmd/go/alldocs.go @@ -1388,6 +1388,7 @@ // 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 " for more information about a command. // @@ -1488,6 +1489,18 @@ // 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 index 0000000000..10c25da396 --- /dev/null +++ b/src/cmd/go/internal/workcmd/use.go @@ -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) + } +} diff --git a/src/cmd/go/internal/workcmd/work.go b/src/cmd/go/internal/workcmd/work.go index dc1164fb77..98d5a01de6 100644 --- a/src/cmd/go/internal/workcmd/work.go +++ b/src/cmd/go/internal/workcmd/work.go @@ -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 index 0000000000..dddce0fe22 --- /dev/null +++ b/src/cmd/go/testdata/script/work_use.txt @@ -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 --