Skip to content

Commit 38c9ebb

Browse files
committed
Add support for script parameters via command-line args
Signed-off-by: Ryan Wang <[email protected]>
1 parent a8eac7f commit 38c9ebb

File tree

1 file changed

+205
-71
lines changed

1 file changed

+205
-71
lines changed

src/index.js

Lines changed: 205 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,73 @@ import {
1515
} from "./utils.js";
1616

1717
// Parse command line arguments
18-
const argv = minimist(process.argv.slice(2));
18+
const argv = minimist(process.argv.slice(2), {
19+
string: ['name', 'domain', 'author', 'uiTool'],
20+
boolean: ['help', 'version'],
21+
alias: {
22+
h: 'help',
23+
v: 'version',
24+
n: 'name',
25+
d: 'domain',
26+
a: 'author',
27+
u: 'uiTool'
28+
}
29+
});
30+
1931
const targetDir = argv._[0];
2032

33+
/**
34+
* Show help information
35+
*/
36+
function showHelp() {
37+
console.log(`
38+
🚀 Halo Plugin Creator
39+
40+
Usage:
41+
pnpm create halo-plugin [directory] [options]
42+
43+
Options:
44+
-n, --name <name> Plugin name (e.g., my-awesome-plugin)
45+
-d, --domain <domain> Domain for group and package name (e.g., com.example)
46+
-a, --author <author> Author name
47+
-u, --uiTool <tool> UI build tool (rsbuild or vite)
48+
-h, --help Show this help message
49+
-v, --version Show version number
50+
51+
Examples:
52+
pnpm create halo-plugin demo --name=demo --domain=com.example --author=ryanwang --uiTool=rsbuild
53+
pnpm create halo-plugin --name my-plugin --domain com.example --author "John Doe" --uiTool vite
54+
pnpm create halo-plugin
55+
`);
56+
}
57+
58+
/**
59+
* Show version information
60+
*/
61+
function showVersion() {
62+
// Read version from package.json
63+
const packagePath = path.join(path.dirname(new URL(import.meta.url).pathname), '..', 'package.json');
64+
try {
65+
const packageJson = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
66+
console.log(packageJson.version || '1.0.0');
67+
} catch {
68+
console.log('1.0.0');
69+
}
70+
}
71+
72+
/**
73+
* Validate UI tool parameter
74+
* @param {string} uiTool - UI tool name
75+
* @returns {boolean|string} True if valid, error message if invalid
76+
*/
77+
function validateUITool(uiTool) {
78+
const validTools = ['rsbuild', 'vite'];
79+
if (!validTools.includes(uiTool)) {
80+
return `UI tool must be one of: ${validTools.join(', ')}`;
81+
}
82+
return true;
83+
}
84+
2185
/**
2286
* Check if directory is empty
2387
* @param {string} dir - Directory path
@@ -78,62 +142,127 @@ function getProjectPath(targetDir, projectName) {
78142
}
79143

80144
async function main() {
145+
// Handle help and version flags
146+
if (argv.help) {
147+
showHelp();
148+
process.exit(0);
149+
}
150+
151+
if (argv.version) {
152+
showVersion();
153+
process.exit(0);
154+
}
155+
81156
console.log("🚀 Welcome to Halo Plugin Creator!\n");
82157

83158
try {
84159
// Validate target directory early (if user specified one)
85160
validateTargetDir(targetDir);
86161

87-
// Get user input
88-
const answers = await prompts([
89-
{
90-
type: "text",
91-
name: "name",
92-
message: "Plugin name:",
93-
hint: "e.g., my-awesome-plugin",
94-
validate: validateProjectName,
95-
},
96-
{
97-
type: "text",
98-
name: "domain",
99-
message: "Domain (for group and package name):",
100-
hint: "e.g., com.example",
101-
validate: validateDomain,
102-
},
103-
{
104-
type: "text",
105-
name: "author",
106-
message: "Author name:",
107-
initial: getCurrentUser(),
108-
},
109-
{
110-
type: "select",
111-
name: "uiTool",
112-
message: "Choose UI build tool:",
113-
choices: [
114-
{
115-
title: "Rsbuild",
116-
value: "rsbuild",
117-
description: "The Rspack Powered Build Tool(Recommended)",
118-
},
119-
{
120-
title: "Vite",
121-
value: "vite",
122-
description: "The Build Tool for the Web",
123-
},
124-
],
125-
},
126-
]);
127-
128-
// If user cancelled input
129-
if (
130-
!answers.name ||
131-
!answers.domain ||
132-
!answers.author ||
133-
!answers.uiTool
134-
) {
135-
console.log("❌ Operation cancelled");
136-
process.exit(0);
162+
// Check if all required parameters are provided via command line
163+
const hasAllParams = argv.name && argv.domain && argv.author && argv.uiTool;
164+
165+
let answers = {};
166+
167+
if (hasAllParams) {
168+
// Validate command line arguments
169+
const nameValidation = validateProjectName(argv.name);
170+
if (nameValidation !== true) {
171+
throw new Error(`Invalid plugin name: ${nameValidation}`);
172+
}
173+
174+
const domainValidation = validateDomain(argv.domain);
175+
if (domainValidation !== true) {
176+
throw new Error(`Invalid domain: ${domainValidation}`);
177+
}
178+
179+
const uiToolValidation = validateUITool(argv.uiTool);
180+
if (uiToolValidation !== true) {
181+
throw new Error(`Invalid UI tool: ${uiToolValidation}`);
182+
}
183+
184+
// Use command line arguments
185+
answers = {
186+
name: argv.name,
187+
domain: argv.domain,
188+
author: argv.author,
189+
uiTool: argv.uiTool
190+
};
191+
192+
console.log("📋 Using command line arguments:");
193+
console.log(` Name: ${answers.name}`);
194+
console.log(` Domain: ${answers.domain}`);
195+
console.log(` Author: ${answers.author}`);
196+
console.log(` UI Tool: ${answers.uiTool}`);
197+
} else {
198+
// Interactive mode - prompt for missing parameters
199+
const promptQuestions = [];
200+
201+
if (!argv.name) {
202+
promptQuestions.push({
203+
type: "text",
204+
name: "name",
205+
message: "Plugin name:",
206+
hint: "e.g., my-awesome-plugin",
207+
validate: validateProjectName,
208+
});
209+
}
210+
211+
if (!argv.domain) {
212+
promptQuestions.push({
213+
type: "text",
214+
name: "domain",
215+
message: "Domain (for group and package name):",
216+
hint: "e.g., com.example",
217+
validate: validateDomain,
218+
});
219+
}
220+
221+
if (!argv.author) {
222+
promptQuestions.push({
223+
type: "text",
224+
name: "author",
225+
message: "Author name:",
226+
initial: getCurrentUser(),
227+
});
228+
}
229+
230+
if (!argv.uiTool) {
231+
promptQuestions.push({
232+
type: "select",
233+
name: "uiTool",
234+
message: "Choose UI build tool:",
235+
choices: [
236+
{
237+
title: "Rsbuild",
238+
value: "rsbuild",
239+
description: "The Rspack Powered Build Tool(Recommended)",
240+
},
241+
{
242+
title: "Vite",
243+
value: "vite",
244+
description: "The Build Tool for the Web",
245+
},
246+
],
247+
});
248+
}
249+
250+
// Get missing parameters through prompts
251+
const promptAnswers = await prompts(promptQuestions);
252+
253+
// If user cancelled input
254+
if (promptQuestions.some(q => promptAnswers[q.name] === undefined)) {
255+
console.log("❌ Operation cancelled");
256+
process.exit(0);
257+
}
258+
259+
// Merge command line args with prompt answers
260+
answers = {
261+
name: argv.name || promptAnswers.name,
262+
domain: argv.domain || promptAnswers.domain,
263+
author: argv.author || promptAnswers.author,
264+
uiTool: argv.uiTool || promptAnswers.uiTool,
265+
};
137266
}
138267

139268
// Process and format input
@@ -144,7 +273,7 @@ async function main() {
144273

145274
// Get project path (will check auto-generated directory if needed)
146275
const projectPath = getProjectPath(targetDir, projectName);
147-
const projectDirName = path.basename(projectPath);
276+
const projectDirName = path.relative(process.cwd(), projectPath);
148277

149278
// Generate project configuration
150279
const variables = {
@@ -156,25 +285,30 @@ async function main() {
156285
uiTool: answers.uiTool,
157286
};
158287

159-
console.log("\n📋 Project Configuration:");
160-
console.log(` Name: ${projectName}`);
161-
console.log(` Domain: ${group}`);
162-
console.log(` Package: ${packageName}`);
163-
console.log(` Author: ${answers.author}`);
164-
console.log(` UI Tool: ${answers.uiTool}`);
165-
console.log(` Output Directory: ${projectPath}`);
166-
167-
// Confirm creation
168-
const { confirm } = await prompts({
169-
type: "confirm",
170-
name: "confirm",
171-
message: "Create project?",
172-
initial: true,
173-
});
174-
175-
if (!confirm) {
176-
console.log("❌ Operation cancelled");
177-
process.exit(0);
288+
if (!hasAllParams) {
289+
console.log("\n📋 Project Configuration:");
290+
console.log(` Name: ${projectName}`);
291+
console.log(` Domain: ${group}`);
292+
console.log(` Package: ${packageName}`);
293+
console.log(` Author: ${answers.author}`);
294+
console.log(` UI Tool: ${answers.uiTool}`);
295+
console.log(` Output Directory: ${projectPath}`);
296+
297+
// Confirm creation (only in interactive mode)
298+
const { confirm } = await prompts({
299+
type: "confirm",
300+
name: "confirm",
301+
message: "Create project?",
302+
initial: true,
303+
});
304+
305+
if (!confirm) {
306+
console.log("❌ Operation cancelled");
307+
process.exit(0);
308+
}
309+
} else {
310+
console.log(` Output Directory: ${projectPath}\n`);
311+
console.log("🔨 Creating project...");
178312
}
179313

180314
// Generate project

0 commit comments

Comments
 (0)