Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@yottahmd
Copy link
Collaborator

@yottahmd yottahmd commented Dec 7, 2025

Summary by CodeRabbit

  • New Features

    • Added --default-working-dir CLI flag to start and enqueue to set a fallback working directory for DAGs without an explicit workingDir
    • Sub-DAG executions now inherit the parent's working directory when not explicitly set; the flag is passed to sub-DAG launches
  • Tests

    • Added tests covering inheritance and explicit override behaviors for default working directory

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Dec 7, 2025

Walkthrough

Adds a --default-working-dir option and propagates it from CLI (start/enqueue) through the spec loader and builder into runtime, enabling a default working directory for DAGs without an explicit workingDir and passing that value into sub-DAG execution commands.

Changes

Cohort / File(s) Summary
CLI flag declaration & wiring
internal/cmd/flags.go, internal/cmd/enqueue.go, internal/cmd/start.go
Declares defaultWorkingDirFlag in flags.go; integrates the flag into the enqueue and start command flag sets. Start reads the flag and forwards it to DAG loading via WithDefaultWorkingDir; enqueue gains the flag in its flag set (declaration present).
Spec loader: options & propagation
internal/core/spec/loader.go
Adds defaultWorkingDir to LoadOptions and introduces WithDefaultWorkingDir(defaultWorkingDir string) LoadOption. Propagates the option into build context so loader sets BuildOpts.DefaultWorkingDir when loading DAGs.
Spec builder: build option and resolution
internal/core/spec/builder.go
Adds public DefaultWorkingDir string to BuildOpts and updates buildWorkingDir logic to consider DefaultWorkingDir when a DAG lacks an explicit workingDir.
Runtime executor command construction
internal/runtime/executor/dag_runner.go
Changes SubDAGExecutor.buildCommand to conditionally insert a --default-working-dir argument when workDir is set and reorders when the DAG location arg is appended (after config-related args).
Tests: unit & integration updates
internal/core/spec/loader_test.go, internal/integration/workingdir_test.go
Adds TestWithDefaultWorkingDir with subtests checking precedence and absence scenarios. Updates integration assertions/messages to reflect inheritance behavior and that explicit workingDir overrides inherited/default values.

Sequence Diagram

sequenceDiagram
    autonumber
    participant User
    participant CLI as CLI (start/enqueue)
    participant Loader as Spec Loader
    participant Builder as Spec Builder
    participant Executor as SubDAG Executor
    Note over CLI,Loader: CLI reads --default-working-dir flag
    User->>CLI: invoke start/enqueue with --default-working-dir
    CLI->>Loader: loadDAGWithParams(..., WithDefaultWorkingDir(value))
    Loader->>Loader: set LoadOptions.defaultWorkingDir
    Loader->>Builder: create BuildOpts with DefaultWorkingDir
    Builder->>Builder: buildWorkingDir: choose explicit > DefaultWorkingDir > file dir
    Loader-->>CLI: return DAG spec (with resolved workingDir)
    CLI->>Executor: launch sub-DAG
    Executor->>Executor: buildCommand() adds --default-working-dir if workDir present
    Executor-->>User: sub-DAG process started with args (including default working dir)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Areas to review closely:
    • Propagation of defaultWorkingDir through all loader paths (Load, LoadYAML, LoadYAMLWithOpts).
    • Precedence logic in buildWorkingDir: explicit workingDir vs DefaultWorkingDir vs file directory.
    • CLI wiring: ensure enqueue/start flag handling is consistent and documented.
    • Argument ordering change in dag_runner.go to confirm runtime CLI semantics and quoting/escaping.

Poem

🐇 I found a flag beneath a log,
A default path for every cog,
Sub-DAGs now follow parental tracks,
No more wandering, they trace the map!
— nibble, hop, compile

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 58.33% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding a --default-working-dir flag to the start command, which is the primary feature implemented across multiple files.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 1456-working-dir

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8397993 and 45e6993.

