From b68f25bc9bae5e7303343710a6f736ec816fd147 Mon Sep 17 00:00:00 2001 From: Emelia Smith Date: Fri, 14 Feb 2025 20:03:40 +0100 Subject: [PATCH] feat: add support for installing specific versions of packages --- commands/add.ts | 17 +++++++++++++---- tests/commands/add.spec.ts | 26 ++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/commands/add.ts b/commands/add.ts index 34913fea..e38eb7ce 100644 --- a/commands/add.ts +++ b/commands/add.ts @@ -28,6 +28,9 @@ export default class Add extends BaseCommand { @args.string({ description: 'Package name' }) declare name: string + @args.string({ description: 'Package version', required: false }) + declare version: string + @flags.boolean({ description: 'Display logs in verbose mode' }) declare verbose?: boolean @@ -80,7 +83,7 @@ export default class Add extends BaseCommand { /** * Install the package using the selected package manager */ - async #installPackage(npmPackageName: string) { + async #installPackage(npmPackageName: string, npmPackageVersion: string) { const colors = this.colors const spinner = this.logger .await(`installing ${colors.green(this.name)} using ${colors.grey(this.packageManager!)}`) @@ -88,8 +91,12 @@ export default class Add extends BaseCommand { spinner.start() + const packageToInstall = npmPackageVersion + ? `${npmPackageName}@${npmPackageVersion}` + : npmPackageName + try { - await installPackage(npmPackageName, { + await installPackage(packageToInstall, { dev: this.dev, silent: this.verbose === true ? false : true, cwd: this.app.makePath(), @@ -130,7 +137,9 @@ export default class Add extends BaseCommand { /** * Prompt the user to confirm the installation */ - const cmd = colors.grey(`${this.packageManager} add ${this.dev ? '-D ' : ''}${this.name}`) + const cmd = colors.grey( + `${this.packageManager} add ${this.dev ? '-D ' : ''}${this.name}${this.version ? `@${this.version}` : ''}` + ) this.logger.info(`Installing the package using the following command : ${cmd}`) const shouldInstall = await this.prompt.confirm('Continue ?', { @@ -146,7 +155,7 @@ export default class Add extends BaseCommand { /** * Install package */ - const pkgWasInstalled = await this.#installPackage(npmPackageName) + const pkgWasInstalled = await this.#installPackage(npmPackageName, this.version) if (!pkgWasInstalled) { return } diff --git a/tests/commands/add.spec.ts b/tests/commands/add.spec.ts index b98c7066..896d66b3 100644 --- a/tests/commands/add.spec.ts +++ b/tests/commands/add.spec.ts @@ -173,6 +173,32 @@ test.group('Install', (group) => { assert.deepEqual(pkgJson.devDependencies, { test: 'file:node_modules/foo' }) }) + test('should install specific version of dependency', async ({ assert, fs }) => { + const ace = await new AceFactory().make(fs.baseUrl, { + importer: (filePath) => import(join(filePath, `index.js?${Math.random()}`)), + }) + + await setupProject(fs, 'npm') + await setupPackage(fs) + + const packageVersion = await fs.contentsJson('package.json') + console.log({ packageVersion }) + + await ace.app.init() + + ace.addLoader(new ListLoader([Configure])) + ace.ui.switchMode('raw') + ace.prompt.trap('install').accept() + + const command = await ace.create(Add, [new URL('node_modules/foo', fs.baseUrl).href, 'latest']) + command.verbose = true + + await command.exec() + + const pkgJson = await fs.contentsJson('package.json') + assert.deepEqual(pkgJson.devDependencies, { test: 'file:node_modules/foo' }) + }) + test('pass unknown args to configure', async ({ fs, assert }) => { const ace = await new AceFactory().make(fs.baseUrl, { importer: (filePath) => import(join(filePath, `index.js?${Math.random()}`)),