Add workflow option to stats command - #247
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughThe ChangesPer-workflow statistics reporting
Estimated code review effort: 3 (Moderate) | ~22 minutes Possibly related issues
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
3fb5199 to
b134da4
Compare
66ed189 to
51fc334
Compare
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (2)
lib/cli/stats.js (2)
370-371: 💤 Low valueMisleading parameter name
templatesInWorkflow.The parameter is named
templatesInWorkflowbut it actually receives a full workflow object (which is then passed toyamlFilesActivity). The naming is inconsistent with the actual usage. Consider renaming toworkflowfor clarity.-async function getYamlSummary(sinceDate, templatesInWorkflow) { - const yamlActivity = await yamlFilesActivity(sinceDate, templatesInWorkflow); +async function getYamlSummary(sinceDate, workflow) { + const yamlActivity = await yamlFilesActivity(sinceDate, workflow);🤖 Prompt for 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. In `@lib/cli/stats.js` around lines 370 - 371, The parameter name templatesInWorkflow in function getYamlSummary is misleading because it actually expects a full workflow object passed into yamlFilesActivity; rename the parameter to workflow (update the function signature of getYamlSummary and all internal references) and update any call sites to pass the same workflow variable name so usage is consistent with the actual object being passed to yamlFilesActivity.
319-344: 💤 Low valueNo defensive checks for missing workflow properties.
If a workflow JSON file is malformed or missing the
templatesproperty (or its sub-properties likereconciliations,exports,accounts), the code will throw with an unclear error. Consider adding defensive checks or clearer error messages.💡 Optional: Add defensive validation
// Fetch workflow // Assume no empty items if present within the workflow. + if (!workflow.templates) { + consola.error(`Workflow "${workflow.name || 'unknown'}" is missing 'templates' property`); + process.exit(1); + } summary.workflow_name = workflow.name; // Reconciliations - const reconciliationsInWorkflow = workflow.templates.reconciliations; + const reconciliationsInWorkflow = workflow.templates.reconciliations || []; // ... - const exportFilesInWorkflow = workflow.templates.exports; + const exportFilesInWorkflow = workflow.templates.exports || []; // ... - const accountTemplatesInWorkflow = workflow.templates.accounts; + const accountTemplatesInWorkflow = workflow.templates.accounts || [];🤖 Prompt for 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. In `@lib/cli/stats.js` around lines 319 - 344, The code assumes workflow.templates and its sub-properties exist (e.g., workflow.templates.reconciliations, .exports, .accounts), which can throw on malformed workflow JSON; update the start of this block to defensively validate workflow and its template arrays (or normalize them) before using them: check that workflow is truthy, that workflow.templates is an object, and that workflow.templates.reconciliations, workflow.templates.exports, workflow.templates.accounts are arrays (fallback to [] if missing) or throw a clear, descriptive error; ensure subsequent uses of reconciliationsInWorkflow, exportFilesInWorkflow, accountTemplatesInWorkflow, and calls to listExternallyManagedTemplates/countYamlFiles use these validated/normalized variables so percentageRoundTwo and .length won't fail.
🤖 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 `@lib/cli/stats.js`:
- Around line 23-26: The code currently sets workflowsFolder and populates
workflowHandles using fs.readdirSync which will throw if the "workflows"
directory is missing; update the logic around the
workflowsFolder/workflowHandles assignment (the workflowsFolder const and
workflowHandles variable) to handle a missing folder by either checking
fs.existsSync(workflowsFolder) before calling fs.readdirSync or wrapping
readdirSync in a try/catch and falling back to an empty array, and ensure any
caught error is handled or logged rather than allowed to crash the process.
- Around line 55-58: The TEMPLATE_PATTERN is built from raw template names
(templatesInWorkflow) so regex metacharacters in names break the pattern; before
joining, escape each template string (e.g., implement or use an escapeRegExp
helper and map over templatesInWorkflow to escape chars like . * + ? ^ $ ( ) [ ]
{ } | \ /) then join the escaped names to build TEMPLATE_PATTERN and proceed to
construct YAML_EXPRESSION and fileTypeRegExp from that escaped pattern (refer to
templatesInWorkflow, TEMPLATE_PATTERN, YAML_EXPRESSION, fileTypeRegExp).
In `@lib/utils/fsUtils.js`:
- Around line 483-495: getWorkflow currently uses the raw CLI-provided
workflowHandle to build file paths allowing path traversal; update getWorkflow
to validate and sanitize workflowHandle (e.g., reject any path separators, "..",
or characters outside a safe whitelist like /^[A-Za-z0-9_-]+$/) and return a
clear error instead of accepting unsafe names, then apply the same sanitization
or safe-filename conversion in saveWorkflowOverviewToFile before constructing
CSV/output paths so both functions (getWorkflow and saveWorkflowOverviewToFile)
never join untrusted input into filesystem paths.
---
Nitpick comments:
In `@lib/cli/stats.js`:
- Around line 370-371: The parameter name templatesInWorkflow in function
getYamlSummary is misleading because it actually expects a full workflow object
passed into yamlFilesActivity; rename the parameter to workflow (update the
function signature of getYamlSummary and all internal references) and update any
call sites to pass the same workflow variable name so usage is consistent with
the actual object being passed to yamlFilesActivity.
- Around line 319-344: The code assumes workflow.templates and its
sub-properties exist (e.g., workflow.templates.reconciliations, .exports,
.accounts), which can throw on malformed workflow JSON; update the start of this
block to defensively validate workflow and its template arrays (or normalize
them) before using them: check that workflow is truthy, that workflow.templates
is an object, and that workflow.templates.reconciliations,
workflow.templates.exports, workflow.templates.accounts are arrays (fallback to
[] if missing) or throw a clear, descriptive error; ensure subsequent uses of
reconciliationsInWorkflow, exportFilesInWorkflow, accountTemplatesInWorkflow,
and calls to listExternallyManagedTemplates/countYamlFiles use these
validated/normalized variables so percentageRoundTwo and .length won't fail.
🪄 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: 25e76814-59ef-4417-9c64-b5134a0b6c9a
📒 Files selected for processing (3)
bin/cli.jslib/cli/stats.jslib/utils/fsUtils.js
There was a problem hiding this comment.
🧹 Nitpick comments (1)
lib/cli/utils.js (1)
61-76: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd focused tests for date-validation boundaries.
Cover a valid leap day, malformed input, impossible dates such as
2024-02-31, and theprocess.exit(1)failure path.tests/lib/cli/utils.test.jsalready mocksconsola, making it suitable for these cases.🤖 Prompt for 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. In `@lib/cli/utils.js` around lines 61 - 76, Add focused tests in utils.test.js for checkDateFormat covering a valid leap day, malformed input, an impossible date such as 2024-02-31, and the process.exit(1) failure path. Reuse the existing consola mock and assert both validation outcomes and the expected exit behavior without changing checkDateFormat.
🤖 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.
Nitpick comments:
In `@lib/cli/utils.js`:
- Around line 61-76: Add focused tests in utils.test.js for checkDateFormat
covering a valid leap day, malformed input, an impossible date such as
2024-02-31, and the process.exit(1) failure path. Reuse the existing consola
mock and assert both validation outcomes and the expected exit behavior without
changing checkDateFormat.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 41da8d3a-f73d-4466-a831-193bb82f0a10
📒 Files selected for processing (2)
bin/cli.jslib/cli/utils.js
🚧 Files skipped from review as they are similar to previous changes (1)
- bin/cli.js
1f856a2 to
6bf07a4
Compare
6bf07a4 to
1817f89
Compare
fs.writeFileSync is synchronous: its third parameter is an options object, so the error callback passed to it was coerced and discarded. A failed write threw an unhandled synchronous error at the user instead. saveOverviewToFile had the same bug. Both save functions now share writeStatisticsRow, which wraps the folder creation, the header write and the append in a try/catch, keeps the cause at debug level and reports through the new errorUtils.statisticsNotWritten. The summary is already on screen by then, so the run reports the lost row and ends normally rather than exiting.
Extracting writeStatisticsRow put it between the two functions calling it, which reads worse than either alternative: it separates the pair and shows the helper before the reason for it. The skill said which file a helper belongs in but not where in that file. State the convention the repo already follows - directly above the first caller, above the first of two when shared - with the examples that show it, and note createLiquidFile as the older exception. Add the mistake to the red flags.
countYamlFiles counted test files while the percentages divide by a number of templates, so a template holding two liquid test files was counted twice and the coverage percentage could exceed 100%. That was the open question left in a comment above the expression. The matched files are now grouped per template through a capture group in the template pattern: a template counts once when it holds any non-empty test file, its unit tests are added up across its files, and "at least two tests" is judged on that combined total. An unparsable YAML file is reported at debug level rather than swallowed. The summary fields, the CSV column labels and the on-screen lines say templates rather than yaml files, so the yaml columns of an existing overview.csv are not comparable with the rows written from now on.
A handle can be listed in a workflow file without ever having been imported. Counting it overstated the workflow, and worse, listExternallyManagedTemplates read its config, which made createConfigIfMissing create the template folder and a config.json marked externally_managed. A typo in a workflow file scaffolded a template through a read-only reporting command and inflated the externally managed count with it. reportOnWorkflow now narrows the workflow to the templates the repository holds, reusing fsUtils.getAllTemplatesOfAType, before the counts and the git scan run, so both cover the same population. The templates left out are named in one warning per workflow through errorUtils.workflowTemplatesMissing, and no config is read for a template which is not stored.
Say in the --workflow help and the README that workflow totals cover the templates the workflow file lists which are stored in the repository, excluding shared parts, so they are not comparable with a repository-wide run, and that a template counts once however many liquid test files it holds. Rewrite the unreleased 1.59.0 changelog entry as one bullet per user-visible change, add the missing bullet for the CSV write failure, and move the date to the current one. Update the stats.js and errorUtils.js inventories in ARCHITECTURE.md and catalogue the new tests.
Fixes # (link to the corresponding issue if applicable)
Description
Include a summary of the changes made
Testing Instructions
Steps:
Author Checklist
Reviewer Checklist
Notes
Plan
getWorkflowTemplateSummary(workflowHandle)functionlistWorkflowTemplatesfunction which can take different classes?Testing notes
ymlfiles in the sametestsfolder so may need to update the Regex expression:.*${FOLDER}/${templatePattern}/tests/.*_liquid_test.*.y(a)?ml. Resolved by temporarily deleting "extra" tests in test branchQuick Notes
clifolder?getTemplatesSummary--> Can it be co-opted for the purposes of this workflow? Take the "Reconciliations" section as an example!