Conversation
📝 WalkthroughWalkthroughAdds multi-format configuration support and parsing: JSONNet, JSON, YAML, TOML, INI, and HCL. Introduces per-format loaders, DTO mapping to RunConfig, new tests and testdata, example files and docs updates, plus dependency and linter configuration adjustments. Changes
Sequence DiagramsequenceDiagram
participant File as Config File<br/>(YAML/TOML/HCL/JSON/INI/JSONNet)
participant Dispatcher as loadConfigs<br/>(Dispatcher)
participant Parser as Format Parser
participant DTO as DTO Converter
participant Validator as Validation & Defaults
participant RunConfig as RunConfig
File->>Dispatcher: read file contents
Dispatcher->>Dispatcher: detect format (by extension / Jsonnet)
Dispatcher->>Parser: dispatch to format-specific loader
Parser->>DTO: parse into configScanDTO / named DTOs
DTO->>Validator: map fields, resolve types and cwd
Validator->>RunConfig: apply defaults and return populated RunConfig
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 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 |
a753c19 to
97abd88
Compare
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
There was a problem hiding this comment.
Actionable comments posted: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
go.mod (1)
5-35: 🧹 Nitpick | 🔵 TrivialConsider updating minor/patch versions and address gopkg.in supply-chain risk.
- hcl/v2 v2.24.0 and yaml.v3 v3.0.1 are at latest versions with no known vulnerabilities.
- go-toml/v2 v2.2.3 has a patch update available (v2.2.4, Apr 2025).
- go-cty v1.16.3 has a minor update available (v1.17.0, Sep 2025).
- ini.v1 v1.67.0 has a patch update available (v1.67.1, Jan 2026).
⚠️ Supply-chain risk: Thegopkg.indomain (used byini.v1andyaml.v3) is reported as expiring Mar 5, 2026. Consider a long-term migration strategy or ensure renewal/maintenance of these dependencies.No active CVEs detected for the current versions; yaml.v3 v3.0.1 includes a fix for CVE-2022-28948 (denial-of-service on invalid input).
internal/core/runconfig.go (1)
369-385:⚠️ Potential issue | 🟠 MajorSchema fields are silently dropped during DTO mapping.
stdout_file,stderr_file,kill_timeout,autorestart, andmax_restartsare in the schema/docs, but the DTOs don’t capture them and they’re hard-coded to zero values here. As a result, config values for these fields are ignored across all formats. Please add these fields to the DTOs/loaders and map them intoRunConfig(or remove them from the schema if they’re intentionally unsupported).
🤖 Fix all issues with AI agents
In `@docs/examples/config.toml`:
- Around line 1-13: The example contains an unsupported TOML table array section
`[[web-server]]` that the parser will ignore; remove the entire `[[web-server]]`
block (the duplicate example starting with `[[web-server]]` and its following
keys) so only the supported `[[processes]]` example remains (keep the existing
`name = "web-server"`, `command = "node"`, `args = ["server.js"]`, `env`,
`tags`, and `startup` under `[[processes]]` and delete the alternate
`[[web-server]]` block to avoid confusion).
In `@internal/core/runconfig_test.go`:
- Around line 46-53: The test loop in runconfig_test.go mistakenly asserts
expected values against themselves: change the comparisons in the loop that
currently use config.Watch.Valid and config.Watch.Value.String() on both sides
to compare expected (config) against actual by using actual[i].Watch.Valid and
actual[i].Watch.Value.String() on the RHS; keep the existing niling of
config.Watch.Value and actual[i].Watch.Value to ignore regexp internals. This
specifically affects the assertions that reference config.Watch.Valid and
config.Watch.Value.String() inside the for i, config := range expected loop.
- Around line 225-229: Remove the duplicate table-driven test entry named
"unsupported_format_duplicate" from the tests in runconfig_test.go; it is
identical to the existing "unsupported_format" case (same content, configFile,
and errMsg), so delete the "unsupported_format_duplicate" map entry to avoid
redundant tests and keep only the original "unsupported_format" case.
In `@readme.md`:
- Around line 135-137: The table in the generated README violates MD060 (missing
spaces around pipes); update the markdown generator (look for functions named
generateMarkdownTable, formatTableRow or renderTableSeparator) to emit spaced
pipes (" | ") between cells for the header and separator rows rather than
unspaced pipes, and add/adjust a unit test for table output to assert spaced
pipes for headers and separators.
- Around line 51-83: The README examples don't match the actual loaders: update
the docs generator to emit YAML as a mapping keyed by process name (matching the
YAML loader used in tests) instead of a list-with-name, and update the TOML
example to only show the supported [[processes]] array form (remove the invalid
[[web-server]] direct-table example); if you prefer to change code instead,
extend the YAML loader (e.g., LoadYAML / parseYAML) to accept both map-by-name
and list-of-objects-with-name, and adjust the TOML loader (e.g., LoadTOML /
parseTOML) to accept direct table arrays like [[web-server]]—but per the
comment, modify the README generator to produce the map-keyed YAML and only the
[[processes]] TOML form so docs and loaders stay consistent.
- Around line 51-52: The heading "#### YAML (.yaml, .yml)" is missing a blank
line after it and the adjacent link uses an empty link text
("[YAML](https://yaml.org/)[ ](https://noyaml.com/)"), triggering markdownlint
rules MD022 and MD039; update the generator (or the source) to always emit a
blank line after headings and replace the empty link text with a visible label
(e.g., change the empty "[ ](https://noyaml.com/)" to a meaningful label like
"[No YAML](https://noyaml.com/)"), and apply the same fixes to the other
affected headings/links with the same pattern.
| #### YAML (.yaml, .yml) | ||
| [YAML](https://yaml.org/)[ ](https://noyaml.com/)- Human-readable data serialization standard. | ||
|
|
||
| ```yaml | ||
| - name: "web-server" | ||
| command: "node" | ||
| args: ["server.js"] | ||
| env: | ||
| PORT: "3000" | ||
| NODE_ENV: "production" | ||
| tags: ["web"] | ||
| startup: true | ||
| ``` | ||
|
|
||
| #### TOML (.toml) | ||
| [TOML](https://toml.io/) - Tom's Obvious, Minimal Language configuration format. | ||
|
|
||
| ```toml | ||
| [[processes]] | ||
| name = "web-server" | ||
| command = "node" | ||
| args = ["server.js"] | ||
| env = { PORT = "3000", NODE_ENV = "production" } | ||
| tags = ["web"] | ||
| startup = true | ||
|
|
||
| # Or direct array format: | ||
| [[web-server]] | ||
| name = "web-server" | ||
| command = "node" | ||
| args = ["server.js"] | ||
| ``` | ||
|
|
There was a problem hiding this comment.
YAML/TOML examples don’t match the current loaders.
YAML loading currently expects a map keyed by process name (as used in testdata), while the example is a list with name. TOML loading supports [[processes]] / array-style entries, but the [[web-server]] example won’t parse. Please align docs with the loader, or extend the loader to accept these shapes. Since this file is generated, update the source examples/docs generator accordingly.
🧰 Tools
🪛 markdownlint-cli2 (0.20.0)
[warning] 51-51: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 52-52: Spaces inside link text
(MD039, no-space-in-links)
[warning] 52-52: Spaces inside link text
(MD039, no-space-in-links)
[warning] 65-65: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
🤖 Prompt for AI Agents
In `@readme.md` around lines 51 - 83, The README examples don't match the actual
loaders: update the docs generator to emit YAML as a mapping keyed by process
name (matching the YAML loader used in tests) instead of a list-with-name, and
update the TOML example to only show the supported [[processes]] array form
(remove the invalid [[web-server]] direct-table example); if you prefer to
change code instead, extend the YAML loader (e.g., LoadYAML / parseYAML) to
accept both map-by-name and list-of-objects-with-name, and adjust the TOML
loader (e.g., LoadTOML / parseTOML) to accept direct table arrays like
[[web-server]]—but per the comment, modify the README generator to produce the
map-keyed YAML and only the [[processes]] TOML form so docs and loaders stay
consistent.
| #### YAML (.yaml, .yml) | ||
| [YAML](https://yaml.org/)[ ](https://noyaml.com/)- Human-readable data serialization standard. |
There was a problem hiding this comment.
markdownlint: add blank lines after headings and avoid empty link text.
MD022 is triggered by missing blank lines after these new headings, and MD039 by the empty link text in the YAML line. Please adjust the generator (or source docs) to insert a blank line after headings and give the noyaml link a visible label.
Also applies to: 65-66, 84-85, 97-98, 113-114
🧰 Tools
🪛 markdownlint-cli2 (0.20.0)
[warning] 51-51: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 52-52: Spaces inside link text
(MD039, no-space-in-links)
[warning] 52-52: Spaces inside link text
(MD039, no-space-in-links)
🤖 Prompt for AI Agents
In `@readme.md` around lines 51 - 52, The heading "#### YAML (.yaml, .yml)" is
missing a blank line after it and the adjacent link uses an empty link text
("[YAML](https://yaml.org/)[ ](https://noyaml.com/)"), triggering markdownlint
rules MD022 and MD039; update the generator (or the source) to always emit a
blank line after headings and replace the empty link text with a visible label
(e.g., change the empty "[ ](https://noyaml.com/)" to a meaningful label like
"[No YAML](https://noyaml.com/)"), and apply the same fixes to the other
affected headings/links with the same pattern.
| | Field | Type | Description | Required | | ||
| |-------|------|-------------|----------| | ||
| | `name` | `string` | Process name (auto-generated if omitted) | No | | ||
| | `name` | `string` | Process name | Yes | |
There was a problem hiding this comment.
markdownlint: table pipe spacing.
MD060 indicates missing spaces around pipes in the header row. Please update the markdown generator to emit spaced pipes for tables.
🧰 Tools
🪛 markdownlint-cli2 (0.20.0)
[warning] 136-136: Table column style
Table pipe is missing space to the right for style "compact"
(MD060, table-column-style)
[warning] 136-136: Table column style
Table pipe is missing space to the left for style "compact"
(MD060, table-column-style)
[warning] 136-136: Table column style
Table pipe is missing space to the right for style "compact"
(MD060, table-column-style)
[warning] 136-136: Table column style
Table pipe is missing space to the left for style "compact"
(MD060, table-column-style)
[warning] 136-136: Table column style
Table pipe is missing space to the right for style "compact"
(MD060, table-column-style)
[warning] 136-136: Table column style
Table pipe is missing space to the left for style "compact"
(MD060, table-column-style)
[warning] 136-136: Table column style
Table pipe is missing space to the right for style "compact"
(MD060, table-column-style)
[warning] 136-136: Table column style
Table pipe is missing space to the left for style "compact"
(MD060, table-column-style)
🤖 Prompt for AI Agents
In `@readme.md` around lines 135 - 137, The table in the generated README violates
MD060 (missing spaces around pipes); update the markdown generator (look for
functions named generateMarkdownTable, formatTableRow or renderTableSeparator)
to emit spaced pipes (" | ") between cells for the header and separator rows
rather than unspaced pipes, and add/adjust a unit test for table output to
assert spaced pipes for headers and separators.
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
internal/core/runconfig.go (1)
325-391:⚠️ Potential issue | 🟠 MajorAllow missing names and generate a fallback name to preserve documented behavior.
RunConfig.Nameis documented as generated when absent, andnamegen.New()already exists. The current validation rejects nil names, so configs without explicitnamenow error and the fallback is unreachable. Generate a name when missing (or empty) instead of returning “missing name.”🛠️ Proposed fix
- if config.Name == nil { - return errors.New("missing name") - }+ name := "" + if config.Name != nil && strings.TrimSpace(*config.Name) != "" { + name = *config.Name + } else { + name = namegen.New() + } return RunConfig{ - Name: *config.Name, + Name: name, Command: config.Command, Args: args,+ "github.com/rprtr258/pm/internal/core/namegen"
🤖 Fix all issues with AI agents
In `@docs/main.ts`:
- Line 447: The docs mark the RunConfig field "name" as required but comments
say it is auto-generated if omitted; verify the actual RunConfig behavior
(constructor/validation) and then either (a) update the docs table row
containing code("name") to mark it optional ("No") or (b) update the RunConfig
validation/constructor to enforce presence of name; ensure you modify the single
table entry for code("name") in docs/main.ts or the RunConfig validation logic
accordingly so docs and runtime behavior match.
- Around line 427-429: The YAML list entry currently includes a_external(" ",
"https://noyaml.com/") which creates an empty-label accessible link; either
remove that a_external call or replace the first argument with visible text
(e.g., "No YAML") so the link has an accessible label. Update the array item in
docs/main.ts where the YAML description is built (the line containing a_external
and codeblock(configExamples.yaml, "yaml")) to ensure every a_external(...) uses
non-empty link text or is omitted.
In `@internal/core/runconfig_test.go`:
- Around line 41-56: In assertConfig, stop unconditionally zeroing
actual[i].Cwd; instead only normalize Cwd when the expected Cwd is empty (i.e.,
if expected[i].Cwd == "" then set actual[i].Cwd = ""), and update the test
fixtures that should have absolute Cwd values to set expected.Cwd to the
absolute path so those are validated; apply the same change to the duplicate
logic around lines referenced (the second block at 152-168) so both comparisons
only clear actual Cwd when expected is empty and otherwise compare absolute
paths.
In `@internal/core/runconfig.go`:
- Around line 46-87: The DependsOn fields in configScanDTO and configNamedKeyDTO
are missing toml struct tags so go-toml/v2 won't map TOML's depends_on key;
update the struct definitions (configScanDTO.DependsOn and
configNamedKeyDTO.DependsOn) to include `toml:"depends_on"` alongside the
existing json/yaml tags so TOML unmarshalling preserves dependency ordering.
| ["YAML (.yaml, .yml)", | ||
| p(a_external("YAML", "https://yaml.org/"), a_external(" ", "https://noyaml.com/"), "- Human-readable data serialization standard."), | ||
| codeblock(configExamples.yaml, "yaml")], |
There was a problem hiding this comment.
Avoid an empty-text external link in the YAML description.
The a_external(" ", ...) renders a link with no accessible label. Give it visible text or remove it.
💡 Suggested adjustment
- ["YAML (.yaml, .yml)",
- p(a_external("YAML", "https://yaml.org/"), a_external(" ", "https://noyaml.com/"), "- Human-readable data serialization standard."),
+ ["YAML (.yaml, .yml)",
+ p(a_external("YAML", "https://yaml.org/"), " / ", a_external("No YAML", "https://noyaml.com/"), " - Human-readable data serialization standard."),
codeblock(configExamples.yaml, "yaml")],📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ["YAML (.yaml, .yml)", | |
| p(a_external("YAML", "https://yaml.org/"), a_external(" ", "https://noyaml.com/"), "- Human-readable data serialization standard."), | |
| codeblock(configExamples.yaml, "yaml")], | |
| ["YAML (.yaml, .yml)", | |
| p(a_external("YAML", "https://yaml.org/"), " / ", a_external("No YAML", "https://noyaml.com/"), " - Human-readable data serialization standard."), | |
| codeblock(configExamples.yaml, "yaml")], |
🤖 Prompt for AI Agents
In `@docs/main.ts` around lines 427 - 429, The YAML list entry currently includes
a_external(" ", "https://noyaml.com/") which creates an empty-label accessible
link; either remove that a_external call or replace the first argument with
visible text (e.g., "No YAML") so the link has an accessible label. Update the
array item in docs/main.ts where the YAML description is built (the line
containing a_external and codeblock(configExamples.yaml, "yaml")) to ensure
every a_external(...) uses non-empty link text or is omitted.
| table( | ||
| ["Field", "Type", "Description", "Required"], | ||
| [code("name"), code("string"), "Process name (auto-generated if omitted)", "No"], | ||
| [code("name"), code("string"), "Process name", "Yes"], |
There was a problem hiding this comment.
Double-check whether name is truly required.
RunConfig comments indicate the name is auto-generated if omitted; if that still holds, keep this field optional in docs (or update validation to enforce it).
📌 Possible doc alignment
- [code("name"), code("string"), "Process name", "Yes"],
+ [code("name"), code("string"), "Process name", "No"],📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| [code("name"), code("string"), "Process name", "Yes"], | |
| [code("name"), code("string"), "Process name", "No"], |
🤖 Prompt for AI Agents
In `@docs/main.ts` at line 447, The docs mark the RunConfig field "name" as
required but comments say it is auto-generated if omitted; verify the actual
RunConfig behavior (constructor/validation) and then either (a) update the docs
table row containing code("name") to mark it optional ("No") or (b) update the
RunConfig validation/constructor to enforce presence of name; ensure you modify
the single table entry for code("name") in docs/main.ts or the RunConfig
validation logic accordingly so docs and runtime behavior match.
| func assertConfig(t *testing.T, expected, actual []RunConfig) { | ||
| t.Helper() | ||
| must.Eq(t, len(expected), len(actual)) | ||
| slices.SortFunc(expected, func(a, b RunConfig) int { return cmp.Compare(a.Name, b.Name) }) | ||
| slices.SortFunc(actual, func(a, b RunConfig) int { return cmp.Compare(a.Name, b.Name) }) | ||
| for i, config := range expected { | ||
| must.Eq(t, config.Watch.Valid, actual[i].Watch.Valid) | ||
| if config.Watch.Valid { | ||
| must.Eq(t, config.Watch.Value.String(), actual[i].Watch.Value.String()) | ||
| // NOTE: regexp removal | ||
| config.Watch.Value = nil | ||
| actual[i].Watch.Value = nil | ||
| } | ||
| actual[i].Cwd = "" // NOTE: temp dir removal | ||
| must.Eq(t, config, actual[i]) | ||
| } |
There was a problem hiding this comment.
Don’t blanket-clear Cwd; validate absolute paths in fixtures.
Zeroing actual[i].Cwd for every config hides regressions for fixtures that set absolute Cwd (e.g., JSON/TOML). Consider clearing only when the expected Cwd is empty, and set expected Cwd for those fixtures.
✅ Suggested fix
func assertConfig(t *testing.T, expected, actual []RunConfig) {
t.Helper()
must.Eq(t, len(expected), len(actual))
slices.SortFunc(expected, func(a, b RunConfig) int { return cmp.Compare(a.Name, b.Name) })
slices.SortFunc(actual, func(a, b RunConfig) int { return cmp.Compare(a.Name, b.Name) })
for i, config := range expected {
must.Eq(t, config.Watch.Valid, actual[i].Watch.Valid)
if config.Watch.Valid {
must.Eq(t, config.Watch.Value.String(), actual[i].Watch.Value.String())
// NOTE: regexp removal
config.Watch.Value = nil
actual[i].Watch.Value = nil
}
- actual[i].Cwd = "" // NOTE: temp dir removal
+ if config.Cwd == "" {
+ actual[i].Cwd = "" // NOTE: temp dir removal
+ }
must.Eq(t, config, actual[i])
}
} "json_simple.json": {
{
Name: "simple-service",
Command: "echo",
Args: []string{"Hello", "JSON!"},
+ Cwd: "/tmp",
Env: map[string]string{"SERVICE_NAME": "test", "VERSION": "1.0.0"},
Tags: []string{"simple", "test"},
},
},
"toml_simple.toml": {
{
Name: "simple-service",
Command: "echo",
Args: []string{"Hello", "TOML!"},
+ Cwd: "/tmp",
Env: map[string]string{"SERVICE_NAME": "test", "VERSION": "1.0.0"},
Tags: []string{"simple", "test"},
},
},Also applies to: 152-168
🤖 Prompt for AI Agents
In `@internal/core/runconfig_test.go` around lines 41 - 56, In assertConfig, stop
unconditionally zeroing actual[i].Cwd; instead only normalize Cwd when the
expected Cwd is empty (i.e., if expected[i].Cwd == "" then set actual[i].Cwd =
""), and update the test fixtures that should have absolute Cwd values to set
expected.Cwd to the absolute path so those are validated; apply the same change
to the duplicate logic around lines referenced (the second block at 152-168) so
both comparisons only clear actual Cwd when expected is empty and otherwise
compare absolute paths.
| type configScanDTO struct { | ||
| Name *string `json:"name"` | ||
| Cwd *string `json:"cwd"` | ||
| Env map[string]string `json:"env"` | ||
| Command string `json:"command"` | ||
| Args []any `json:"args"` | ||
| Tags []string `json:"tags"` | ||
| Watch *string `json:"watch"` | ||
| Startup bool `json:"startup"` | ||
| DependsOn []string `json:"depends_on" yaml:"depends_on"` | ||
| Cron *string `json:"cron"` | ||
| } | ||
|
|
||
| type configNamedKeyDTO struct { | ||
| Cwd *string `json:"cwd"` | ||
| Env map[string]string `json:"env"` | ||
| Command string `json:"command"` | ||
| Args []any `json:"args"` | ||
| Tags []string `json:"tags"` | ||
| Watch *string `json:"watch"` | ||
| Startup bool `json:"startup"` | ||
| DependsOn []string `json:"depends_on" yaml:"depends_on"` | ||
| Cron *string `json:"cron"` | ||
| } | ||
|
|
||
| return !stat.IsDir() | ||
| type hclProcess struct { | ||
| Name string `hcl:"name,label"` | ||
| Cwd *string `hcl:"cwd,optional"` | ||
| Env map[string]string `hcl:"env,optional"` | ||
| Command string `hcl:"command"` | ||
| Args []string `hcl:"args,optional"` | ||
| Tags []string `hcl:"tags,optional"` | ||
| Watch *string `hcl:"watch,optional"` | ||
| Startup bool `hcl:"startup,optional"` | ||
| DependsOn []string `hcl:"depends_on,optional"` | ||
| Cron *string `hcl:"cron,optional"` | ||
| Body hcl.Body `hcl:",remain"` | ||
| } | ||
|
|
||
| type hclConfigFile struct { | ||
| Processes []*hclProcess `hcl:"process,block"` | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
go-toml/v2 struct tags json tag behavior unmarshalling
💡 Result:
In github.com/pelletier/go-toml/v2, struct field naming/options for both marshaling and unmarshaling are controlled by the toml struct tag (not json). The toml tag’s format intentionally mirrors encoding/json: toml:"name,opt1,opt2" (name can be empty to specify only options). Supported options include multiline, inline, omitempty, and commented (and a separate comment tag exists for emitting comments). [1]
For unmarshaling, v2 matches keys to struct fields in a case-insensitive way (similar to encoding/json). If you need exact control (e.g., to avoid ambiguous casing), you should explicitly set field names with toml:"...". [2]
Implication: if your struct only has json:"..." tags, go-toml/v2 will not use those names; add toml:"..." tags to get the desired mapping. [1]
Sources:
[1] https://pkg.go.dev/github.com/pelletier/go-toml/v2 (Struct tags section)
[2] https://pkg.go.dev/github.com/pelletier/go-toml/v2 (Migrating from v1 → Automatic field name guessing)
🏁 Script executed:
# Check how TOML unmarshalling is used in the file
rg -A 5 -B 5 "json.Unmarshal|toml.Unmarshal|yaml.Unmarshal" internal/core/runconfig.go | head -80Repository: rprtr258/pm
Length of output: 1003
Add explicit toml tags for depends_on to ensure TOML configs parse dependency ordering.
go-toml/v2 does not honor json struct tags during unmarshalling—it uses only toml tags. Without toml:"depends_on" tags on the DependsOn fields in configScanDTO and configNamedKeyDTO, TOML-formatted configs will silently drop the depends_on key and lose dependency ordering.
🔧 Proposed fix
type configScanDTO struct {
Name *string `json:"name"`
Cwd *string `json:"cwd"`
Env map[string]string `json:"env"`
Command string `json:"command"`
Args []any `json:"args"`
Tags []string `json:"tags"`
Watch *string `json:"watch"`
Startup bool `json:"startup"`
- DependsOn []string `json:"depends_on" yaml:"depends_on"`
+ DependsOn []string `json:"depends_on" yaml:"depends_on" toml:"depends_on"`
Cron *string `json:"cron"`
}
type configNamedKeyDTO struct {
Cwd *string `json:"cwd"`
Env map[string]string `json:"env"`
Command string `json:"command"`
Args []any `json:"args"`
Tags []string `json:"tags"`
Watch *string `json:"watch"`
Startup bool `json:"startup"`
- DependsOn []string `json:"depends_on" yaml:"depends_on"`
+ DependsOn []string `json:"depends_on" yaml:"depends_on" toml:"depends_on"`
Cron *string `json:"cron"`
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| type configScanDTO struct { | |
| Name *string `json:"name"` | |
| Cwd *string `json:"cwd"` | |
| Env map[string]string `json:"env"` | |
| Command string `json:"command"` | |
| Args []any `json:"args"` | |
| Tags []string `json:"tags"` | |
| Watch *string `json:"watch"` | |
| Startup bool `json:"startup"` | |
| DependsOn []string `json:"depends_on" yaml:"depends_on"` | |
| Cron *string `json:"cron"` | |
| } | |
| type configNamedKeyDTO struct { | |
| Cwd *string `json:"cwd"` | |
| Env map[string]string `json:"env"` | |
| Command string `json:"command"` | |
| Args []any `json:"args"` | |
| Tags []string `json:"tags"` | |
| Watch *string `json:"watch"` | |
| Startup bool `json:"startup"` | |
| DependsOn []string `json:"depends_on" yaml:"depends_on"` | |
| Cron *string `json:"cron"` | |
| } | |
| return !stat.IsDir() | |
| type hclProcess struct { | |
| Name string `hcl:"name,label"` | |
| Cwd *string `hcl:"cwd,optional"` | |
| Env map[string]string `hcl:"env,optional"` | |
| Command string `hcl:"command"` | |
| Args []string `hcl:"args,optional"` | |
| Tags []string `hcl:"tags,optional"` | |
| Watch *string `hcl:"watch,optional"` | |
| Startup bool `hcl:"startup,optional"` | |
| DependsOn []string `hcl:"depends_on,optional"` | |
| Cron *string `hcl:"cron,optional"` | |
| Body hcl.Body `hcl:",remain"` | |
| } | |
| type hclConfigFile struct { | |
| Processes []*hclProcess `hcl:"process,block"` | |
| } | |
| type configScanDTO struct { | |
| Name *string `json:"name"` | |
| Cwd *string `json:"cwd"` | |
| Env map[string]string `json:"env"` | |
| Command string `json:"command"` | |
| Args []any `json:"args"` | |
| Tags []string `json:"tags"` | |
| Watch *string `json:"watch"` | |
| Startup bool `json:"startup"` | |
| DependsOn []string `json:"depends_on" yaml:"depends_on" toml:"depends_on"` | |
| Cron *string `json:"cron"` | |
| } | |
| type configNamedKeyDTO struct { | |
| Cwd *string `json:"cwd"` | |
| Env map[string]string `json:"env"` | |
| Command string `json:"command"` | |
| Args []any `json:"args"` | |
| Tags []string `json:"tags"` | |
| Watch *string `json:"watch"` | |
| Startup bool `json:"startup"` | |
| DependsOn []string `json:"depends_on" yaml:"depends_on" toml:"depends_on"` | |
| Cron *string `json:"cron"` | |
| } | |
| type hclProcess struct { | |
| Name string `hcl:"name,label"` | |
| Cwd *string `hcl:"cwd,optional"` | |
| Env map[string]string `hcl:"env,optional"` | |
| Command string `hcl:"command"` | |
| Args []string `hcl:"args,optional"` | |
| Tags []string `hcl:"tags,optional"` | |
| Watch *string `hcl:"watch,optional"` | |
| Startup bool `hcl:"startup,optional"` | |
| DependsOn []string `hcl:"depends_on,optional"` | |
| Cron *string `hcl:"cron,optional"` | |
| Body hcl.Body `hcl:",remain"` | |
| } | |
| type hclConfigFile struct { | |
| Processes []*hclProcess `hcl:"process,block"` | |
| } |
🤖 Prompt for AI Agents
In `@internal/core/runconfig.go` around lines 46 - 87, The DependsOn fields in
configScanDTO and configNamedKeyDTO are missing toml struct tags so go-toml/v2
won't map TOML's depends_on key; update the struct definitions
(configScanDTO.DependsOn and configNamedKeyDTO.DependsOn) to include
`toml:"depends_on"` alongside the existing json/yaml tags so TOML unmarshalling
preserves dependency ordering.
Summary by CodeRabbit
New Features
Documentation
Tests
✏️ Tip: You can customize this high-level summary in your review settings.