Repository navigation
feat: add file operation actions - #2151
Conversation
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughThis PR introduces a complete "file" executor for the Dagu DAG system, enabling built-in filesystem operations (stat, read, write, copy, move, delete, mkdir, list) within DAG workflows. It defines the JSON schema contract, registers the executor type in the spec layer, implements the runtime operations with configuration validation, and provides unit and integration tests validating the complete flow. ChangesFile Executor Feature
Sequence Diagram(s)sequenceDiagram
participant DAG as DAG Loader
participant Normalizer as StepV2 Normalizer
participant Validator as Schema Validator
participant Executor as FileExecutor
participant FS as Filesystem
DAG->>Validator: Load step with action: file.write
Validator->>Validator: Check action in file.* set
Validator->>Validator: Validate with object against fileActionConfig
Validator-->>DAG: Valid step
DAG->>Normalizer: Normalize step
Normalizer->>Normalizer: Match file.write in builtinActionNormalizers
Normalizer-->>DAG: Resolved to executorType: file, command: write
DAG->>Executor: Run(ctx, step)
Executor->>Executor: Decode and validate configuration
Executor->>Executor: Extract operation (write) from command
Executor->>FS: Create parent dirs and write file
FS-->>Executor: File created
Executor->>Executor: Marshal operation result to JSON
Executor-->>DAG: JSON output on stdout, exit code 0
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@internal/cmn/schema/dag.schema.json`:
- Around line 5583-5584: The schema now allows builtinExecutorType value "file"
but never wires that type to the fileActionConfig schema, so steps/executors
with type:"file" are unconstrained; update the schema so "file" is handled the
same as action: "file.*" by adding an explicit branch in definitions.step.allOf
and definitions.executorObject.allOf that maps type == "file" to the existing
fileActionConfig (or references the same fileActionConfig definition), ensuring
executor and step validation uses fileActionConfig instead of permitting
arbitrary config.
In `@internal/runtime/builtin/file/config.go`:
- Around line 56-61: The decoder currently allows unknown keys because
mapstructure.DecoderConfig has ErrorUnused: false; in decodeConfig enable strict
decoding by setting ErrorUnused: true on the mapstructure.DecoderConfig (i.e.,
in the mapstructure.NewDecoder call) so unknown fields produce an error, and
also update the executor JSON schema for the same config (the schema block that
defines the config object) to include "additionalProperties": false so the
schema rejects unknown keys; reference mapstructure.NewDecoder/DecoderConfig,
ErrorUnused, decodeConfig and the JSON schema object/AdditionalProperties to
locate the two changes.
In `@internal/runtime/builtin/file/file.go`:
- Around line 359-370: The current overwrite flow removes the destination before
the move completes, causing possible data loss; change the logic in the
file-move routine so you first attempt to move (call os.Rename(source,
destination)) and if that returns syscall.EXDEV fall back to
e.moveAcrossDevices(source, destination), and only after the move succeeds
perform cleanup of any previous destination when e.cfg.Overwrite requires it (or
ensure the move implementation itself replaces atomically); update error
handling to return failures from os.Rename or moveAcrossDevices without having
already removed destination so the original destination remains intact on error.
- Around line 303-315: After resolving source and destination in runCopy (after
calls to e.resolvePath) and runMove, add an explicit equality guard that
compares the resolved source and destination strings and returns a clear
non-destructive error if they are identical; this prevents copyRegularFile from
opening the destination with os.O_TRUNC and runMove from calling
os.RemoveAll(destination) before os.Rename when paths are the same. Locate the
checks in runCopy and runMove (use the resolved variables named source and
destination) and return an appropriate error value (not performing any
filesystem operations) when source == destination.
- Around line 515-530: The code must reject cases where the destination is
inside the source tree before creating the destination to avoid WalkDir
recursing into the new dir; in the copy path (inside the block handling
info.IsDir) and in moveAcrossDevices/copyPath fallback, resolve and clean both
source and destination (apply filepath.EvalSymlinks when FollowSymlinks is true,
then filepath.Abs and filepath.Clean), compute rel :=
filepath.Rel(sourceResolved, destResolved) and if rel == "." or (rel != "" &&
!strings.HasPrefix(rel, ".."+string(filepath.Separator)) && rel != "..") return
an error like "destination is under source: copy not allowed"; perform this
check before calling ensureDir, before calling e.copyDir, and in the
moveAcrossDevices path so overlapping trees are rejected upfront.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 026a218d-d0ef-4b30-8f28-30c3cd1db026
📒 Files selected for processing (11)
internal/cmn/schema/dag.schema.jsoninternal/cmn/schema/dag_schema_test.gointernal/core/spec/step_test.gointernal/core/spec/step_types.gointernal/core/spec/step_v2.gointernal/core/spec/step_v2_test.gointernal/intg/file_test.gointernal/runtime/builtin/builtin.gointernal/runtime/builtin/file/config.gointernal/runtime/builtin/file/file.gointernal/runtime/builtin/file/file_test.go
Summary
Add built-in local file operation actions for workflows, including stat, read, write, copy, move, delete, mkdir, and list.
Changes
fileexecutor and register file action normalization forfile.*actions.type: fileconfigs.Related Issues
N/A
Validation
git diff --checkgo test ./internal/core/spec ./internal/cmn/schema ./internal/runtime/builtin/file -count=1go test ./internal/runtime/builtin/... -count=1go test ./internal/intg -run TestFileActions -count=1Checklist