mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
build(Makefile): enable parallel make -j gen with correct dependency graph (#22612)
`make gen` could not run with `-j` because inter-target dependency edges were missing. Multiple recipes compile `coderd/rbac` (which includes generated files like `object_gen.go`), and without explicit ordering, parallel runs produced syntax errors from mid-write reads. Three main changes: **Dependency graph fixes** declare the compile-time chain through `coderd/rbac` so that `object_gen.go` is written before anything that imports it is compiled. The DB generation targets use a GNU Make 4.3+ grouped target (`&:`) so Make knows `generate.sh` co-produces `querier.go`, `unique_constraint.go`, `dbmetrics`, and `dbauthz` in a single invocation. `SKIP_DUMP_SQL=1` avoids re-entrant `make` inside `generate.sh` when the Makefile already guarantees `dump.sql` is fresh. **`scripts/atomicwrite` package** replaces `os.WriteFile` in all gen scripts with a temp-file-in-same-dir + rename pattern, preventing interrupted runs from leaving partial files. **`.PRECIOUS` and shell atomic writes** protect git-tracked generated files from Make's default delete-on-error behavior. Since these files are committed, deletion is worse than staleness -- `git restore` is the recovery path. CI now runs `make -j --output-sync -B gen` (~32s, down from ~85s serial). | Scenario | Before | After | |-----------------------------------|--------------------|----------| | `make gen` (serial) | 95s | 95s | | `make -j gen` (parallel) | race error | **22s** | | CI `make -j --output-sync -B gen` | forced serial ~85s | **~32s** |
This commit is contained in:
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/acarl005/stripansi"
|
||||
|
||||
"github.com/coder/coder/v2/buildinfo"
|
||||
"github.com/coder/coder/v2/scripts/atomicwrite"
|
||||
"github.com/coder/flog"
|
||||
"github.com/coder/serpent"
|
||||
)
|
||||
@@ -125,24 +126,21 @@ func genTree(dir string, cmd *serpent.Command, wroteLog map[string]*serpent.Comm
|
||||
}
|
||||
|
||||
path := filepath.Join(dir, fmtDocFilename(cmd))
|
||||
// Write out root.
|
||||
fi, err := os.OpenFile(
|
||||
path,
|
||||
os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0o644,
|
||||
)
|
||||
|
||||
var buf strings.Builder
|
||||
err := writeCommand(&buf, cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer fi.Close()
|
||||
|
||||
err = writeCommand(fi, cmd)
|
||||
err = atomicwrite.File(path, []byte(buf.String()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
flog.Successf(
|
||||
"wrote\t%s",
|
||||
fi.Name(),
|
||||
path,
|
||||
)
|
||||
wroteLog[path] = cmd
|
||||
for _, sub := range cmd.Children {
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/coder/coder/v2/enterprise/cli"
|
||||
"github.com/coder/coder/v2/scripts/atomicwrite"
|
||||
"github.com/coder/flog"
|
||||
"github.com/coder/serpent"
|
||||
)
|
||||
@@ -94,6 +95,11 @@ func main() {
|
||||
cliMarkdownDir = filepath.Join(docsDir, "reference/cli")
|
||||
)
|
||||
|
||||
if d := os.Getenv("DOCS_DIR"); d != "" {
|
||||
docsDir = d
|
||||
cliMarkdownDir = filepath.Join(docsDir, "reference/cli")
|
||||
}
|
||||
|
||||
cmd, err := root.Command(root.EnterpriseSubcommands())
|
||||
if err != nil {
|
||||
flog.Fatalf("creating command: %v", err)
|
||||
@@ -188,7 +194,7 @@ func main() {
|
||||
flog.Fatalf("marshaling manifest: %v", err)
|
||||
}
|
||||
|
||||
err = os.WriteFile(manifestPath, manifestByt, 0o600)
|
||||
err = atomicwrite.File(manifestPath, manifestByt)
|
||||
if err != nil {
|
||||
flog.Fatalf("writing manifest: %v", err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user