diff --git a/.plzconfig b/.plzconfig index 9c052141..cf75e12d 100644 --- a/.plzconfig +++ b/.plzconfig @@ -1,5 +1,5 @@ [Please] -Version = >=17.0.0-beta.8 +Version = >=17.0.0 [build] hashcheckers = sha256 @@ -136,5 +136,9 @@ Help = Compile for the Go race detector Optional = true Help = A built target for a go.mod, which can help avoid the need to pass modules via requirements to go_repo. +[PluginConfig "structured_third_party"] +Optional = true +Help = Whether go repo should be structured based on the module path, or use a flattened singular build file. + [Plugin "shell"] Target = //plugins:shell diff --git a/build_defs/go.build_defs b/build_defs/go.build_defs index 10306a86..b3972ba4 100644 --- a/build_defs/go.build_defs +++ b/build_defs/go.build_defs @@ -1095,6 +1095,8 @@ def _add_ld_flags(name:str, stdout:list): def _module_rule_name(module): + if CONFIG.GO.STRUCTURED_THIRD_PARTY: + return basename(module) return module.replace("/", "_") def go_repo(module: str, version:str=None, download:str=None, name:str=None, install:list=[], requirements:list=[], @@ -1158,12 +1160,13 @@ def go_repo(module: str, version:str=None, download:str=None, name:str=None, ins else: modFileArg = "" + structured_flag = "--structured_third_party" if CONFIG.GO.STRUCTURED_THIRD_PARTY else "" requirements = " ".join(requirements) repo = build_rule( name = name, tag = "repo" if install else None, srcs = srcs, - cmd = f"rm -rf $SRCS_DOWNLOAD/.plzconfig && find $SRCS_DOWNLOAD -name BUILD -delete && $TOOL generate {modFileArg} --module {module} --src_root=$SRCS_DOWNLOAD {install_args} {requirements} && mv $SRCS_DOWNLOAD $OUT", + cmd = f"rm -rf $SRCS_DOWNLOAD/.plzconfig && find $SRCS_DOWNLOAD -name BUILD -delete && $TOOL generate {modFileArg} {structured_flag} --module {module} --src_root=$SRCS_DOWNLOAD {install_args} {requirements} && mv $SRCS_DOWNLOAD $OUT", outs = [subrepo_name], tools = [CONFIG.GO.PLEASE_GO_TOOL], env= { diff --git a/test/goget/BUILD b/test/goget/BUILD deleted file mode 100644 index 4f92ea5e..00000000 --- a/test/goget/BUILD +++ /dev/null @@ -1,7 +0,0 @@ -subinclude("//test/build_defs:e2e") - -please_repo_e2e_test( - name = "go_get_test", - plz_command = "plz test", - repo = "test_repo", -) diff --git a/test/gorepo/BUILD b/test/gorepo/BUILD new file mode 100644 index 00000000..4f055b68 --- /dev/null +++ b/test/gorepo/BUILD @@ -0,0 +1,13 @@ +subinclude("//test/build_defs:e2e") + +please_repo_e2e_test( + name = "structured_test", + plz_command = "plz test", + repo = "structured_repo", +) + +please_repo_e2e_test( + name = "unstructured_test", + plz_command = "plz test", + repo = "unstructured_repo", +) diff --git a/test/gorepo/structured_repo/.plzconfig b/test/gorepo/structured_repo/.plzconfig new file mode 100644 index 00000000..aded0246 --- /dev/null +++ b/test/gorepo/structured_repo/.plzconfig @@ -0,0 +1,10 @@ +[Parse] +BuildFileName = BUILD_FILE +BuildFileName = BUILD + +[Plugin "go"] +Target = //plugins:go +PleaseGoTool = +GoTool = +FeatureFlags = go_get +Stdlib = //third_party/go:std diff --git a/test/goget/test_repo/BUILD_FILE b/test/gorepo/structured_repo/BUILD_FILE similarity index 59% rename from test/goget/test_repo/BUILD_FILE rename to test/gorepo/structured_repo/BUILD_FILE index 4d7f1203..51e5a2a1 100644 --- a/test/goget/test_repo/BUILD_FILE +++ b/test/gorepo/structured_repo/BUILD_FILE @@ -1,7 +1,7 @@ subinclude("///go//build_defs:go") go_test( - name = "go_get_test", - srcs = ["go_get_test.go"], + name = "go_repo_test", + srcs = ["go_repo_test.go"], deps = ["//third_party/go:testify"], ) \ No newline at end of file diff --git a/test/goget/test_repo/go_get_test.go b/test/gorepo/structured_repo/go_repo_test.go similarity index 83% rename from test/goget/test_repo/go_get_test.go rename to test/gorepo/structured_repo/go_repo_test.go index eebd151e..c8d7c980 100644 --- a/test/goget/test_repo/go_get_test.go +++ b/test/gorepo/structured_repo/go_repo_test.go @@ -1,4 +1,4 @@ -package test_repo +package unstructured_repo import ( "github.com/stretchr/testify/assert" diff --git a/test/goget/test_repo/plugins/BUILD_FILE b/test/gorepo/structured_repo/plugins/BUILD_FILE similarity index 100% rename from test/goget/test_repo/plugins/BUILD_FILE rename to test/gorepo/structured_repo/plugins/BUILD_FILE diff --git a/test/goget/test_repo/third_party/go/BUILD_FILE b/test/gorepo/structured_repo/third_party/go/BUILD_FILE similarity index 100% rename from test/goget/test_repo/third_party/go/BUILD_FILE rename to test/gorepo/structured_repo/third_party/go/BUILD_FILE diff --git a/test/goget/test_repo/.plzconfig b/test/gorepo/unstructured_repo/.plzconfig similarity index 89% rename from test/goget/test_repo/.plzconfig rename to test/gorepo/unstructured_repo/.plzconfig index 9609c546..fb6a772a 100644 --- a/test/goget/test_repo/.plzconfig +++ b/test/gorepo/unstructured_repo/.plzconfig @@ -8,6 +8,7 @@ PleaseGoTool = GoTool = FeatureFlags = go_get Stdlib = //third_party/go:std +StructuredThirdParty = true [FeatureFlags] ExcludeGoRules = true \ No newline at end of file diff --git a/test/gorepo/unstructured_repo/BUILD_FILE b/test/gorepo/unstructured_repo/BUILD_FILE new file mode 100644 index 00000000..ac590ed9 --- /dev/null +++ b/test/gorepo/unstructured_repo/BUILD_FILE @@ -0,0 +1,7 @@ +subinclude("///go//build_defs:go") + +go_test( + name = "go_repo_test", + srcs = ["go_repo_test.go"], + deps = ["///third_party/go/github.com/stretchr/testify//assert"], +) \ No newline at end of file diff --git a/test/gorepo/unstructured_repo/go_repo_test.go b/test/gorepo/unstructured_repo/go_repo_test.go new file mode 100644 index 00000000..c8d7c980 --- /dev/null +++ b/test/gorepo/unstructured_repo/go_repo_test.go @@ -0,0 +1,10 @@ +package unstructured_repo + +import ( + "github.com/stretchr/testify/assert" + "testing" +) + +func TestAssertImportable(t *testing.T) { + assert.True(t, true) +} diff --git a/test/gorepo/unstructured_repo/plugins/BUILD_FILE b/test/gorepo/unstructured_repo/plugins/BUILD_FILE new file mode 100644 index 00000000..f197577d --- /dev/null +++ b/test/gorepo/unstructured_repo/plugins/BUILD_FILE @@ -0,0 +1,4 @@ +plugin_repo( + name = "go", + revision = "master", +) \ No newline at end of file diff --git a/test/gorepo/unstructured_repo/third_party/go/BUILD_FILE b/test/gorepo/unstructured_repo/third_party/go/BUILD_FILE new file mode 100644 index 00000000..7e2be50c --- /dev/null +++ b/test/gorepo/unstructured_repo/third_party/go/BUILD_FILE @@ -0,0 +1,5 @@ +subinclude("///go//build_defs:go") + +go_stdlib( + name = "std", +) diff --git a/test/gorepo/unstructured_repo/third_party/go/github.com/davecgh/BUILD_FILE b/test/gorepo/unstructured_repo/third_party/go/github.com/davecgh/BUILD_FILE new file mode 100644 index 00000000..0822343d --- /dev/null +++ b/test/gorepo/unstructured_repo/third_party/go/github.com/davecgh/BUILD_FILE @@ -0,0 +1,7 @@ +subinclude("///go//build_defs:go") + +go_repo( + licences = ["ISC"], + module = "github.com/davecgh/go-spew", + version = "v1.1.1", +) diff --git a/test/gorepo/unstructured_repo/third_party/go/github.com/pmezard/BUILD_FILE b/test/gorepo/unstructured_repo/third_party/go/github.com/pmezard/BUILD_FILE new file mode 100644 index 00000000..e33bdc91 --- /dev/null +++ b/test/gorepo/unstructured_repo/third_party/go/github.com/pmezard/BUILD_FILE @@ -0,0 +1,7 @@ +subinclude("///go//build_defs:go") + +go_repo( + licences = ["BSD-3-Clause"], + module = "github.com/pmezard/go-difflib", + version = "v1.0.0", +) \ No newline at end of file diff --git a/test/gorepo/unstructured_repo/third_party/go/github.com/stretchr/BUILD_FILE b/test/gorepo/unstructured_repo/third_party/go/github.com/stretchr/BUILD_FILE new file mode 100644 index 00000000..e940bbca --- /dev/null +++ b/test/gorepo/unstructured_repo/third_party/go/github.com/stretchr/BUILD_FILE @@ -0,0 +1,14 @@ +subinclude("///go//build_defs:go") + +go_repo( + licences = ["MIT"], + module = "github.com/stretchr/objx", + version = "v0.5.0", +) + +go_repo( + name = "testify", + licences = ["MIT"], + module = "github.com/stretchr/testify", + version = "v1.7.0", +) \ No newline at end of file diff --git a/test/gorepo/unstructured_repo/third_party/go/gopkg.in/BUILD_FILE b/test/gorepo/unstructured_repo/third_party/go/gopkg.in/BUILD_FILE new file mode 100644 index 00000000..4926fe28 --- /dev/null +++ b/test/gorepo/unstructured_repo/third_party/go/gopkg.in/BUILD_FILE @@ -0,0 +1,7 @@ +subinclude("///go//build_defs:go") + +go_repo( + licences = ["MIT"], + module = "gopkg.in/yaml.v3", + version = "v3.0.0-20210107192922-496545a6307b", +) \ No newline at end of file diff --git a/tools/please_go/generate/generate.go b/tools/please_go/generate/generate.go index 77d37689..74aab65e 100644 --- a/tools/please_go/generate/generate.go +++ b/tools/please_go/generate/generate.go @@ -14,30 +14,32 @@ import ( ) type Generate struct { - moduleName string - srcRoot string - buildContext build.Context - modFile string - buildFileNames []string - moduleDeps []string - pluginTarget string - replace map[string]string - knownImportTargets map[string]string // cache these so we don't end up looping over all the modules for every import - thirdPartyFolder string - install []string + moduleName string + srcRoot string + buildContext build.Context + modFile string + buildFileNames []string + moduleDeps []string + pluginTarget string + replace map[string]string + knownImportTargets map[string]string // cache these so we don't end up looping over all the modules for every import + thirdPartyFolder string + structuredThirdParty bool + install []string } -func New(srcRoot, thirdPartyFolder, modFile, module string, buildFileNames, moduleDeps, install []string) *Generate { +func New(srcRoot, thirdPartyFolder, modFile, module string, buildFileNames, moduleDeps, install []string, structuredThirdParty bool) *Generate { return &Generate{ - srcRoot: srcRoot, - buildContext: build.Default, - buildFileNames: buildFileNames, - moduleDeps: moduleDeps, - modFile: modFile, - knownImportTargets: map[string]string{}, - thirdPartyFolder: thirdPartyFolder, - install: install, - moduleName: module, + srcRoot: srcRoot, + buildContext: build.Default, + buildFileNames: buildFileNames, + moduleDeps: moduleDeps, + modFile: modFile, + knownImportTargets: map[string]string{}, + thirdPartyFolder: thirdPartyFolder, + install: install, + moduleName: module, + structuredThirdParty: structuredThirdParty, } } @@ -431,6 +433,9 @@ func (g *Generate) subrepoName(module string) string { if g.moduleName == module { return "" } + if g.structuredThirdParty { + return filepath.Join(g.thirdPartyFolder, module) + } return filepath.Join(g.thirdPartyFolder, strings.ReplaceAll(module, "/", "_")) } diff --git a/tools/please_go/please_go.go b/tools/please_go/please_go.go index 351260d7..01cda2a2 100644 --- a/tools/please_go/please_go.go +++ b/tools/please_go/please_go.go @@ -92,13 +92,14 @@ var opts = struct { Packages []string `short:"p" long:"packages" description:"Packages to include in the module"` } `command:"module_info" alias:"m" description:"Creates an info file about a series of packages in a go_module"` Generate struct { - SrcRoot string `short:"r" long:"src_root" description:"The src root of the module to inspect"` - ImportPath string `long:"import_path" description:"overrides the module's import path. If not set, the import path from the go.mod will be used.'"` - ThirdPartyFolder string `short:"t" long:"third_part_folder" description:"The folder containing the third party subrepos" default:"third_party/go"` - ModFile string `long:"mod_file" description:"Path to the mod file to use to resolve dependencies against"` - Module string `long:"module" description:"The name of the current module"` - Install []string `long:"install" description:"The packages to add to the :install alias"` - Args struct { + SrcRoot string `short:"r" long:"src_root" description:"The src root of the module to inspect"` + ImportPath string `long:"import_path" description:"overrides the module's import path. If not set, the import path from the go.mod will be used.'"` + ThirdPartyFolder string `short:"t" long:"third_part_folder" description:"The folder containing the third party subrepos" default:"third_party/go"` + StructuredThirdParty bool `long:"structured_third_party" description:"Whether to use a directory structure for third party based off the module path, or a singular flat build file."` + ModFile string `long:"mod_file" description:"Path to the mod file to use to resolve dependencies against"` + Module string `long:"module" description:"The name of the current module"` + Install []string `long:"install" description:"The packages to add to the :install alias"` + Args struct { Requirements []string `positional-arg-name:"requirements" description:"Any module requirements not included in the go.mod"` } `positional-args:"true"` } `command:"generate" alias:"f" description:"Filter go sources based on the go build tag rules."` @@ -173,7 +174,16 @@ var subCommands = map[string]func() int{ return 0 }, "generate": func() int { - g := generate.New(opts.Generate.SrcRoot, opts.Generate.ThirdPartyFolder, opts.Generate.ModFile, opts.Generate.Module, []string{"BUILD", "BUILD.plz"}, opts.Generate.Args.Requirements, opts.Generate.Install) + g := generate.New( + opts.Generate.SrcRoot, + opts.Generate.ThirdPartyFolder, + opts.Generate.ModFile, + opts.Generate.Module, + []string{"BUILD", "BUILD.plz"}, + opts.Generate.Args.Requirements, + opts.Generate.Install, + opts.Generate.StructuredThirdParty, + ) if err := g.Generate(); err != nil { log.Fatalf("failed to generate go rules: %v", err) }