feat: add automated template initialization script#103
feat: add automated template initialization script#103madhavansingh wants to merge 1 commit intoAOSSIE-Org:mainfrom
Conversation
WalkthroughA new Node.js script setup.js is introduced to automate template initialization. It interactively prompts for project name, description, and tech stack; validates inputs; replaces TODO placeholders in template files; creates backups; supports dry-run mode; and verifies successful completion with exit codes. Changes
Sequence Diagram(s)sequenceDiagram
actor User
participant setup.js as Setup Script
participant FileSystem as File System
participant TemplateFiles as Template Files<br/>(README.md, CONTRIBUTING.md)
User->>setup.js: Run node setup.js
setup.js->>User: Prompt for project name
User->>setup.js: Provide project name
setup.js->>User: Prompt for project description
User->>setup.js: Provide description
setup.js->>User: Prompt for tech stack
User->>setup.js: Select tech stack
setup.js->>User: Display summary & request confirmation
User->>setup.js: Confirm changes
setup.js->>FileSystem: Read README.md
FileSystem-->>setup.js: File content
alt Placeholders found
setup.js->>FileSystem: Create .bak backup
FileSystem-->>setup.js: Backup created
setup.js->>setup.js: Replace placeholders with values
setup.js->>FileSystem: Write updated content
FileSystem-->>setup.js: Write complete
end
setup.js->>FileSystem: Read CONTRIBUTING.md
FileSystem-->>setup.js: File content
alt Placeholders found
setup.js->>FileSystem: Create .bak backup
FileSystem-->>setup.js: Backup created
setup.js->>setup.js: Replace placeholders with values
setup.js->>FileSystem: Write updated content
FileSystem-->>setup.js: Write complete
end
setup.js->>TemplateFiles: Scan for remaining placeholders
TemplateFiles-->>setup.js: Validation results
alt No placeholders remain
setup.js->>User: Print success & setup guidance
else Placeholders still present
setup.js->>User: Print warnings
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Suggested labels
Poem
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
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 |
|
I have implemented the automated template initialization script as discussed in Issue #102. Summary:
I have tested the script locally and ensured it works as expected. Would appreciate your feedback and suggestions. Thanks! |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@setup.js`:
- Around line 15-20: Replace the current log.error implementation so errors are
written to stderr instead of stdout: update the log object (symbol: log) and
specifically the error method (log.error) to call console.error with the same
formatted message rather than console.log; keep the ANSI coloring and message
format unchanged so other methods (info, success, warning) remain intact.
- Line 195: The call to main() should chain a .catch() to handle any unhandled
promise rejections—update the invocation of main() so that it appends .catch(err
=> { processLogger.error("Unhandled error in main", err); process.exit(1); })
(or use console.error if processLogger is not available) to log the error and
exit with a non-zero code; reference the existing main() invocation to apply
this defensive handler.
- Around line 61-66: The replacePlaceholders function is vulnerable because
String.replace treats $-patterns in the replacement string; change both .replace
calls to use a replacement function (e.g., .replace(/TODO:\s*Project\s*Name/gi,
() => data.projectName) and .replace(/TODO:\s*Project\s*Description/gi, () =>
data.projectDescription)) so user-provided projectName/projectDescription are
inserted literally and special $ sequences are not interpreted.
- Around line 137-142: The techStack value collected by promptUser is passed
into processFile but never used by replacePlaceholders, so update
replacePlaceholders to accept and apply tech-stack-specific replacements (e.g.,
replace tokens like {{techStack}} or {{isNode}}/{{isPython}}) or remove passing
techStack from processFile and the prompt; specifically, modify
replacePlaceholders(signature and implementation) to take a third parameter
techStack and perform substitution logic for {{techStack}} (and any conditional
tokens used for guidance), then ensure processFile calls
replacePlaceholders(projectName, projectDescription, techStack) and that any
template placeholders referenced in the repo match these token names.
🪄 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: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 446b78cb-56a3-409e-8eb5-663044227cc4
📒 Files selected for processing (1)
setup.js
| const log = { | ||
| info: (msg) => console.log(`\x1b[36m[INFO]\x1b[0m ${msg}`), | ||
| success: (msg) => console.log(`\x1b[32m[SUCCESS]\x1b[0m ${msg}`), | ||
| warning: (msg) => console.log(`\x1b[33m[WARNING]\x1b[0m ${msg}`), | ||
| error: (msg) => console.log(`\x1b[31m[ERROR]\x1b[0m ${msg}`) | ||
| }; |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Use console.error for error logging.
Error messages should be written to stderr, not stdout. This follows Node.js conventions and allows proper stream separation when piping output.
♻️ Suggested fix
const log = {
info: (msg) => console.log(`\x1b[36m[INFO]\x1b[0m ${msg}`),
success: (msg) => console.log(`\x1b[32m[SUCCESS]\x1b[0m ${msg}`),
- warning: (msg) => console.log(`\x1b[33m[WARNING]\x1b[0m ${msg}`),
- error: (msg) => console.log(`\x1b[31m[ERROR]\x1b[0m ${msg}`)
+ warning: (msg) => console.warn(`\x1b[33m[WARNING]\x1b[0m ${msg}`),
+ error: (msg) => console.error(`\x1b[31m[ERROR]\x1b[0m ${msg}`)
};📝 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.
| const log = { | |
| info: (msg) => console.log(`\x1b[36m[INFO]\x1b[0m ${msg}`), | |
| success: (msg) => console.log(`\x1b[32m[SUCCESS]\x1b[0m ${msg}`), | |
| warning: (msg) => console.log(`\x1b[33m[WARNING]\x1b[0m ${msg}`), | |
| error: (msg) => console.log(`\x1b[31m[ERROR]\x1b[0m ${msg}`) | |
| }; | |
| const log = { | |
| info: (msg) => console.log(`\x1b[36m[INFO]\x1b[0m ${msg}`), | |
| success: (msg) => console.log(`\x1b[32m[SUCCESS]\x1b[0m ${msg}`), | |
| warning: (msg) => console.warn(`\x1b[33m[WARNING]\x1b[0m ${msg}`), | |
| error: (msg) => console.error(`\x1b[31m[ERROR]\x1b[0m ${msg}`) | |
| }; |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@setup.js` around lines 15 - 20, Replace the current log.error implementation
so errors are written to stderr instead of stdout: update the log object
(symbol: log) and specifically the error method (log.error) to call
console.error with the same formatted message rather than console.log; keep the
ANSI coloring and message format unchanged so other methods (info, success,
warning) remain intact.
| const replacePlaceholders = (content, data) => { | ||
| let newContent = content; | ||
| newContent = newContent.replace(/TODO:\s*Project\s*Name/gi, data.projectName); | ||
| newContent = newContent.replace(/TODO:\s*Project\s*Description/gi, data.projectDescription); | ||
| return newContent; | ||
| }; |
There was a problem hiding this comment.
User input may contain special replacement patterns causing unexpected output.
In JavaScript's String.replace(), the replacement string interprets special patterns like $& (matched substring), $' (portion after match), $` (portion before match), and $$ (literal $). If a user enters a project name or description containing these patterns, the replacement will produce incorrect results.
Example: If user enters "My $& Project" as the name, the output would be "My TODO: Project Name Project".
🐛 Proposed fix using replacement function
const replacePlaceholders = (content, data) => {
let newContent = content;
- newContent = newContent.replace(/TODO:\s*Project\s*Name/gi, data.projectName);
- newContent = newContent.replace(/TODO:\s*Project\s*Description/gi, data.projectDescription);
+ newContent = newContent.replace(/TODO:\s*Project\s*Name/gi, () => data.projectName);
+ newContent = newContent.replace(/TODO:\s*Project\s*Description/gi, () => data.projectDescription);
return newContent;
};🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@setup.js` around lines 61 - 66, The replacePlaceholders function is
vulnerable because String.replace treats $-patterns in the replacement string;
change both .replace calls to use a replacement function (e.g.,
.replace(/TODO:\s*Project\s*Name/gi, () => data.projectName) and
.replace(/TODO:\s*Project\s*Description/gi, () => data.projectDescription)) so
user-provided projectName/projectDescription are inserted literally and special
$ sequences are not interpreted.
| let techStack; | ||
| while (true) { | ||
| techStack = (await promptUser('Enter tech stack (node/python)')).toLowerCase(); | ||
| if (techStack === 'node' || techStack === 'python') break; | ||
| log.error('Invalid choice. Please enter either "node" or "python".'); | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check if template files contain any tech stack related placeholders
rg -i "TODO.*tech|TODO.*stack" README.md CONTRIBUTING.md 2>/dev/null || echo "No tech stack placeholders found"Repository: AOSSIE-Org/Template-Repo
Length of output: 100
🏁 Script executed:
# Find all template files and search for placeholders more broadly
find . -type f \( -name "*.template" -o -name "*.tmpl" -o -name "*.hbs" \) | head -20Repository: AOSSIE-Org/Template-Repo
Length of output: 50
🏁 Script executed:
# Search for placeholder patterns across the entire codebase
rg -E "{{|TODO|FIXME|\$\{" --type-list | head -5 && rg -E "{{|TODO|FIXME" . --max-count=20 2>/dev/null | head -30Repository: AOSSIE-Org/Template-Repo
Length of output: 177
🏁 Script executed:
# Read setup.js around the techStack usage lines to understand its purpose
cat -n setup.js | sed -n '130,180p'Repository: AOSSIE-Org/Template-Repo
Length of output: 2409
🏁 Script executed:
# Find and read the processFile function
rg -n "function processFile|const processFile|processFile\s*=" setup.js -A 30Repository: AOSSIE-Org/Template-Repo
Length of output: 1132
🏁 Script executed:
# Also search for any placeholder patterns in actual template files or content files
find . -type f \( -name "*.md" -o -name "*.json" -o -name "*.txt" \) -exec grep -l "projectName\|projectDescription\|techStack" {} \; 2>/dev/null | head -20Repository: AOSSIE-Org/Template-Repo
Length of output: 50
🏁 Script executed:
# Find and read the replacePlaceholders function
rg -n "function replacePlaceholders|const replacePlaceholders|replacePlaceholders\s*=" setup.js -A 30Repository: AOSSIE-Org/Template-Repo
Length of output: 1241
🏁 Script executed:
# Check FILES_TO_PROCESS to see which files are actually being modified
rg -n "FILES_TO_PROCESS" setup.js -B 5 -A 5Repository: AOSSIE-Org/Template-Repo
Length of output: 1711
Tech stack input is collected but not used in placeholder replacement.
The techStack value is passed to processFile() but the replacePlaceholders() function only processes projectName and projectDescription placeholders. It ignores the techStack parameter entirely, using the value only for conditional guidance messages (lines 170-174). Either remove the unnecessary techStack collection, or extend replacePlaceholders() to support tech-stack-specific placeholders if that's intended.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@setup.js` around lines 137 - 142, The techStack value collected by promptUser
is passed into processFile but never used by replacePlaceholders, so update
replacePlaceholders to accept and apply tech-stack-specific replacements (e.g.,
replace tokens like {{techStack}} or {{isNode}}/{{isPython}}) or remove passing
techStack from processFile and the prompt; specifically, modify
replacePlaceholders(signature and implementation) to take a third parameter
techStack and perform substitution logic for {{techStack}} (and any conditional
tokens used for guidance), then ensure processFile calls
replacePlaceholders(projectName, projectDescription, techStack) and that any
template placeholders referenced in the repo match these token names.
Addressed Issues:
Fixes #102
Description
This PR introduces an automated template initialization script (
setup.js) to improve the usability of the repository and eliminate manual placeholder replacement.Key Features
TODO: Project NameandTODO: Project Descriptionacross filesREADME.mdandCONTRIBUTING.mdnode setup.js --dry-run.bakfiles before modifying original files[INFO],[SUCCESS],[WARNING],[ERROR]logsUsage
Run:
node setup.js
Dry run:
node setup.js --dry-run
Additional Notes:
fs,readline,path)This contribution is part of my preparation for GSoC 2026.
Checklist
Summary by CodeRabbit