diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..d7520d2 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,7 @@ +{ + "bracketSpacing": true, + "printWidth": 100, + "semi": false, + "singleQuote": true, + "trailingComma": "all" +} diff --git a/index.js b/index.js index 5e8d672..ec4094e 100644 --- a/index.js +++ b/index.js @@ -3,19 +3,73 @@ import { execSync } from "child_process"; import { join } from "path"; import { rmSync } from "fs"; +import readline from "readline"; import chalk from "chalk"; +import os from "os"; + +const commandSilencer = os.platform() === "win32" ? '> nul 2>&1' : '> /dev/null 2>&1' + +const repoUrls = { + barebones: "https://github.com/BootNodeDev/dAppBooster.git", + example: "https://github.com/BootNodeDev/dAppBoosterLandingPage.git", +}; -const repoUrl = "https://github.com/bootnodedev/dappbooster.git"; const projectName = process.argv[2]; +// Check if the project name is valid if (!projectName || !/^[a-zA-Z0-9-_]+$/.test(projectName)) { - console.error("Invalid directory name. Please enter a valid project name."); + console.error(`${chalk.red.bold("Invalid directory name. Please enter a valid project name.")}`); process.exit(1); } -cloneRepo(projectName); +// Prompt the user to select the repository type +promptUserForRepoType() + .then((repoType) => { + const repoUrl = repoUrls[repoType]; + cloneRepo(projectName, repoUrl); + }) + .catch((error) => { + console.error(chalk.red.bold("Error:"), error.message); + process.exit(1); + }); + +/** + * @description Prompt the user to select the repository type + * @returns {Promise} The selected repository type + */ +function promptUserForRepoType() { + return new Promise((resolve, reject) => { + const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, + }); + + rl.question( + `You can choose to start with a ${chalk.green.bold('Barebones')} project or a project with ${chalk.green.bold('Examples')} and demo code (B/e):`, + (answer) => { + rl.close(); + const selection = answer.trim().toUpperCase(); + if (selection === "B" || selection === "") { + resolve("barebones"); + } else if (selection === "E") { + resolve("example"); + } else { + reject(new Error("Invalid selection. Please choose B or E.")); + } + } + ); + }); +} + +/** + * @description Get the latest tag in the repository + * @param {Object} execOptions The options to pass to the exec + * @returns {string} The latest tag in the repository + */ +function getLatestTag(execOptions) { + // Fetch all tags + execSync(`git fetch --tags ${commandSilencer}`, execOptions); -function getLatestTag() { // Get all tags, sorted by version const tags = execSync("git tag -l --sort=-v:refname") .toString() @@ -26,7 +80,13 @@ function getLatestTag() { return tags[0]; } -function cloneRepo(projectName) { +/** + * @description Clone the specified repository + * @param {string} projectName The name of the project + * @param {string} repoUrl The URL of the repository + * @returns {void} + */ +function cloneRepo(projectName, repoUrl) { const sanitizedProjectName = projectName.replace(/[^a-zA-Z0-9-_]/g, "-"); const projectDir = join(process.cwd(), sanitizedProjectName); const execOptions = { @@ -35,7 +95,7 @@ function cloneRepo(projectName) { }; try { - console.log(`Cloning dAppBooster...`); + console.log(`\nCloning dAppBooster...`); // Clone the repository execSync( @@ -46,43 +106,50 @@ function cloneRepo(projectName) { // Change to the project directory process.chdir(projectDir); - // Fetch all tags - execSync("git fetch --tags", execOptions); - // Get the latest tag const latestTag = getLatestTag(); - if (!latestTag) { - throw new Error("No tags found in the repository"); + if (latestTag) { + console.log(`Checking out latest tag: ${latestTag}`); + execSync(`git checkout "${latestTag}"`, execOptions); + } else { + console.log(`No tags found, checking out ${chalk.bold('main')} branch...`); + execSync("git checkout main", execOptions); } - // Checkout the latest tag - execSync(`git checkout "${latestTag}"`, execOptions); - // Remove the .git directory rmSync(join(projectDir, ".git"), { recursive: true, force: true }); // Initialize a new git repository execSync("git init", execOptions); - console.log(`dAppBooster repository cloned in ${chalk.bold(projectDir)}`); - console.log(`Latest version: ${chalk.bold(latestTag)}`); + // Success + console.log(`\ndAppBooster repository cloned in ${chalk.bold(projectDir)}`); + if (latestTag) { + console.log(`Latest version: ${chalk.bold(latestTag)}`); + } + + console.log(`\n---\n`); + // Some extra instructions for the user console.log(` -${chalk.green.bold( - "You can now start your project with the following commands:" -)} +${chalk.blue.bold("You can now start your project with the following commands:")} -${chalk.blue("# Change to the project directory")} +${chalk.gray.italic("# Change to the project directory")} $ ${chalk.cyan(`cd ${sanitizedProjectName}`)} -${chalk.blue("# Install dependencies")} +${chalk.gray.italic("# Install dependencies")} $ ${chalk.cyan("pnpm install")} -${chalk.blue("# Copy the example environment file")} +${chalk.gray.italic("# Copy the example environment file")} $ ${chalk.cyan("cp .env.example .env.local")} -${chalk.blue("# Start the development server")} +${chalk.gray.italic("# Start the development server")} $ ${chalk.cyan("pnpm dev")} + +--- + +Remember to also check out the docs in ${chalk.green.bold("https://docs.dappbooster.dev/")} + `); } catch (error) { console.error(`${chalk.bold.red("An error occurred:")}`, error.message); diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 6d5983b..0000000 --- a/package-lock.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "dappbooster", - "version": "0.3.3", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "dappbooster", - "version": "0.3.3", - "license": "MIT", - "dependencies": { - "chalk": "^5.3.0" - }, - "bin": { - "dappbooster": "index.js" - } - }, - "node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - } - } -} diff --git a/package.json b/package.json index fc679a6..fc2ed7c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "dappbooster", - "version": "0.3.3", + "version": "0.3.4", "description": "Script to easily start your project with dAppBooster", "main": "index.js", "bin": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..69b4adc --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,23 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + chalk: + specifier: ^5.3.0 + version: 5.4.1 + +packages: + + chalk@5.4.1: + resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + +snapshots: + + chalk@5.4.1: {}