Skip to content

Commit c3ee3e9

Browse files
authored
perf: parallelize code generation (#330)
Parallelize code generation via magefile deps to mitigate longer build times.
1 parent 8c2b863 commit c3ee3e9

1 file changed

Lines changed: 43 additions & 1 deletion

File tree

magefiles/magesrc/magesrc.go

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package magesrc
55

66
import (
77
"errors"
8+
"strings"
89

910
"github.com/magefile/mage/mg"
1011
"github.com/magefile/mage/sh"
@@ -17,7 +18,9 @@ var ErrSrcCode = errors.New("source code generation failed")
1718
func Generate() error {
1819
mageutil.MagePrintln(mageutil.MsgStart, "Running code generation...")
1920

20-
err := sh.Run(mg.GoCmd(), "generate", "./...")
21+
// We run code generation for all packages in parallel, up to the number of CPU cores.
22+
// This saves meaningful time now that we have many packages with code generation.
23+
err := generateForAllPackagesInParallel()
2124
if err != nil {
2225
return mageutil.PrintAndReturnError("Code generation failed.", ErrSrcCode, err)
2326
}
@@ -26,3 +29,42 @@ func Generate() error {
2629

2730
return nil
2831
}
32+
33+
func generateForAllPackagesInParallel() error {
34+
paths, err := listPackages()
35+
if err != nil {
36+
return err
37+
}
38+
39+
generateDeps := []interface{}{}
40+
41+
// Build up a list of dependencies to run in parallel; we'll let [mg.Deps] take care of
42+
// the parallel execution.
43+
for _, path := range paths {
44+
generateDeps = append(generateDeps, mg.F(generateForPackage, path))
45+
}
46+
47+
mg.Deps(generateDeps...)
48+
49+
return nil
50+
}
51+
52+
// listPackages lists all Go packages in the current module.
53+
func listPackages() ([]string, error) {
54+
out, err := sh.Output(mg.GoCmd(), "list", "./...")
55+
if err != nil {
56+
return nil, mageutil.PrintAndReturnError("Failed to list Go packages.", ErrSrcCode, err)
57+
}
58+
59+
return strings.Split(strings.TrimSpace(out), "\n"), nil
60+
}
61+
62+
// generateForPackage runs code generation for a specific package.
63+
func generateForPackage(path string) error {
64+
err := sh.Run(mg.GoCmd(), "generate", path)
65+
if err != nil {
66+
return mageutil.PrintAndReturnError("Code generation failed.", ErrSrcCode, err)
67+
}
68+
69+
return nil
70+
}

0 commit comments

Comments
 (0)