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 <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>
This commit is contained in:
Michael Matloob 2021-10-28 16:28:32 -04:00
parent 3a4b95073a
commit fdee1b2974
4 changed files with 175 additions and 0 deletions

View File

@ -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 <command>" 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:

View File

@ -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)
}
}

View File

@ -25,5 +25,6 @@ which workspaces are a part.
cmdEdit,
cmdInit,
cmdSync,
cmdUse,
},
}

32
src/cmd/go/testdata/script/work_use.txt vendored Normal file
View File

@ -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 --