Skip to content

Commit f6be1fc

Browse files
r-hanglinzhp
authored andcommitted
go/tools/gopackagesdriver/pkgjson: Construct pkg json from file input (#4371)
When testing the bazel driver, we ran into an error that flaged that the argument list as too long. ``` ERROR: ...json failed: (Exit -1): pkgjson failed: error executing Action command (from target //...) bazel-out/k8-opt-exec-ST-a828a81199fe/bin/external/io_bazel_rules_go/go/tools/gopackagesdriver/pkgjson/reset_pkgjson/pkgjson --id @//src/... --pkg_path ... (remaining 15 arguments skipped) Use --sandbox_debug to see verbose messages from the sandbox and retain the sandbox build root for debugging Action failed to execute: java.io.IOException: Cannot run program "/home/user/.cache/bazel/_bazel_rhang/install/7e4ce7b0d69e79cb6bd84c7f9dfefe6b/process-wrapper" (in directory "/home/user/.cache/pkgdrv/0ddf1c72b811bee41d29991c732306ef72553747/sandbox/processwrapper-sandbox/29913/execroot/__main__"): error=7, Argument list too long ERROR: Build did NOT complete successfully ``` Digging into this issue, the cause is that the pkgjson command takes in all of the fields of package archive data as arguments. To work around this, we should preserve the original approach of writing a pkg json, before #4338, which used Skylark builtins to write the package content directly to disk. The pkgjson command is updated to parse ths json file directly and write out a transformed pkg json with the cgo related corrections in order to avoid limits regarding argument size. Note: This diff also makes changes to undo a breaking change (i.e. changing the signature of the make_pkg_json function) that was made in #4338. I revert changes to the functionalty of make_pkg_json and add a new replacement function make_pkg_json_with_archive.
1 parent 8e7d9cd commit f6be1fc

File tree

3 files changed

+72
-64
lines changed

3 files changed

+72
-64
lines changed

go/tools/gopackagesdriver/aspect.bzl

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,20 @@ def is_file_external(f):
4646
def file_path(f):
4747
return file_path_lib(f)
4848

49-
def make_pkg_json(ctx, pkg_json_tool, name, archive):
49+
# make_pkg_json_with_archive generates a pkg.json file from an archive
50+
# and supports cgo generated code.
51+
#
52+
# This function was created to avoid breaking the signature of make_pkg_json
53+
# and avoid adding an explicit field for cgo output files in the pkg.json.
54+
def make_pkg_json_with_archive(ctx, name, archive):
55+
pkg_json_file = ctx.actions.declare_file(name + ".pkg.json")
56+
write_pkg_json(ctx, ctx.executable._pkgjson, archive, pkg_json_file)
57+
return pkg_json_file
58+
59+
# deprecated: use make_pkg_json_with_archive instead
60+
def make_pkg_json(ctx, name, pkg_info):
5061
pkg_json_file = ctx.actions.declare_file(name + ".pkg.json")
51-
write_pkg_json(ctx, pkg_json_tool, archive, pkg_json_file)
62+
ctx.actions.write(pkg_json_file, content = json.encode(pkg_info))
5263
return pkg_json_file
5364

5465
def _go_pkg_info_aspect_impl(target, ctx):
@@ -87,13 +98,13 @@ def _go_pkg_info_aspect_impl(target, ctx):
8798
if archive.data.cgo_out_dir:
8899
compiled_go_files.append(archive.data.cgo_out_dir)
89100
export_files.append(archive.data.export_file)
90-
pkg_json_files.append(make_pkg_json(ctx, ctx.executable._pkgjson, archive.data.name, archive))
101+
pkg_json_files.append(make_pkg_json_with_archive(ctx, archive.data.name, archive))
91102

92103
if ctx.rule.kind == "go_test":
93104
for dep_archive in archive.direct:
94105
# find the archive containing the test sources
95106
if archive.data.label == dep_archive.data.label:
96-
pkg_json_files.append(make_pkg_json(ctx, ctx.executable._pkgjson, dep_archive.data.name, dep_archive))
107+
pkg_json_files.append(make_pkg_json_with_archive(ctx, dep_archive.data.name, dep_archive))
97108
compiled_go_files.extend(dep_archive.source.srcs)
98109
export_files.append(dep_archive.data.export_file)
99110
break

go/tools/gopackagesdriver/pkgjson/main.go

Lines changed: 20 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,8 @@ func main() {
2727
}
2828

2929
type params struct {
30-
id string
31-
pkgPath string
32-
exportFile string
33-
goFiles []string
34-
compiledGoFiles []string
35-
otherFiles []string
36-
imports map[string]string
30+
pkgJSONPath string
3731
cgoOutDir string
38-
// path to write the pkgjson
3932
output string
4033
}
4134

@@ -53,32 +46,16 @@ func parseArgs(args []string) (*params, error) {
5346
var params params
5447

5548
fs := flag.NewFlagSet("pkgjson", flag.ContinueOnError)
56-
fs.StringVar(&params.id, "id", "", "id")
57-
fs.StringVar(&params.pkgPath, "pkg_path", "", "package path")
58-
fs.StringVar(&params.exportFile, "export_file", "", "export file")
49+
50+
fs.StringVar(&params.pkgJSONPath, "pkg_json", "", "pkg json file")
5951
fs.StringVar(&params.cgoOutDir, "cgo_out_dir", "", "cgo out dir")
60-
rawGoFiles := fs.String("go_files", "", "a comma separated list of go files")
61-
rawCompiledGoFiles := fs.String("compiled_go_files", "", "a comma separated list of compiled go files")
62-
rawOtherFiles := fs.String("other_files", "", "a comma separated list of other files")
63-
rawImports := fs.String("imports", "", "comma separate pairs of importpath=label")
64-
fs.StringVar(&params.output, "output", "", "path to write the pkgjson")
52+
fs.StringVar(&params.output, "output", "", "output file")
6553

6654
err := fs.Parse(args)
6755
if err != nil {
6856
return nil, err
6957
}
7058

71-
params.goFiles = strings.Split(*rawGoFiles, ",")
72-
params.compiledGoFiles = strings.Split(*rawCompiledGoFiles, ",")
73-
params.otherFiles = strings.Split(*rawOtherFiles, ",")
74-
params.imports = make(map[string]string)
75-
if len(*rawImports) > 0 {
76-
for _, rawImport := range strings.Split(*rawImports, ",") {
77-
parts := strings.Split(rawImport, "=")
78-
params.imports[parts[0]] = parts[1]
79-
}
80-
}
81-
8259
return &params, nil
8360
}
8461

@@ -87,14 +64,23 @@ func run(args []string) error {
8764
if err != nil {
8865
return err
8966
}
67+
68+
b, err := os.ReadFile(params.pkgJSONPath)
69+
if err != nil {
70+
return err
71+
}
72+
73+
var pjson pkgJson
74+
json.Unmarshal(b, &pjson)
75+
9076
data := pkgJson{
91-
ID: params.id,
92-
PkgPath: params.pkgPath,
93-
ExportFile: params.exportFile,
94-
GoFiles: params.goFiles,
95-
CompiledGoFiles: params.compiledGoFiles,
96-
OtherFiles: params.otherFiles,
97-
Imports: params.imports,
77+
ID: pjson.ID,
78+
PkgPath: pjson.PkgPath,
79+
ExportFile: pjson.ExportFile,
80+
GoFiles: pjson.GoFiles,
81+
CompiledGoFiles: pjson.CompiledGoFiles,
82+
OtherFiles: pjson.OtherFiles,
83+
Imports: pjson.Imports,
9884
}
9985
if err = processCgoFiles(params.cgoOutDir, &data, resolvePath); err != nil {
10086
return err

go/tools/gopackagesdriver/pkgjson/pkg_json.bzl

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,38 +3,26 @@ load(
33
"paths",
44
)
55

6-
def write_pkg_json(ctx, pkg_json_tool, archive, output_json):
6+
def write_pkg_json(ctx, pkg_json_tool, archive, pkg_json):
7+
args = ctx.actions.args()
78
inputs = [src for src in archive.data.srcs if src.path.endswith(".go")]
8-
input_paths = [file_path(src) for src in inputs]
9-
cgo_out_dir = ""
9+
10+
tmp_json = ctx.actions.declare_file(pkg_json.path + ".tmp")
11+
pkg_info = _go_archive_to_pkg(archive)
12+
ctx.actions.write(tmp_json, content = json.encode(pkg_info))
13+
inputs.append(tmp_json)
14+
args.add("--pkg_json", tmp_json.path)
15+
1016
if archive.data.cgo_out_dir:
1117
inputs.append(archive.data.cgo_out_dir)
12-
cgo_out_dir = file_path(archive.data.cgo_out_dir)
18+
args.add("--cgo_out_dir", file_path(archive.data.cgo_out_dir))
1319

20+
args.add("--output", pkg_json.path)
1421
ctx.actions.run(
1522
inputs = inputs,
16-
outputs = [output_json],
17-
executable = pkg_json_tool,
18-
arguments = [
19-
"--id",
20-
str(archive.data.label),
21-
"--pkg_path",
22-
archive.data.importpath,
23-
"--export_file",
24-
file_path(archive.data.export_file),
25-
"--go_files",
26-
",".join(input_paths),
27-
"--compiled_go_files",
28-
",".join(input_paths),
29-
"--cgo_out_dir",
30-
cgo_out_dir,
31-
"--other_files",
32-
",".join([file_path(src) for src in archive.data.srcs if not src.path.endswith(".go")]),
33-
"--imports",
34-
",".join([pkg.data.importpath + "=" + str(pkg.data.label) for pkg in archive.direct]),
35-
"--output",
36-
output_json.path,
37-
],
23+
outputs = [pkg_json],
24+
executable = pkg_json_tool.path,
25+
arguments = [args],
3826
tools = [pkg_json_tool],
3927
)
4028

@@ -48,3 +36,26 @@ def file_path(f):
4836

4937
def is_file_external(f):
5038
return f.owner.workspace_root != ""
39+
40+
def _go_archive_to_pkg(archive):
41+
go_files = [
42+
file_path(src)
43+
for src in archive.data.srcs
44+
if src.path.endswith(".go")
45+
]
46+
return struct(
47+
ID = str(archive.data.label),
48+
PkgPath = archive.data.importpath,
49+
ExportFile = file_path(archive.data.export_file),
50+
GoFiles = go_files,
51+
CompiledGoFiles = go_files,
52+
OtherFiles = [
53+
file_path(src)
54+
for src in archive.data.srcs
55+
if not src.path.endswith(".go")
56+
],
57+
Imports = {
58+
pkg.data.importpath: str(pkg.data.label)
59+
for pkg in archive.direct
60+
},
61+
)

0 commit comments

Comments
 (0)