diff --git a/packages/cli/lib/getPackageManager.ts b/packages/cli/lib/getPackageManager.ts index 091385c..91ea6b7 100644 --- a/packages/cli/lib/getPackageManager.ts +++ b/packages/cli/lib/getPackageManager.ts @@ -4,7 +4,7 @@ export default function get(): string|null { return null; } - const manager= userAgent.split(" ")[0].split("/")[0]; + const manager = userAgent.split(" ")[0].split("/")[0]; return manager } \ No newline at end of file diff --git a/packages/cli/lib/installDependencies.ts b/packages/cli/lib/installDependencies.ts index ab21849..cf15d2f 100644 --- a/packages/cli/lib/installDependencies.ts +++ b/packages/cli/lib/installDependencies.ts @@ -1,44 +1,87 @@ -import { spawn } from "child_process"; -import { userInfo } from "os"; +import { exec, spawn } from "child_process"; +import { platform, userInfo } from "os"; +import * as logger from "../utils/logger" export default function install(packageManager: "npm" | "pnpm" | "yarn" | null, workingDirectory: string) { const cmds = { npm: { - command: "npm", - args: ["install"] + win32: { + command: "npm.cmd", + args: ["install"], + full: "npm.cmd install" + }, + + linux: { + command: "npm.cmd", + args: ["install"], + full: "npm install" + }, + + darwin: { + command: "npm", + args: ["install"], + full: "npm install" + } }, pnpm: { - command: "pnpm", - args: ["install"] + win32: { + command: "pnpm.cmd", + args: ["i"], + full: "pnpm.cmd install" + }, + + linux: { + command: "pnpm", + args: ["i"], + full: "pnpm install" + }, + + darwin: { + command: "pnpm", + args: ["i"], + full: "pnpm install" + } }, yarn: { - command: "yarn", - args: [] + win32: { + command: "yarn.cmd", + args: [], + full: "yarn.cmd" + }, + + linux: { + command: "yarn", + args: [], + full: "yarn" + }, + + darwin: { + command: "yarn", + args: [], + full: "yarn" + } } } - - console.log(userInfo().shell) switch (packageManager) { case null: - const spawnedNPM = spawn(`${cmds.npm.command}`, cmds.npm.args, { cwd: workingDirectory, stdio: "inherit", shell: userInfo().shell }) + exec("npm config set color always") + logger.info("Installing dependencies with npm.") + const spawnedNPM = spawn(`${cmds.npm[platform()].command}`, cmds.npm[platform()].args, { cwd: workingDirectory }) spawnedNPM.stdout.on("data", (out) => { - console.log(`Installing dependencies using npm`) - console.log(`\rnpm :: ${out}`) + logger.custom("npm", out.toString().trim()) }) - case "npm" || "pnpm" || "yarn": - const spawnedAny = spawn(`${cmds[packageManager].command}`, cmds[packageManager].args, { cwd: workingDirectory, stdio: "inherit", shell: userInfo().shell }) + default: + logger.info(`Installing dependencies with ${packageManager}`) + const spawnedAny = spawn(`${cmds[packageManager][platform()].command}`, cmds[packageManager][platform()].args, { cwd: workingDirectory }) spawnedAny.stdout.on("data", (out) => { - console.log(`Installing dependencies using ${packageManager}`) - console.log(`\r${packageManager} :: ${out}`) - }) + logger.custom(packageManager, out.toString().trim()) + }) spawnedAny.stderr.on("data", (err) => { - console.error(`\r${packageManager} error: ${err}`) + logger.customError(packageManager, err.toString().trim()) }) - - } } \ No newline at end of file diff --git a/packages/cli/package.json b/packages/cli/package.json index 6b6d059..9d6bf5c 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -12,6 +12,7 @@ "author": "", "license": "ISC", "dependencies": { + "fs-extra": "^10.1.0", "inquirer": "8.2.3", "kleur": "^4.1.5" }, diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index 84ca54c..9a87626 100644 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -1,9 +1,16 @@ +import { mkdir, readdir, readdirSync } from "fs"; import * as inquirer from "inquirer"; import getPackageManager from "../lib/getPackageManager"; import install from "../lib/installDependencies"; +import * as logger from "../utils/logger" inquirer - .prompt([ + .prompt([ + { + type: "input", + name: "location", + message: "Where should the project be initialized?" + }, { type: 'list', name: 'flavor', @@ -13,16 +20,30 @@ inquirer return val.toLowerCase(); }, }, + ]) .then((answers) => { - console.log(JSON.stringify(answers, null, ' ')); + mkdir(answers.location, (e) => { + if (e && e.code != "EEXIST") { + logger.error("Failed to create project directory.") + process.exit(1) + } + + if (e) { + if (e.code == "EEXIST") { + readdir(answers.location, (_, files) => { + if (files.length) { + logger.error("Directory not empty.") + process.exit(1) + } + }) + } + } + }) + let packageManager = getPackageManager() - if (packageManager !== "npm"||"pnpm"||"yarn") { - packageManager = "npm" - } - install(packageManager as "npm"|"pnpm"|"yarn"|null, ".") - - + install(packageManager as "npm" | "pnpm" | "yarn" | null, answers.location) + }); diff --git a/packages/cli/utils/logger.ts b/packages/cli/utils/logger.ts new file mode 100644 index 0000000..14d3c67 --- /dev/null +++ b/packages/cli/utils/logger.ts @@ -0,0 +1,30 @@ +import * as kleur from 'kleur'; + +const progressStyle = kleur.bold().gray +const successStyle = kleur.bold().green +const errorStyle = kleur.black().bold().red +const warningStyle = kleur.black().bold().yellow + +export function warn(log: string) { + console.log(warningStyle(`warning`), " ", log ) +} + +export function error(log: string) { + console.log(errorStyle(`error`), " ", log ) +} + +export function info(log: string) { + console.log(successStyle(`info`), " ", log ) +} + +export function success(log: string) { + console.log(successStyle(`success`), " ", log ) +} + +export function custom(customType: string, log: string) { + console.log(progressStyle(`[${customType}] `), log) +} + +export function customError(customType: string, log: string) { + console.log(errorStyle(`[${customType}] error `), log) +} \ No newline at end of file diff --git a/packages/package-lock.json b/packages/package-lock.json new file mode 100644 index 0000000..4885e12 --- /dev/null +++ b/packages/package-lock.json @@ -0,0 +1,24 @@ +{ + "name": "packages", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "dependencies": { + "async": "latest" + } + }, + "node_modules/async": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" + } + }, + "dependencies": { + "async": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" + } + } +} diff --git a/packages/package.json b/packages/package.json new file mode 100644 index 0000000..16d765c --- /dev/null +++ b/packages/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "async": "latest" + } +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2f29842..0e3c108 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -43,6 +43,7 @@ importers: '@types/inquirer': 8.2.3 '@types/node': ^18.11.9 '@types/prompt': ^1.1.4 + fs-extra: ^10.1.0 inquirer: 8.2.3 kleur: ^4.1.5 ts-node: ^10.9.1 @@ -51,6 +52,7 @@ importers: tslib: ^2.4.1 typescript: ^4.9.3 dependencies: + fs-extra: 10.1.0 inquirer: 8.2.3 kleur: 4.1.5 devDependencies: @@ -1156,6 +1158,15 @@ packages: resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} dev: false + /fs-extra/10.1.0: + resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} + engines: {node: '>=12'} + dependencies: + graceful-fs: 4.2.10 + jsonfile: 6.1.0 + universalify: 2.0.0 + dev: false + /fs.realpath/1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} @@ -1250,6 +1261,10 @@ packages: slash: 3.0.0 dev: false + /graceful-fs/4.2.10: + resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} + dev: false + /has-bigints/1.0.2: resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} dev: false @@ -1509,6 +1524,14 @@ packages: minimist: 1.2.7 dev: false + /jsonfile/6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + dependencies: + universalify: 2.0.0 + optionalDependencies: + graceful-fs: 4.2.10 + dev: false + /jsx-ast-utils/3.3.3: resolution: {integrity: sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw==} engines: {node: '>=4.0'} @@ -2297,6 +2320,11 @@ packages: which-boxed-primitive: 1.0.2 dev: false + /universalify/2.0.0: + resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} + engines: {node: '>= 10.0.0'} + dev: false + /uri-js/4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} dependencies: