From 4c3ef4810ac4e0fa9cf64c15eb31c47311448e34 Mon Sep 17 00:00:00 2001 From: Jacob Nguyen <76754747+jacoobes@users.noreply.github.com> Date: Sun, 8 May 2022 21:01:50 -0500 Subject: [PATCH 1/7] refactor: add jsdoc for gitinit --- package-lock.json | 4 ++-- src/prompts/init.js | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 740ac6d..f8b9e00 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { - "name": "@sern-handler/cli", + "name": "@sern/cli", "version": "0.1.0", "lockfileVersion": 2, "requires": true, "packages": { "": { - "name": "@sern-handler/cli", + "name": "@sern/cli", "version": "0.1.0", "license": "MIT", "dependencies": { diff --git a/src/prompts/init.js b/src/prompts/init.js index 6ea7024..a29ce4b 100644 --- a/src/prompts/init.js +++ b/src/prompts/init.js @@ -93,7 +93,9 @@ export const npmInit = { message: `Do you want to ${blueBright('me')} to initialize npm?`, initial: true, }; - +/** + * @type {import('prompts').PromptObject} + */ export const gitInit = { name: 'gitinit', type: 'confirm', From f760dbc6e39e098496f25a5c4ee90855a2bb3bd5 Mon Sep 17 00:00:00 2001 From: Jacob Nguyen <76754747+jacoobes@users.noreply.github.com> Date: Sun, 8 May 2022 22:12:06 -0500 Subject: [PATCH 2/7] perf(init.js): string.match -> regex.test for node version --- src/commands/init.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/commands/init.js b/src/commands/init.js index 4dc0198..621b9ce 100644 --- a/src/commands/init.js +++ b/src/commands/init.js @@ -22,8 +22,7 @@ export async function init({ flags }) { process.exit(0); } const node = await execa('node', ['--version']); - - if (node.stdout.match(/v1(([0-6]\.[2-9])|([0-5]\.[0-9]))/gm)?.length) { + if ((/v1(([0-6]\.[2-9])|([0-5]\.[0-9]))/gm).test(node.stdout)) { console.log( yellowBright( `\nYou are using Node ${node.stdout}\nPlease upgrade to Node 16.10.x or higher!\n` From e74976a72cce8f9adeddbd92d3b55466b4e84e2a Mon Sep 17 00:00:00 2001 From: Jacob Nguyen <76754747+jacoobes@users.noreply.github.com> Date: Sun, 8 May 2022 22:26:10 -0500 Subject: [PATCH 3/7] refactor: Simplifying logic, cleaning up code --- src/commands/test.js | 3 +-- src/index.js | 4 ++-- src/prompts/init.js | 4 +--- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/commands/test.js b/src/commands/test.js index 4934480..b968606 100644 --- a/src/commands/test.js +++ b/src/commands/test.js @@ -12,6 +12,5 @@ export async function editMain(name) { output.main = name; - const result = () => writeFile(pjLocation, JSON.stringify(output, null, 2)); - return result(); + return writeFile(pjLocation, JSON.stringify(output, null, 2)); } diff --git a/src/index.js b/src/index.js index 3bbfc4e..c9d465f 100644 --- a/src/index.js +++ b/src/index.js @@ -2,9 +2,9 @@ import { init } from './commands/init.js'; const regex = /(?<=--|-)\w+/gm; -const flags = process.argv.slice(2).join(' ').match(regex); - const rawArgs = process.argv.slice(2); +const flags = rawArgs.join(' ').match(regex); + const args = rawArgs .join(' ') .trim() diff --git a/src/prompts/init.js b/src/prompts/init.js index a29ce4b..3daaec9 100644 --- a/src/prompts/init.js +++ b/src/prompts/init.js @@ -61,9 +61,7 @@ export const token = { type: 'password', validate: (/** @type {string} */ token) => - token.match( - /(?mfa\.[a-z0-9_-]{20,})|(?[a-z0-9_-]{23,28}\.[a-z0-9_-]{6,7}\.[a-z0-9_-]{27})/i - )?.length + (/(?mfa\.[a-z0-9_-]{20,})|(?[a-z0-9_-]{23,28}\.[a-z0-9_-]{6,7}\.[a-z0-9_-]{27})/i).test(token) ? true : 'Invalid token', }; From 6086af063a982609a1c6ba0e6a4a68d3feca1ace Mon Sep 17 00:00:00 2001 From: Jacob Nguyen <76754747+jacoobes@users.noreply.github.com> Date: Sun, 8 May 2022 22:54:26 -0500 Subject: [PATCH 4/7] refactor: removing redundant return process.exit(), more concise cli messages --- src/commands/init.js | 46 +++++++++++++++++++++++--------------------- src/commands/test.js | 2 +- src/prompts/init.js | 7 +++---- 3 files changed, 28 insertions(+), 27 deletions(-) diff --git a/src/commands/init.js b/src/commands/init.js index 621b9ce..9460b2d 100644 --- a/src/commands/init.js +++ b/src/commands/init.js @@ -18,9 +18,10 @@ const { prompt } = prompts; // TODO make this functional and better! export async function init({ flags }) { if (flags?.includes('y')) { - console.log("I see a flag there! Seems like you're lazy!\nBye!"); + console.log("I see the -y flag there! Seems like you're lazy!\nBye!"); process.exit(0); } + const node = await execa('node', ['--version']); if ((/v1(([0-6]\.[2-9])|([0-5]\.[0-9]))/gm).test(node.stdout)) { console.log( @@ -28,7 +29,7 @@ export async function init({ flags }) { `\nYou are using Node ${node.stdout}\nPlease upgrade to Node 16.10.x or higher!\n` ) ); - return process.exit(1); + process.exit(1); } const pkg = await findUp('package.json'); @@ -40,24 +41,24 @@ export async function init({ flags }) { `${redBright('Failed')} to initialize Sern!` + '\nMaybe you should run npm init?' ); - return process.exit(1); - } else { - const spin = ora({ - text: 'Initializing npm...', - spinner: 'aesthetic', - }).start(); - const exee = await execa('npm', ['init', '-y']).catch( - () => null - ); /* .stdout.pipe(process.stdout) */ - await wait(300); - if (!exee || exee?.failed) { - spin.fail( - `${redBright('Failed')} to initialize npm!` + - '\nMaybe you should run npm init?' - ); - return process.exit(1); - } else spin.succeed('Npm initialized!'); - } + process.exit(1); + } + const spin = ora({ + text: 'Initializing npm...', + spinner: 'aesthetic', + }).start(); + const exee = await execa('npm', ['init', '-y']).catch( + () => null + ); /* .stdout.pipe(process.stdout) */ + await wait(300); + if (!exee || exee?.failed) { + spin.fail( + `${redBright('Failed')} to initialize npm!` + + '\nMaybe you should run npm init?' + ); + process.exit(1); + } + spin.succeed('Npm initialized!'); } const git = await findUp('.git/config'); if (!git) { @@ -81,8 +82,9 @@ export async function init({ flags }) { `${redBright('Failed')} to initialize git!` + '\nMaybe you should run git init?' ); - return process.exit(1); - } else spin.succeed('Git initialized!'); + process.exit(1); + } + spin.succeed('Git initialized!'); return; } } diff --git a/src/commands/test.js b/src/commands/test.js index b968606..476c4ad 100644 --- a/src/commands/test.js +++ b/src/commands/test.js @@ -8,7 +8,7 @@ import { findUp } from 'find-up'; export async function editMain(name) { const pjLocation = await findUp('package.json'); const output = JSON.parse(await readFile(pjLocation, 'utf8')); - if (!output) throw new Error("Can't read file."); + if (!output) throw new Error("Can't read your package.json."); output.main = name; diff --git a/src/prompts/init.js b/src/prompts/init.js index 3daaec9..9dcf741 100644 --- a/src/prompts/init.js +++ b/src/prompts/init.js @@ -22,7 +22,7 @@ const Intents = [ ].map((i, j) => ({ title: i, value: j, short: `${j}` })); //! bad way export const lang = { - message: 'What language you want the project to be in?', + message: 'What language do you want the project to be in?', name: 'lang', type: 'select', choices: [ @@ -48,7 +48,7 @@ export const intent = { export const default_prefix = { message: - 'What is the default prefix for your bot? Type "none" if it is completely based on Application Commands', + 'What is the default prefix for your bot? Type "none" if it is completely Application-Command based', name: 'prefix', type: 'text', @@ -59,7 +59,6 @@ export const token = { message: 'What is your bot token?', name: 'token', type: 'password', - validate: (/** @type {string} */ token) => (/(?mfa\.[a-z0-9_-]{20,})|(?[a-z0-9_-]{23,28}\.[a-z0-9_-]{6,7}\.[a-z0-9_-]{27})/i).test(token) ? true @@ -86,7 +85,7 @@ export const cmds_dir = { * @type {import('prompts').PromptObject} */ export const npmInit = { - name: 'npminit', + name: 'npm_init', type: 'confirm', message: `Do you want to ${blueBright('me')} to initialize npm?`, initial: true, From 65f38f3eb2b4e8e2bd136b9bd8f37f1966be1661 Mon Sep 17 00:00:00 2001 From: EvolutionX Date: Mon, 9 May 2022 20:44:48 +0530 Subject: [PATCH 5/7] feat(*): cli is now functional --- src/{commands/test.js => utilities/edits.js} | 14 +++- src/utilities/install.js | 78 ++++++++++++++++++++ src/utilities/npm.js | 21 ++++++ 3 files changed, 109 insertions(+), 4 deletions(-) rename src/{commands/test.js => utilities/edits.js} (50%) create mode 100644 src/utilities/install.js create mode 100644 src/utilities/npm.js diff --git a/src/commands/test.js b/src/utilities/edits.js similarity index 50% rename from src/commands/test.js rename to src/utilities/edits.js index 476c4ad..413d21e 100644 --- a/src/commands/test.js +++ b/src/utilities/edits.js @@ -1,16 +1,22 @@ -//@ts-check import { readFile, writeFile } from 'node:fs/promises'; import { findUp } from 'find-up'; + /** - * @param {string} name + * It takes a string, finds the package.json file in the directory of the string, and changes the name + * of the package.json file to the string. + * @param {string} name - The name of the project. + * @returns A promise. */ export async function editMain(name) { - const pjLocation = await findUp('package.json'); + const pjLocation = await findUp('package.json', { + cwd: process.cwd() + '/' + name, + }); + const output = JSON.parse(await readFile(pjLocation, 'utf8')); if (!output) throw new Error("Can't read your package.json."); - output.main = name; + output.name = name; return writeFile(pjLocation, JSON.stringify(output, null, 2)); } diff --git a/src/utilities/install.js b/src/utilities/install.js new file mode 100644 index 0000000..d25d0bb --- /dev/null +++ b/src/utilities/install.js @@ -0,0 +1,78 @@ +import { execa } from 'execa'; +import { redBright } from 'colorette'; +import fs from 'fs'; +import path from 'path'; +import { readFile } from 'fs/promises'; +import { findUp } from 'find-up'; +import ora from 'ora'; + +/** + * It installs dependencies from a package.json file + * @param choice - The package manager to use. + * @param name - The name of the project + * @returns a promise. + */ +export async function installDeps(choice, name) { + const pkg = await findUp('package.json', { + cwd: process.cwd() + '/' + name, + }); + if (!pkg) throw new Error('No package.json found!'); + const output = JSON.parse(await readFile(pkg, 'utf8')); + if (!output) throw new Error("Can't read file."); + const deps = output.dependencies; + if (!deps) throw new Error("Can't find dependencies."); + const spin = ora({ + text: `Installing dependencies...`, + spinner: 'aesthetic', + }).start(); + const result = await execa(choice, ['install'], { + cwd: process.cwd() + '/' + name, + }).catch(() => null); + if (!result || result?.failed) { + spin.fail(`${redBright('Failed')} to install dependencies!`); + return process.exit(1); + } else spin.succeed(`Dependencies installed!`); +} + +/** + * Clone the repo, copy the files from the repo to the new project directory, and delete the repo + * @param {string} lang - The language of the template + * @param {string} name - The name of the project + */ +export async function cloneRepo(lang, name) { + await execa('git', [ + 'clone', + `https://github.com/sern-handler/templates.git`, // ? See the idea of @Allyedge having templates built in cli + ]); + copyRecursiveSync(`templates/templates/${lang}`, name); + fs.rmSync(`templates/`, { recursive: true, force: true }); +} + +/** + * If the source is a directory, create the destination directory and then recursively copy the + * contents of the source directory to the destination directory. If the source is not a directory, + * copy the source file to the destination file + * @param {string} src - The source path. + * @param {string} dest - The destination folder where the files will be copied to. + */ +function copyRecursiveSync(src, dest) { + var exists = fs.existsSync(src); + var stats = exists && fs.statSync(src); + var isDirectory = exists && stats.isDirectory(); + if (isDirectory) { + fs.mkdirSync(dest); + fs.readdirSync(src).forEach(function (childItemName) { + copyRecursiveSync( + path.join(src, childItemName), + path.join(dest, childItemName) + ); + }); + } else { + fs.copyFileSync(src, dest); + } +} + +// async function wait(ms) { +// const wait = (await import('util')).promisify(setTimeout); +// return wait(ms); +// } diff --git a/src/utilities/npm.js b/src/utilities/npm.js new file mode 100644 index 0000000..2f73a6c --- /dev/null +++ b/src/utilities/npm.js @@ -0,0 +1,21 @@ +import { execa } from 'execa'; + +/** + * It checks if you have npm or yarn installed, and returns a string based on the result + * @returns A promise that resolves to a string. + */ +export async function npm() { + const npm = await execa('npm', ['-v']); + const npm_version = npm?.stdout; + const yarn = await execa('yarn', ['-v']); + const yarn_version = yarn?.stdout; + if (npm_version && !yarn_version) { + return 'npm'; + } + if (!npm_version && yarn_version) { + return 'yarn'; + } + if (npm_version && yarn_version) { + return 'both'; + } +} From 6c2e65923af1d5a451a6ca3b439afdd00285910b Mon Sep 17 00:00:00 2001 From: EvolutionX Date: Mon, 9 May 2022 20:47:06 +0530 Subject: [PATCH 6/7] chore: shit --- src/utilities/edits.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/utilities/edits.js b/src/utilities/edits.js index 413d21e..9bac1ba 100644 --- a/src/utilities/edits.js +++ b/src/utilities/edits.js @@ -1,7 +1,6 @@ import { readFile, writeFile } from 'node:fs/promises'; import { findUp } from 'find-up'; - /** * It takes a string, finds the package.json file in the directory of the string, and changes the name * of the package.json file to the string. From 4a24ed0cbafbba4179e87f1e5454561d2020ffbf Mon Sep 17 00:00:00 2001 From: EvolutionX Date: Mon, 9 May 2022 20:56:45 +0530 Subject: [PATCH 7/7] chore: update description --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 169ee50..03243ca 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@sern/cli", "version": "0.1.0", - "description": "A CLI for @sern-handler", + "description": "A CLI for @sern/handler", "exports": "./src/index.js", "bin": { "sern": "./src/index.js"