📒 Files selected for processing (1)
  • internal/core/spec/loader.go (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • internal/core/spec/loader.go
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Test on ubuntu-latest

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
internal/cmd/flags.go (1)

160-165: defaultWorkingDirFlag definition is consistent and clear

Flag name/description match the new behaviour, and leaving bindViper unset keeps it strictly CLI-scoped, which seems appropriate here. If you ever want config-driven defaults, you could later add bindViper: true, but it’s not required for this PR.

internal/core/spec/builder.go (1)

81-86: DefaultWorkingDir threading and precedence look correct

Adding DefaultWorkingDir to BuildOpts and checking it in buildWorkingDir between explicit spec.WorkingDir and file-based fallback gives the intended override semantics for inherited working dirs, matching the new tests. Since callers (CLI/sub-DAG runner) already pass a concrete working directory, skipping env/path expansion here is reasonable; if you ever expose more user-facing inputs, you might normalise that value before constructing BuildOpts rather than here.

Also applies to: 644-680

internal/cmd/start.go (1)

60-60: --default-working-dir is correctly wired into DAG loading

Adding defaultWorkingDirFlag to startFlags and threading "default-working-dir" through loadDAGWithParams into spec.WithDefaultWorkingDir cleanly connects the CLI flag to BuildOpts.DefaultWorkingDir for both root and sub-DAG runs. The comment mentions sub-DAG inheritance (which is the main use case) but this also intentionally affects root DAGs when the flag is set, as covered by TestWithDefaultWorkingDir.

Also applies to: 369-377

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d5acf37 and 8397993.

📒 Files selected for processing (8)
  • internal/cmd/enqueue.go (1 hunks)
  • internal/cmd/flags.go (1 hunks)
  • internal/cmd/start.go (2 hunks)
  • internal/core/spec/builder.go (2 hunks)
  • internal/core/spec/loader.go (4 hunks)
  • internal/core/spec/loader_test.go (2 hunks)
  • internal/integration/workingdir_test.go (2 hunks)
  • internal/runtime/executor/dag_runner.go (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

**/*.go: Backend entrypoint in cmd/ orchestrates the scheduler and CLI; runtime, persistence, and service layers sit under internal/* (for example internal/runtime, internal/persistence)
Keep Go files gofmt/goimports clean; use tabs, PascalCase for exported symbols (SchedulerClient), lowerCamelCase for locals, and Err... names for package-level errors
Repository linting relies on golangci-lint; prefer idiomatic Go patterns, minimal global state, and structured logging helpers in internal/common

Files:

  • internal/core/spec/builder.go
  • internal/cmd/start.go
  • internal/integration/workingdir_test.go
  • internal/core/spec/loader_test.go
  • internal/runtime/executor/dag_runner.go
  • internal/cmd/flags.go
  • internal/core/spec/loader.go
  • internal/cmd/enqueue.go
**/*_test.go

📄 CodeRabbit inference engine (AGENTS.md)

**/*_test.go: Co-locate Go tests as *_test.go; favour table-driven cases and cover failure paths
Use stretchr/testify/require and shared fixtures from internal/test instead of duplicating mocks

Files:

  • internal/integration/workingdir_test.go
  • internal/core/spec/loader_test.go
🧠 Learnings (1)
📚 Learning: 2025-12-04T10:34:17.051Z
Learnt from: CR
Repo: dagu-org/dagu PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-04T10:34:17.051Z
Learning: Applies to **/*_test.go : Co-locate Go tests as `*_test.go`; favour table-driven cases and cover failure paths

Applied to files:

  • internal/core/spec/loader_test.go
🧬 Code graph analysis (4)
internal/cmd/start.go (2)
internal/common/logger/context.go (1)
  • Errorf (75-77)
internal/core/spec/loader.go (1)
  • WithDefaultWorkingDir (124-128)
internal/core/spec/loader_test.go (1)
internal/core/spec/loader.go (3)
  • LoadYAML (169-183)
  • WithDefaultWorkingDir (124-128)
  • Load (145-166)
internal/runtime/executor/dag_runner.go (2)
internal/common/config/context.go (1)
  • ConfigFileUsed (26-31)
internal/core/dag.go (1)
  • DAG (33-135)
internal/core/spec/loader.go (1)
internal/core/spec/builder.go (1)
  • BuildFlag (56-56)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Test on ubuntu-latest
🔇 Additional comments (5)
internal/cmd/enqueue.go (1)

32-32: Enqueue now correctly exposes --default-working-dir

Including defaultWorkingDirFlag in enqueueFlags keeps enqueue’s DAG loading behaviour aligned with start (both can now drive WithDefaultWorkingDir via loadDAGWithParams). Looks good.

internal/core/spec/loader_test.go (1)

3-13: New TestWithDefaultWorkingDir thoroughly exercises precedence rules

The added test cases (no file context, default vs file directory, explicit workingDir overriding the default) align with the new loader/builder semantics and should prevent regressions. Use of t.Parallel, require, and assert is consistent with the existing suite and prior testing guidelines. Based on learnings, this is solid coverage.

Also applies to: 549-617

internal/integration/workingdir_test.go (1)

20-22: Integration test expectations now match inherited/override semantics

The updated description and assert.Contains checks for call_child_with_wd vs call_child_no_wd correctly encode the new behaviour: explicit subDAG workingDir overrides, while a missing workingDir inherits the parent’s working directory for local runs. This gives good end-to-end coverage of the CLI + loader + executor path.

Also applies to: 90-104

internal/runtime/executor/dag_runner.go (1)

119-134: SubDAG executor now correctly passes --default-working-dir to start

Conditionally appending --default-working-dir=<workDir> and moving the DAG path after config arguments keeps the command line well-formed while enabling the loader to resolve a default working directory for child DAGs. Combined with cmd.Dir = workDir, this should give the desired inheritance semantics for local sub-DAG execution.

internal/core/spec/loader.go (1)

29-37: Loader-level defaultWorkingDir option is wired cleanly with one minor note

Extending LoadOptions with defaultWorkingDir, adding WithDefaultWorkingDir, and threading that into BuildOpts.DefaultWorkingDir in both Load and LoadYAML gives a consistent API surface and matches the builder/test expectations.

The repository uses keyed fields consistently in BuildOpts composite literals. Two empty BuildOpts{} literals exist in loader_test.go (lines 200, 210), which are safe from field reordering concerns. All other instances explicitly name their fields.

@yottahmd yottahmd merged commit 85b04da into main Dec 7, 2025
5 checks passed
@yottahmd yottahmd deleted the 1456-working-dir branch December 7, 2025 08:07
@codecov
Copy link

codecov bot commented Dec 8, 2025

Codecov Report

❌ Patch coverage is 80.00000% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 59.80%. Comparing base (78844bf) to head (45e6993).
⚠️ Report is 4 commits behind head on main.

Files with missing lines Patch % Lines
internal/cmd/start.go 20.00% 2 Missing and 2 partials ⚠️
internal/core/spec/loader.go 90.00% 1 Missing and 1 partial ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #1459      +/-   ##
==========================================
- Coverage   59.85%   59.80%   -0.06%     
==========================================
  Files         188      188              
  Lines       21238    21316      +78     
==========================================
+ Hits        12713    12749      +36     
- Misses       7202     7234      +32     
- Partials     1323     1333      +10     
Files with missing lines Coverage Δ
internal/cmd/enqueue.go 62.16% <ø> (ø)
internal/cmd/flags.go 100.00% <ø> (ø)
internal/core/spec/builder.go 68.38% <100.00%> (+0.05%) ⬆️
internal/runtime/executor/dag_runner.go 33.11% <100.00%> (+0.44%) ⬆️
internal/core/spec/loader.go 64.23% <90.00%> (+0.34%) ⬆️
internal/cmd/start.go 46.15% <20.00%> (-0.55%) ⬇️

... and 8 files with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 78844bf...45e6993. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants