mirror of
https://github.com/pnpm/pnpm.git
synced 2026-01-06 22:18:17 -05:00
feat: add the pnpm create command (#3829)
This commit is contained in:
6
.changeset/forty-steaks-kick.md
Normal file
6
.changeset/forty-steaks-kick.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@pnpm/plugin-commands-script-runners": minor
|
||||
"pnpm": minor
|
||||
---
|
||||
|
||||
New command added: create. `pnpm create` is similar to `yarn create`.
|
||||
76
packages/plugin-commands-script-runners/src/create.ts
Normal file
76
packages/plugin-commands-script-runners/src/create.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import renderHelp from 'render-help'
|
||||
import { docsUrl } from '@pnpm/cli-utils'
|
||||
import PnpmError from '@pnpm/error'
|
||||
import * as dlx from './dlx'
|
||||
|
||||
export const commandNames = ['create']
|
||||
|
||||
export async function handler (_opts: Record<string, never>, params: string[]) {
|
||||
const [packageName, ...packageArgs] = params
|
||||
if (packageName === undefined) {
|
||||
throw new PnpmError(
|
||||
'MISSING_ARGS',
|
||||
'Missing the template package name.\n' +
|
||||
'The correct usage is `pnpm create <name>` ' +
|
||||
'with <name> substituted for a package name.'
|
||||
)
|
||||
}
|
||||
|
||||
const createPackageName = convertToCreateName(packageName)
|
||||
return dlx.handler({}, [createPackageName, ...packageArgs])
|
||||
}
|
||||
|
||||
export function rcOptionsTypes () {
|
||||
return {}
|
||||
}
|
||||
|
||||
export function cliOptionsTypes () {
|
||||
return {}
|
||||
}
|
||||
|
||||
export function help () {
|
||||
return renderHelp({
|
||||
description: 'Creates a project from a `create-*` starter kit.',
|
||||
url: docsUrl('create'),
|
||||
usages: [
|
||||
'pnpm create <name>',
|
||||
'pnpm create <name-without-create>',
|
||||
'pnpm create <@scope>',
|
||||
],
|
||||
})
|
||||
}
|
||||
|
||||
const CREATE_PREFIX = 'create-'
|
||||
|
||||
/**
|
||||
* Defines the npm's algorithm for resolving a package name
|
||||
* for create-* packages.
|
||||
*
|
||||
* Example:
|
||||
* - `foo` -> `create-foo`
|
||||
* - `@usr/foo` -> `@usr/create-foo`
|
||||
* - `@usr` -> `@usr/create`
|
||||
*
|
||||
* For more info, see https://docs.npmjs.com/cli/v7/commands/npm-init#description
|
||||
*/
|
||||
function convertToCreateName (packageName: string) {
|
||||
if (packageName.startsWith('@')) {
|
||||
const [scope, scopedPackage = ''] = packageName.split('/')
|
||||
|
||||
if (scopedPackage === '') {
|
||||
return `${scope}/create`
|
||||
} else {
|
||||
return `${scope}/${ensureCreatePrefixed(scopedPackage)}`
|
||||
}
|
||||
} else {
|
||||
return ensureCreatePrefixed(packageName)
|
||||
}
|
||||
}
|
||||
|
||||
function ensureCreatePrefixed (packageName: string) {
|
||||
if (packageName.startsWith(CREATE_PREFIX)) {
|
||||
return packageName
|
||||
} else {
|
||||
return `${CREATE_PREFIX}${packageName}`
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
import * as create from './create'
|
||||
import * as dlx from './dlx'
|
||||
import * as exec from './exec'
|
||||
import * as restart from './restart'
|
||||
@@ -9,4 +10,4 @@ const test = {
|
||||
..._test,
|
||||
}
|
||||
|
||||
export { dlx, exec, restart, run, test }
|
||||
export { create, dlx, exec, restart, run, test }
|
||||
|
||||
65
packages/plugin-commands-script-runners/test/create.ts
Normal file
65
packages/plugin-commands-script-runners/test/create.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import PnpmError from '@pnpm/error'
|
||||
import { create, dlx } from '../src'
|
||||
|
||||
jest.mock('../src/dlx', () => ({ handler: jest.fn() }))
|
||||
|
||||
beforeEach((dlx.handler as jest.Mock).mockClear)
|
||||
|
||||
it('throws an error if called without arguments', async () => {
|
||||
await expect(create.handler({}, [])).rejects.toThrow(PnpmError)
|
||||
expect(dlx.handler).not.toBeCalled()
|
||||
})
|
||||
|
||||
it(
|
||||
'appends `create-` to an unscoped package that doesn\'t start with `create-`',
|
||||
async () => {
|
||||
await create.handler({}, ['some-app'])
|
||||
expect(dlx.handler).toBeCalledWith({}, ['create-some-app'])
|
||||
|
||||
await create.handler({}, ['create_no_dash'])
|
||||
expect(dlx.handler).toBeCalledWith({}, ['create-create_no_dash'])
|
||||
}
|
||||
)
|
||||
|
||||
it(
|
||||
'does not append `create-` to an unscoped package that starts with `create-`',
|
||||
async () => {
|
||||
await create.handler({}, ['create-some-app'])
|
||||
expect(dlx.handler).toBeCalledWith({}, ['create-some-app'])
|
||||
|
||||
await create.handler({}, ['create-'])
|
||||
expect(dlx.handler).toBeCalledWith({}, ['create-'])
|
||||
}
|
||||
)
|
||||
|
||||
it(
|
||||
'appends `create-` to a scoped package that doesn\'t start with `create-`',
|
||||
async () => {
|
||||
await create.handler({}, ['@scope/some-app'])
|
||||
expect(dlx.handler).toBeCalledWith({}, ['@scope/create-some-app'])
|
||||
|
||||
await create.handler({}, ['@scope/create_no_dash'])
|
||||
expect(dlx.handler).toBeCalledWith({}, ['@scope/create-create_no_dash'])
|
||||
}
|
||||
)
|
||||
|
||||
it(
|
||||
'does not append `create-` to a scoped package that starts with `create-`',
|
||||
async () => {
|
||||
await create.handler({}, ['@scope/create-some-app'])
|
||||
expect(dlx.handler).toBeCalledWith({}, ['@scope/create-some-app'])
|
||||
|
||||
await create.handler({}, ['@scope/create-'])
|
||||
expect(dlx.handler).toBeCalledWith({}, ['@scope/create-'])
|
||||
}
|
||||
)
|
||||
|
||||
it('infers a package name from a plain scope', async () => {
|
||||
await create.handler({}, ['@scope'])
|
||||
expect(dlx.handler).toBeCalledWith({}, ['@scope/create'])
|
||||
})
|
||||
|
||||
it('passes the remaining arguments to `dlx`', async () => {
|
||||
await create.handler({}, ['some-app', 'directory/', '--silent'])
|
||||
expect(dlx.handler).toBeCalledWith({}, ['create-some-app', 'directory/', '--silent'])
|
||||
})
|
||||
@@ -9,6 +9,7 @@ import { outdated } from '@pnpm/plugin-commands-outdated'
|
||||
import { pack, publish } from '@pnpm/plugin-commands-publishing'
|
||||
import { rebuild } from '@pnpm/plugin-commands-rebuild'
|
||||
import {
|
||||
create,
|
||||
dlx,
|
||||
exec,
|
||||
restart,
|
||||
@@ -64,6 +65,7 @@ const commands: Array<{
|
||||
add,
|
||||
audit,
|
||||
bin,
|
||||
create,
|
||||
dlx,
|
||||
env,
|
||||
exec,
|
||||
|
||||
Reference in New Issue
Block a user