Skip to content

Commit 0216664

Browse files
committed
docs: 🔥 update setup.js
1 parent e232266 commit 0216664

File tree

2 files changed

+174
-116
lines changed

2 files changed

+174
-116
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,4 @@
4545
"prettier --write"
4646
]
4747
}
48-
}
48+
}

setup.js

Lines changed: 173 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,17 @@ const path = require('path');
66

77
// Configure readline interface for user input
88
const rl = readline.createInterface({
9-
input: process.stdin,
10-
output: process.stdout
9+
input: process.stdin,
10+
output: process.stdout,
1111
});
1212

1313
// List of files that need to be modified by the script
1414
const filesToModify = [
15-
'project.json',
16-
'CONTRIBUTING.md',
17-
'LICENSE',
18-
'CODE_OF_CONDUCT.md',
19-
'README.md'
15+
'project.json',
16+
'CONTRIBUTING.md',
17+
'LICENSE',
18+
'CODE_OF_CONDUCT.md',
19+
'README.md',
2020
];
2121

2222
/**
@@ -25,137 +25,195 @@ const filesToModify = [
2525
* @returns {Promise<string>} A promise that resolves with the user's answer.
2626
*/
2727
function askQuestion(query) {
28-
return new Promise(resolve => rl.question(query, resolve));
28+
return new Promise((resolve) => rl.question(query, resolve));
2929
}
3030

3131
/**
3232
* Collects all necessary inputs from the user.
3333
* @returns {Promise<Object>} An object containing all user inputs.
3434
*/
3535
async function getUserInputs() {
36-
console.log('\n--- Project Setup ---');
37-
console.log('Let\'s personalize your new repository.');
38-
console.log('Please provide the following information:');
39-
40-
const inputs = {};
41-
42-
inputs.projectName = await askQuestion('1. Enter the name for your new project (e.g., my-awesome-app): ');
43-
inputs.projectDescription = await askQuestion('2. Enter a short description for your project: ');
44-
inputs.projectKeywords = await askQuestion('3. Enter keywords for your project, separated by commas (e.g., javascript, web, utility): ');
45-
inputs.authorName = await askQuestion('4. Enter the author\'s name (e.g., John Doe or My Company Inc.): ');
46-
inputs.contactEmail = await askQuestion('5. Enter a contact email for your project (e.g., contact@yourproject.com): ');
47-
48-
const currentYear = new Date().getFullYear();
49-
inputs.licenseYear = (await askQuestion(`6. Enter the copyright year (default: ${currentYear}): `)) || currentYear.toString(); // Ensure string for replacement
50-
51-
inputs.githubUsername = await askQuestion('7. Enter your GitHub username or organization name (e.g., octocat): ');
52-
inputs.codecovToken = await askQuestion('8. Enter your Codecov token (optional, leave blank if not using): ');
53-
54-
rl.close(); // Close the readline interface after all questions are asked
55-
return inputs;
36+
console.log('\n--- Project Setup ---');
37+
console.log("Let's personalize your new repository.");
38+
console.log('Please provide the following information:');
39+
40+
const inputs = {};
41+
42+
inputs.projectName = await askQuestion(
43+
'1. Enter the name for your new project (e.g., my-awesome-app): '
44+
);
45+
inputs.projectDescription = await askQuestion(
46+
'2. Enter a short description for your project: '
47+
);
48+
inputs.projectKeywords = await askQuestion(
49+
'3. Enter keywords for your project, separated by commas (e.g., javascript, web, utility): '
50+
);
51+
inputs.authorName = await askQuestion(
52+
"4. Enter the author's name (e.g., John Doe or My Company Inc.): "
53+
);
54+
inputs.contactEmail = await askQuestion(
55+
'5. Enter a contact email for your project (e.g., contact@yourproject.com): '
56+
);
57+
58+
const currentYear = new Date().getFullYear();
59+
inputs.licenseYear =
60+
(await askQuestion(
61+
`6. Enter the copyright year (default: ${currentYear}): `
62+
)) || currentYear.toString(); // Ensure string for replacement
63+
64+
inputs.githubUsername = await askQuestion(
65+
'7. Enter your GitHub username or organization name (e.g., octocat): '
66+
);
67+
inputs.codecovToken = await askQuestion(
68+
'8. Enter your Codecov token (optional, leave blank if not using): '
69+
);
70+
71+
rl.close(); // Close the readline interface after all questions are asked
72+
return inputs;
5673
}
5774

