From 924492465a595254314cb3b0973c2e6272032498 Mon Sep 17 00:00:00 2001 From: jdwilkin4 Date: Mon, 12 Jun 2023 13:07:21 -0700 Subject: [PATCH 1/7] feat: adding package manager option to CLI --- packages/create-starter/src/index.ts | 37 ++++++++++++++++------------ 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/packages/create-starter/src/index.ts b/packages/create-starter/src/index.ts index 5b01abcbf..9f5cd1fd9 100644 --- a/packages/create-starter/src/index.ts +++ b/packages/create-starter/src/index.ts @@ -10,6 +10,7 @@ import { trackSelectedKit } from './metrics'; const STARTER_KITS_JSON_URL = 'https://raw.githubusercontent.com/thisdot/starter.dev/main/starter-kits.json'; const EXCLUDED_PACKAGE_JSON_FIELDS = ['hasShowcase']; +const PACKAGE_MANAGERS: string[] = ['npm', 'pnpm', 'yarn']; export async function main() { console.log(`\n${bold('Welcome to starter.dev!')} ${gray('(create-starter)')}`); @@ -25,10 +26,12 @@ export async function main() { if (res.ok) { const starterKitsJSON = await res.json(); if (typeof starterKitsJSON === 'object' && starterKitsJSON !== null) { - starters = Object.entries(starterKitsJSON).map(([name, description]) => ({ - value: name as string, - title: description as string, - })).sort((a, b) => a.title.localeCompare(b.title)); + starters = Object.entries(starterKitsJSON) + .map(([name, description]) => ({ + value: name as string, + title: description as string, + })) + .sort((a, b) => a.title.localeCompare(b.title)); } } else { throw new Error(); @@ -44,7 +47,14 @@ export async function main() { name: 'kit', message: 'Which starter kit would you like to use?', choices: starters, - suggest: (input, choices) => Promise.resolve(choices.filter(c => c.title.includes(input))), + suggest: (input, choices) => Promise.resolve(choices.filter((c) => c.title.includes(input))), + }, + { + type: 'autocomplete', + name: 'packageManager', + message: 'Which package manager would you like to use?', + choices: PACKAGE_MANAGERS.map((pm) => ({ title: pm, value: pm })), + suggest: (input, choices) => Promise.resolve(choices.filter((c) => c.title.includes(input))), }, { type: 'text', @@ -53,26 +63,23 @@ export async function main() { }, ]); - if (!options.kit || !options.name) { + if (!options.kit || !options.name || !options.packageManager) { process.exit(1); } - const [createSelectedKitResult] = await Promise.allSettled([ - createStarter(options), - trackSelectedKit(options.kit) - ]) + const [createSelectedKitResult] = await Promise.allSettled([createStarter(options), trackSelectedKit(options.kit)]); if (createSelectedKitResult.status === 'rejected') { const err = createSelectedKitResult.reason; console.error(red(err instanceof Error ? err.message : `Creating starter kit failed`)); process.exit(1); } - } -async function createStarter(options: prompts.Answers<'name' | 'kit'>): Promise { +async function createStarter(options: prompts.Answers<'name' | 'kit' | 'packageManager'>): Promise { const repoPath = `thisdot/starter.dev/starters/${options.kit}`; const destPath = path.join(process.cwd(), options.name); + const packageManager = options.packageManager; const emitter = degit(repoPath, { cache: false, @@ -106,10 +113,10 @@ async function createStarter(options: prompts.Answers<'name' | 'kit'>): Promise< console.log(` ${bold(cyan(`cd ${options.name}`))}`); if (packageJsonExists) { - console.log(` ${bold(cyan('npm install'))} (or pnpm install, yarn, etc)`); + console.log(` ${bold(cyan(`${packageManager} install`))}`); } } catch (err: unknown) { - throw new Error('Failed to initialize the starter kit. This probably means that you provided an invalid kit name.') + throw new Error('Failed to initialize the starter kit. This probably means that you provided an invalid kit name.'); } } @@ -130,5 +137,3 @@ async function initNodeProject(packageJsonPath: string, projectDestPath: string, console.info(gray(`> ${bold('Note:')} Failed to update package.json. You may need to do this manually.`)); } } - - From ff40f55e6457df5c42afd892822cb29975476c62 Mon Sep 17 00:00:00 2001 From: WillHutt Date: Tue, 13 Jun 2023 13:29:44 -0700 Subject: [PATCH 2/7] feat: wip repo commit changes --- packages/create-starter/src/index.ts | 3 ++- packages/create-starter/src/utils.ts | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/packages/create-starter/src/index.ts b/packages/create-starter/src/index.ts index 9f5cd1fd9..325aeb337 100644 --- a/packages/create-starter/src/index.ts +++ b/packages/create-starter/src/index.ts @@ -5,7 +5,7 @@ import prompts, { Choice } from 'prompts'; import degit from 'tiged'; import fetch from 'node-fetch'; import yargs from 'yargs-parser'; -import { initGitRepo, removeLockFileIfExists, overrideAngularJsonIfExists, fileExists } from './utils'; +import { initGitRepo, initCommit, removeLockFileIfExists, overrideAngularJsonIfExists, fileExists } from './utils'; import { trackSelectedKit } from './metrics'; const STARTER_KITS_JSON_URL = 'https://raw.githubusercontent.com/thisdot/starter.dev/main/starter-kits.json'; @@ -108,6 +108,7 @@ async function createStarter(options: prompts.Answers<'name' | 'kit' | 'packageM } await initGitRepo(destPath); + await initCommit(destPath, packageManager); console.log(bold(green('✔') + ' Done!')); console.log('\nNext steps:'); console.log(` ${bold(cyan(`cd ${options.name}`))}`); diff --git a/packages/create-starter/src/utils.ts b/packages/create-starter/src/utils.ts index da33c95c3..7ee938c13 100644 --- a/packages/create-starter/src/utils.ts +++ b/packages/create-starter/src/utils.ts @@ -27,6 +27,24 @@ export async function initGitRepo(path: string) { }); } +export async function initCommit(path: string, packageManager: string) { + return new Promise((resolve, reject) => { + exec( + `ls && cd ${path} && ${packageManager} install && git status && git add . && git status && git commit -m 'init commit generated by starter.dev CLI' && git status && ls && cd ../ && ls`, + (err, stdout) => { + if (err) { + console.log('err', err); + reject(err); + } else { + console.log('success'); + console.log('stdout', stdout); + resolve(undefined); + } + } + ); + }); +} + export async function removeLockFileIfExists(fileName: string, directoryPath: string): Promise { let removed: boolean; try { From 8404bb077d9a37149500a21158c157c921b2ba7f Mon Sep 17 00:00:00 2001 From: WillHutt Date: Tue, 13 Jun 2023 16:13:33 -0700 Subject: [PATCH 3/7] feat: repo commit changes/reorganization --- packages/create-starter/src/index.ts | 23 ++++++++++++++--------- packages/create-starter/src/utils.ts | 25 +++++-------------------- 2 files changed, 19 insertions(+), 29 deletions(-) diff --git a/packages/create-starter/src/index.ts b/packages/create-starter/src/index.ts index 325aeb337..7e0c73263 100644 --- a/packages/create-starter/src/index.ts +++ b/packages/create-starter/src/index.ts @@ -5,7 +5,7 @@ import prompts, { Choice } from 'prompts'; import degit from 'tiged'; import fetch from 'node-fetch'; import yargs from 'yargs-parser'; -import { initGitRepo, initCommit, removeLockFileIfExists, overrideAngularJsonIfExists, fileExists } from './utils'; +import { initGitRepo, removeLockFileIfExists, overrideAngularJsonIfExists, fileExists } from './utils'; import { trackSelectedKit } from './metrics'; const STARTER_KITS_JSON_URL = 'https://raw.githubusercontent.com/thisdot/starter.dev/main/starter-kits.json'; @@ -49,6 +49,11 @@ export async function main() { choices: starters, suggest: (input, choices) => Promise.resolve(choices.filter((c) => c.title.includes(input))), }, + { + type: 'text', + name: 'name', + message: 'What is the name of your project?', + }, { type: 'autocomplete', name: 'packageManager', @@ -56,11 +61,6 @@ export async function main() { choices: PACKAGE_MANAGERS.map((pm) => ({ title: pm, value: pm })), suggest: (input, choices) => Promise.resolve(choices.filter((c) => c.title.includes(input))), }, - { - type: 'text', - name: 'name', - message: 'What is the name of your project?', - }, ]); if (!options.kit || !options.name || !options.packageManager) { @@ -107,14 +107,19 @@ async function createStarter(options: prompts.Answers<'name' | 'kit' | 'packageM await initNodeProject(packageJsonPath, destPath, options); } - await initGitRepo(destPath); - await initCommit(destPath, packageManager); + await initGitRepo(destPath, packageManager); console.log(bold(green('✔') + ' Done!')); console.log('\nNext steps:'); console.log(` ${bold(cyan(`cd ${options.name}`))}`); if (packageJsonExists) { - console.log(` ${bold(cyan(`${packageManager} install`))}`); + switch (packageManager) { + case 'yarn': + console.log(`${bold(cyan(`${packageManager} dev`))}`); + break; + default: + console.log(`${bold(cyan(`${packageManager} start`))}`); + } } } catch (err: unknown) { throw new Error('Failed to initialize the starter kit. This probably means that you provided an invalid kit name.'); diff --git a/packages/create-starter/src/utils.ts b/packages/create-starter/src/utils.ts index 7ee938c13..8b8e56aee 100644 --- a/packages/create-starter/src/utils.ts +++ b/packages/create-starter/src/utils.ts @@ -15,36 +15,21 @@ export async function fileExists(path: string) { } } -export async function initGitRepo(path: string) { +export async function initGitRepo(path: string, packageManager: string) { return new Promise((resolve, reject) => { - exec(`git init ${path}`, (err) => { + exec(`cd ${path} && git init && ${packageManager} install && git add . && git commit -m 'init commit generated by starter.dev CLI' && cd ../`, (err, stdout) => { if (err) { + console.log('err', err); reject(err); } else { + console.log('success'); + console.log('stdout', stdout); resolve(undefined); } }); }); } -export async function initCommit(path: string, packageManager: string) { - return new Promise((resolve, reject) => { - exec( - `ls && cd ${path} && ${packageManager} install && git status && git add . && git status && git commit -m 'init commit generated by starter.dev CLI' && git status && ls && cd ../ && ls`, - (err, stdout) => { - if (err) { - console.log('err', err); - reject(err); - } else { - console.log('success'); - console.log('stdout', stdout); - resolve(undefined); - } - } - ); - }); -} - export async function removeLockFileIfExists(fileName: string, directoryPath: string): Promise { let removed: boolean; try { From 0f7bda914dbdbdf2f96ecd06f179b0345fcf43c7 Mon Sep 17 00:00:00 2001 From: WillHutt Date: Tue, 13 Jun 2023 16:17:40 -0700 Subject: [PATCH 4/7] refactor: cleanup --- packages/create-starter/src/utils.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/create-starter/src/utils.ts b/packages/create-starter/src/utils.ts index 8b8e56aee..e6a68cafa 100644 --- a/packages/create-starter/src/utils.ts +++ b/packages/create-starter/src/utils.ts @@ -19,11 +19,8 @@ export async function initGitRepo(path: string, packageManager: string) { return new Promise((resolve, reject) => { exec(`cd ${path} && git init && ${packageManager} install && git add . && git commit -m 'init commit generated by starter.dev CLI' && cd ../`, (err, stdout) => { if (err) { - console.log('err', err); reject(err); } else { - console.log('success'); - console.log('stdout', stdout); resolve(undefined); } }); From 71591001e6c9b21cdd08e63032b141dd9c2ba664 Mon Sep 17 00:00:00 2001 From: WillHutt Date: Wed, 14 Jun 2023 16:07:31 -0700 Subject: [PATCH 5/7] fix: wip address of dev/start and package optionsi --- packages/create-starter/src/index.ts | 52 +++++++++++++++++++++++----- packages/create-starter/src/utils.ts | 24 +++++++++---- 2 files changed, 61 insertions(+), 15 deletions(-) diff --git a/packages/create-starter/src/index.ts b/packages/create-starter/src/index.ts index 7e0c73263..c7ba95bfb 100644 --- a/packages/create-starter/src/index.ts +++ b/packages/create-starter/src/index.ts @@ -10,7 +10,6 @@ import { trackSelectedKit } from './metrics'; const STARTER_KITS_JSON_URL = 'https://raw.githubusercontent.com/thisdot/starter.dev/main/starter-kits.json'; const EXCLUDED_PACKAGE_JSON_FIELDS = ['hasShowcase']; -const PACKAGE_MANAGERS: string[] = ['npm', 'pnpm', 'yarn']; export async function main() { console.log(`\n${bold('Welcome to starter.dev!')} ${gray('(create-starter)')}`); @@ -54,20 +53,23 @@ export async function main() { name: 'name', message: 'What is the name of your project?', }, + ]); + + const packageOptions = await prompts([ { type: 'autocomplete', name: 'packageManager', message: 'Which package manager would you like to use?', - choices: PACKAGE_MANAGERS.map((pm) => ({ title: pm, value: pm })), + choices: packageSelection(options.kit).map((pm) => ({ title: pm, value: pm })), suggest: (input, choices) => Promise.resolve(choices.filter((c) => c.title.includes(input))), }, ]); - if (!options.kit || !options.name || !options.packageManager) { + if (!options.kit || !options.name || !packageOptions) { process.exit(1); } - const [createSelectedKitResult] = await Promise.allSettled([createStarter(options), trackSelectedKit(options.kit)]); + const [createSelectedKitResult] = await Promise.allSettled([createStarter(options, packageOptions), trackSelectedKit(options.kit)]); if (createSelectedKitResult.status === 'rejected') { const err = createSelectedKitResult.reason; @@ -76,10 +78,25 @@ export async function main() { } } -async function createStarter(options: prompts.Answers<'name' | 'kit' | 'packageManager'>): Promise { +function packageSelection(selection: string): Array { + let packageOptions; + switch (selection) { + case 'deno-oak-denodb': + packageOptions = ['deno']; + break; + default: + packageOptions = ['npm', 'pnpm', 'yarn']; + } + return packageOptions; +} + +async function createStarter(options: prompts.Answers<'name' | 'kit'>, packageOptions: prompts.Answers<'packageManager'>): Promise { const repoPath = `thisdot/starter.dev/starters/${options.kit}`; const destPath = path.join(process.cwd(), options.name); - const packageManager = options.packageManager; + const packageManager = packageOptions.packageManager; + const kit = options.kit; + + console.log('packageManager', packageManager); const emitter = degit(repoPath, { cache: false, @@ -107,6 +124,22 @@ async function createStarter(options: prompts.Answers<'name' | 'kit' | 'packageM await initNodeProject(packageJsonPath, destPath, options); } + const packageCommand = `https://raw.githubusercontent.com/thisdot/starter.dev/main/starters/${kit}/${packageManager === 'deno' ? 'deno' : 'package'}.json`; + const res = await fetch(packageCommand); + let packageJSON; + + if (res.ok) { + packageJSON = await res.json(); + console.log('packageJSON', packageJSON); + console.log('scripts', packageJSON?.scripts?.dev); //with angular this is undefined + console.log('scripts', packageJSON?.scripts?.start); //with angular this returns a value + } else { + throw new Error(); + } + // need to resolve ts error + const startAction = packageJSON?.scripts?.dev !== undefined ? 'dev' : 'start'; + + // based off of packageManager we will need to tweak the install await initGitRepo(destPath, packageManager); console.log(bold(green('✔') + ' Done!')); console.log('\nNext steps:'); @@ -114,11 +147,12 @@ async function createStarter(options: prompts.Answers<'name' | 'kit' | 'packageM if (packageJsonExists) { switch (packageManager) { - case 'yarn': - console.log(`${bold(cyan(`${packageManager} dev`))}`); + // need to add special steps + case 'deno': + console.log(`${bold(cyan(`${packageManager} `))}`); break; default: - console.log(`${bold(cyan(`${packageManager} start`))}`); + console.log(`${bold(cyan(`${packageManager} ${startAction}`))}`); } } } catch (err: unknown) { diff --git a/packages/create-starter/src/utils.ts b/packages/create-starter/src/utils.ts index e6a68cafa..6f28e8d84 100644 --- a/packages/create-starter/src/utils.ts +++ b/packages/create-starter/src/utils.ts @@ -16,14 +16,26 @@ export async function fileExists(path: string) { } export async function initGitRepo(path: string, packageManager: string) { + // need to add check for deno + console.log( + `cd ${path} && git init && ${packageManager} ${ + packageManager === 'deno' ? 'cache' : 'install' + } && git add . && git commit -m 'init commit generated by starter.dev CLI' && cd ../` + ); return new Promise((resolve, reject) => { - exec(`cd ${path} && git init && ${packageManager} install && git add . && git commit -m 'init commit generated by starter.dev CLI' && cd ../`, (err, stdout) => { - if (err) { - reject(err); - } else { - resolve(undefined); + exec( + `cd ${path} && git init && ${packageManager} ${ + packageManager === 'deno' ? 'cache' : 'install' + } && git add . && git commit -m 'init commit generated by starter.dev CLI' && cd ../`, + (err, stdout) => { + if (err) { + reject(err); + } else { + console.log(stdout); + resolve(undefined); + } } - }); + ); }); } From 54762324b0b089166dc8879ec6a794a653f2ee00 Mon Sep 17 00:00:00 2001 From: WillHutt Date: Thu, 15 Jun 2023 16:18:46 -0700 Subject: [PATCH 6/7] fix: resolves deno issue and adds deno specific next steps --- packages/create-starter/src/index.ts | 34 +++++++++++++++------------- packages/create-starter/src/utils.ts | 11 ++------- 2 files changed, 20 insertions(+), 25 deletions(-) diff --git a/packages/create-starter/src/index.ts b/packages/create-starter/src/index.ts index 58b3b8081..89331f9b5 100644 --- a/packages/create-starter/src/index.ts +++ b/packages/create-starter/src/index.ts @@ -11,6 +11,13 @@ import { trackSelectedKit } from './metrics'; const STARTER_KITS_JSON_URL = 'https://raw.githubusercontent.com/thisdot/starter.dev/main/starter-kits.json'; const EXCLUDED_PACKAGE_JSON_FIELDS = ['hasShowcase']; +type Package = { + scripts: { + dev: string; + start: string; + }; +}; + export async function main() { console.log(`\n${bold('Welcome to starter.dev!')} ${gray('(create-starter)')}`); @@ -69,7 +76,6 @@ export async function main() { process.exit(1); } - const [createSelectedKitResult] = await Promise.allSettled([createStarter(options, packageOptions), trackSelectedKit(options.kit)]); if (createSelectedKitResult.status === 'rejected') { @@ -127,34 +133,30 @@ async function createStarter(options: prompts.Answers<'name' | 'kit'>, packageOp const packageCommand = `https://raw.githubusercontent.com/thisdot/starter.dev/main/starters/${kit}/${packageManager === 'deno' ? 'deno' : 'package'}.json`; const res = await fetch(packageCommand); - let packageJSON; + let packageJSON: Package; if (res.ok) { - packageJSON = await res.json(); - console.log('packageJSON', packageJSON); - console.log('scripts', packageJSON?.scripts?.dev); //with angular this is undefined - console.log('scripts', packageJSON?.scripts?.start); //with angular this returns a value + packageJSON = (await res.json()) as Package; } else { throw new Error(); } - // need to resolve ts error + const startAction = packageJSON?.scripts?.dev !== undefined ? 'dev' : 'start'; - // based off of packageManager we will need to tweak the install await initGitRepo(destPath, packageManager); console.log(bold(green('✔') + ' Done!')); console.log('\nNext steps:'); console.log(` ${bold(cyan(`cd ${options.name}`))}`); if (packageJsonExists) { - switch (packageManager) { - // need to add special steps - case 'deno': - console.log(`${bold(cyan(`${packageManager} `))}`); - break; - default: - console.log(`${bold(cyan(`${packageManager} ${startAction}`))}`); - } + console.log(` ${bold(cyan(`${packageManager} ${startAction}`))}`); + } else if (packageManager === 'deno') { + console.log(` ${bold(cyan('Make sure you have Docker & docker-compose installed on your machine'))}`); + console.log(` ${bold(cyan('Create a .env file and copy the contents of .env.example into it'))}`); + console.log(` ${bold(cyan('Run deno task start-db to start the local PostgreSQL and Redis'))}`); + console.log(` ${bold(cyan('Run deno task start-web to start the development server'))}`); + console.log(` ${bold(cyan('Open your browser to http://localhost:3333/health to see the API running'))}`); + console.log(` ${bold(cyan('Proceed to the Seeding chapter to seed the database with some sample data'))}`); } } catch (err: unknown) { throw new Error('Failed to initialize the starter kit. This probably means that you provided an invalid kit name.'); diff --git a/packages/create-starter/src/utils.ts b/packages/create-starter/src/utils.ts index 6f28e8d84..4099b402a 100644 --- a/packages/create-starter/src/utils.ts +++ b/packages/create-starter/src/utils.ts @@ -16,22 +16,15 @@ export async function fileExists(path: string) { } export async function initGitRepo(path: string, packageManager: string) { - // need to add check for deno - console.log( - `cd ${path} && git init && ${packageManager} ${ - packageManager === 'deno' ? 'cache' : 'install' - } && git add . && git commit -m 'init commit generated by starter.dev CLI' && cd ../` - ); return new Promise((resolve, reject) => { exec( `cd ${path} && git init && ${packageManager} ${ - packageManager === 'deno' ? 'cache' : 'install' + packageManager === 'deno' ? 'cache --lock=deno.lock --lock-write deps.ts' : 'install' } && git add . && git commit -m 'init commit generated by starter.dev CLI' && cd ../`, - (err, stdout) => { + (err) => { if (err) { reject(err); } else { - console.log(stdout); resolve(undefined); } } From 43f528e19be1bb2d77230cf4facdb2313bb6547d Mon Sep 17 00:00:00 2001 From: WillHutt Date: Thu, 15 Jun 2023 16:26:26 -0700 Subject: [PATCH 7/7] refactor: cleanup --- packages/create-starter/src/index.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/create-starter/src/index.ts b/packages/create-starter/src/index.ts index 89331f9b5..e13785efb 100644 --- a/packages/create-starter/src/index.ts +++ b/packages/create-starter/src/index.ts @@ -103,8 +103,6 @@ async function createStarter(options: prompts.Answers<'name' | 'kit'>, packageOp const packageManager = packageOptions.packageManager; const kit = options.kit; - console.log('packageManager', packageManager); - const emitter = degit(repoPath, { cache: false, force: true,