5875
/**
5976
* Processes each file, replacing placeholders with user inputs.
6077
* @param {Object} inputs An object containing all user inputs.
6178
*/
6279
async function processFiles(inputs) {
63-
for (const file of filesToModify) {
64-
const filePath = path.join(process.cwd(), file); // Assumes script is run from repo root
65-
console.log(`\nProcessing ${file}...`);
66-
67-
try {
68-
let content = fs.readFileSync(filePath, 'utf8');
69-
70-
// --- Generic Replacements (order matters if placeholders overlap) ---
71-
content = content.replace(new RegExp('{{PROJECT_NAME}}', 'g'), inputs.projectName);
72-
content = content.replace(new RegExp('{{PROJECT_DESCRIPTION}}', 'g'), inputs.projectDescription);
73-
content = content.replace(new RegExp('{{AUTHOR_NAME}}', 'g'), inputs.authorName);
74-
content = content.replace(new RegExp('{{CONTACT_EMAIL}}', 'g'), inputs.contactEmail);
75-
content = content.replace(new RegExp('{{LICENSE_YEAR}}', 'g'), inputs.licenseYear);
76-
content = content.replace(new RegExp('{{GITHUB_USERNAME}}', 'g'), inputs.githubUsername);
77-
// Handle optional Codecov token
78-
content = content.replace(new RegExp('{{CODECOV_TOKEN}}', 'g'), inputs.codecovToken || '');
79-
80-
81-
// --- Specific handling for project.json ---
82-
if (file === 'project.json') {
83-
let projectJson = JSON.parse(content);
84-
85-
// Update specific fields that might have been generically replaced but need JSON structure
86-
projectJson.name = inputs.projectName;
87-
projectJson.description = inputs.projectDescription;
88-
projectJson.author = inputs.authorName;
89-
90-
// Handle keywords array: convert comma-separated string to array
91-
if (inputs.projectKeywords) {
92-
projectJson.keywords = inputs.projectKeywords.split(',').map(kw => kw.trim()).filter(kw => kw.length > 0);
93-
} else {
94-
projectJson.keywords = []; // Set to empty array if no keywords provided
95-
}
96-
97-
content = JSON.stringify(projectJson, null, 2); // Pretty print JSON with 2 spaces
98-
}
99-
100-
// --- Specific handling for README.md ---
101-
if (file === 'README.md') {
102-
// Correct the LICENSE link from LICENSE.md to LICENSE
103-
content = content.replace(/\[LICENSE\]\(LICENSE\.md\)/g, '[LICENSE](LICENSE)');
104-
105-
// Update the 'Post-Template Setup' section
106-
// This regex captures the section content up to the next '##' heading or end of file
107-
const postTemplateSetupRegex = /(## Post-Template Setup[\s\S]*?)(?=##|$)/;
108-
const newPostTemplateSetupContent = `## Post-Template Setup\n\nAfter creating your repository from this template, you've successfully run this setup script to personalize your project. You're ready to start building!\n\n*(This section was updated by the setup script.)*`;
109-
110-
if (content.match(postTemplateSetupRegex)) {
111-
content = content.replace(postTemplateSetupRegex, newPostTemplateSetupContent);
112-
} else {
113-
// If the section isn't found (e.g., file was heavily modified), append it
114-
console.warn('Warning: "Post-Template Setup" section not found in README.md. Appending new content.');
115-
content += `\n${newPostTemplateSetupContent}`;
116-
}
117-
}
118-
119-
fs.writeFileSync(filePath, content, 'utf8');
120-
console.log(`Successfully updated ${file}.`);
121-
122-
} catch (error) {
123-
console.error(`Error processing ${file}: ${error.message}`);
124-
if (file === 'project.json' && error instanceof SyntaxError) {
125-
console.error('Make sure project.json is valid JSON before running the script.');
126-
}
80+
for (const file of filesToModify) {
81+
const filePath = path.join(process.cwd(), file); // Assumes script is run from repo root
82+
console.log(`\nProcessing ${file}...`);
83+
84+
try {
85+
let content = fs.readFileSync(filePath, 'utf8');
86+
87+
// --- Generic Replacements (order matters if placeholders overlap) ---
88+
content = content.replace(
89+
new RegExp('{{PROJECT_NAME}}', 'g'),
90+
inputs.projectName
91+
);
92+
content = content.replace(
93+
new RegExp('{{PROJECT_DESCRIPTION}}', 'g'),
94+
inputs.projectDescription
95+
);
96+
content = content.replace(
97+
new RegExp('{{AUTHOR_NAME}}', 'g'),
98+
inputs.authorName
99+
);
100+
content = content.replace(
101+
new RegExp('{{CONTACT_EMAIL}}', 'g'),
102+
inputs.contactEmail
103+
);
104+
content = content.replace(
105+
new RegExp('{{LICENSE_YEAR}}', 'g'),
106+
inputs.licenseYear
107+
);
108+
content = content.replace(
109+
new RegExp('{{GITHUB_USERNAME}}', 'g'),
110+
inputs.githubUsername
111+
);
112+
// Handle optional Codecov token
113+
content = content.replace(
114+
new RegExp('{{CODECOV_TOKEN}}', 'g'),
115+
inputs.codecovToken || ''
116+
);
117+
118+
// --- Specific handling for project.json ---
119+
if (file === 'project.json') {
120+
let projectJson = JSON.parse(content);
121+
122+
// Update specific fields that might have been generically replaced but need JSON structure
123+
projectJson.name = inputs.projectName;
124+
projectJson.description = inputs.projectDescription;
125+
projectJson.author = inputs.authorName;
126+
127+
// Handle keywords array: convert comma-separated string to array
128+
if (inputs.projectKeywords) {
129+
projectJson.keywords = inputs.projectKeywords
130+
.split(',')
131+
.map((kw) => kw.trim())
132+
.filter((kw) => kw.length > 0);
133+
} else {
134+
projectJson.keywords = []; // Set to empty array if no keywords provided
135+
}
136+
137+
content = JSON.stringify(projectJson, null, 2); // Pretty print JSON with 2 spaces
138+
}
139+
140+
// --- Specific handling for README.md ---
141+
if (file === 'README.md') {
142+
// Correct the LICENSE link from LICENSE.md to LICENSE
143+
content = content.replace(
144+
/\[LICENSE\]\(LICENSE\.md\)/g,
145+
'[LICENSE](LICENSE)'
146+
);
147+
148+
// Update the 'Post-Template Setup' section
149+
// This regex captures the section content up to the next '##' heading or end of file
150+
const postTemplateSetupRegex =
151+
/(## Post-Template Setup[\s\S]*?)(?=##|$)/;
152+
const newPostTemplateSetupContent = `## Post-Template Setup\n\nAfter creating your repository from this template, you've successfully run this setup script to personalize your project. You're ready to start building!\n\n*(This section was updated by the setup script.)*`;
153+
154+
if (content.match(postTemplateSetupRegex)) {
155+
content = content.replace(
156+
postTemplateSetupRegex,
157+
newPostTemplateSetupContent
158+
);
159+
} else {
160+
// If the section isn't found (e.g., file was heavily modified), append it
161+
console.warn(
162+
'Warning: "Post-Template Setup" section not found in README.md. Appending new content.'
163+
);
164+
content += `\n${newPostTemplateSetupContent}`;
127165
}
166+
}
167+
168+
fs.writeFileSync(filePath, content, 'utf8');
169+
console.log(`Successfully updated ${file}.`);
170+
} catch (error) {
171+
console.error(`Error processing ${file}: ${error.message}`);
172+
if (file === 'project.json' && error instanceof SyntaxError) {
173+
console.error(
174+
'Make sure project.json is valid JSON before running the script.'
175+
);
176+
}
128177
}
178+
}
129179
}
130180

131181
/**
132182
* Main function to run the setup script.
133183
*/
134184
async function runSetup() {
135-
try {
136-
const inputs = await getUserInputs();
137-
await processFiles(inputs);
138-
139-
console.log('\n--- Setup Complete! ---');
140-
console.log('Your repository has been successfully personalized.');
141-
console.log('Here are some quick reminders:');
142-
console.log(`- Project Name: ${inputs.projectName}`);
143-
console.log(`- Author: ${inputs.authorName}`);
144-
console.log(`- GitHub Repository: https://github.com/${inputs.githubUsername}/${inputs.projectName}`);
145-
if (inputs.codecovToken) {
146-
console.log(`- Remember to add your Codecov token as a secret named 'CODECOV_TOKEN' in your GitHub repository settings for CI integration.`);
147-
}
148-
console.log('\n- Please review the modified files to ensure everything looks correct and fine-tune as needed.');
149-
console.log('- Don\'t forget to initialize your Git repository if you haven\'t already!');
150-
console.log('\nHappy coding!');
151-
} catch (error) {
152-
console.error('\nAn unexpected error occurred during setup:', error);
153-
process.exit(1); // Exit with an error code
154-
} finally {
155-
if (!rl.closed) {
156-
rl.close(); // Ensure readline interface is closed even on error
157-
}
185+
try {
186+
const inputs = await getUserInputs();
187+
await processFiles(inputs);
188+
189+
console.log('\n--- Setup Complete! ---');
190+
console.log('Your repository has been successfully personalized.');
191+
console.log('Here are some quick reminders:');
192+
console.log(`- Project Name: ${inputs.projectName}`);
193+
console.log(`- Author: ${inputs.authorName}`);
194+
console.log(
195+
`- GitHub Repository: https://github.com/${inputs.githubUsername}/${inputs.projectName}`
196+
);
197+
if (inputs.codecovToken) {
198+
console.log(
199+
`- Remember to add your Codecov token as a secret named 'CODECOV_TOKEN' in your GitHub repository settings for CI integration.`
200+
);
201+
}
202+
console.log(
203+
'\n- Please review the modified files to ensure everything looks correct and fine-tune as needed.'
204+
);
205+
console.log(
206+
"- Don't forget to initialize your Git repository if you haven't already!"
207+
);
208+
console.log('\nHappy coding!');
209+
} catch (error) {
210+
console.error('\nAn unexpected error occurred during setup:', error);
211+
process.exit(1); // Exit with an error code
212+
} finally {
213+
if (!rl.closed) {
214+
rl.close(); // Ensure readline interface is closed even on error
158215
}
216+
}
159217
}
160218

161219
// Execute the setup script

0 commit comments

Comments
 (0)