feat: publish and pack support package.{json5,yaml}

PR #1809
ref #1803
This commit is contained in:
Zoltan Kochan
2019-05-04 16:58:00 +03:00
committed by GitHub
parent bb3fd532fb
commit c043e5c478
13 changed files with 215 additions and 38 deletions

View File

@@ -84,7 +84,8 @@
"text-table": "0.2.0",
"tree-kill": "1.2.1",
"update-notifier": "2.5.0",
"version-selector-type": "2.0.1"
"version-selector-type": "2.0.1",
"write-json-file": "3.2.0"
},
"devDependencies": {
"@pnpm/assert-project": "link:../../privatePackages/assert-project",
@@ -127,7 +128,6 @@
"ts-node": "8.1.0",
"tslint": "5.16.0",
"typescript": "3.4.5",
"write-json-file": "3.2.0",
"write-pkg": "4.0.0",
"write-yaml-file": "2.0.0"
},

View File

@@ -37,11 +37,9 @@ if (argv.includes('--help') || argv.includes('-h') || argv.includes('--h')) {
case 'login':
case 'logout':
case 'owner':
case 'pack':
case 'ping':
case 'prefix':
case 'profile':
case 'publish':
case 'repo':
case 's':
case 'se':
@@ -78,5 +76,6 @@ async function runPnpm () {
async function passThruToNpm () {
const runNpm = (await import('../cmd/runNpm')).default
runNpm(argv)
const { status } = runNpm(argv)
process.exit(status)
}

View File

@@ -215,6 +215,20 @@ function getHelpText (command: string) {
Removes extraneous packages
`
case 'pack':
return stripIndent`
pnpm pack
Creates a compressed gzip archive of package dependencies.
`
case 'publish':
return stripIndent`
pnpm publish [<tarball>|<folder>] [--tag <tag>] [--access <public|restricted>]
Publishes a package to the npm registry.
`
case 'install-test':
return stripIndent`
pnpm install-test
@@ -473,7 +487,9 @@ function getHelpText (command: string) {
- link
- list
- outdated
- pack
- prune
- publish
- rebuild
- restart
- root

View File

@@ -6,6 +6,7 @@ import link from './link'
import list from './list'
import outdated from './outdated'
import prune from './prune'
import publish, { pack } from './publish'
import rebuild from './rebuild'
import recursive from './recursive'
import root from './root'
@@ -24,7 +25,9 @@ export default {
link,
list,
outdated,
pack,
prune,
publish,
rebuild,
recursive,
restart,

View File

@@ -0,0 +1,56 @@
import readImporterManifest from '@pnpm/read-importer-manifest'
import path = require('path')
import rimraf = require('rimraf-then')
import writeJsonFile = require('write-json-file')
import { PnpmOptions } from '../types'
import runNpm from './runNpm'
export default async function (
args: string[],
opts: PnpmOptions,
command: string,
) {
if (args.length && args[0].endsWith('.tgz')) {
await runNpm(['publish', ...args])
return
}
const prefix = args.length && args[0] || process.cwd()
let _status!: number
await fakeRegularManifest(prefix, async () => {
const { status } = await runNpm(['publish', ...opts.argv.original.slice(1)])
_status = status
})
if (_status !== 0) {
process.exit(_status)
}
}
export async function pack (
args: string[],
opts: PnpmOptions,
command: string,
) {
let _status!: number
await fakeRegularManifest(opts.prefix, async () => {
const { status } = await runNpm(['pack', ...opts.argv.original.slice(1)])
_status = status
})
if (_status !== 0) {
process.exit(_status)
}
}
async function fakeRegularManifest (prefix: string, fn: () => Promise<void>) {
const { fileName, manifest, writeImporterManifest } = await readImporterManifest(prefix)
const exoticManifestFormat = fileName !== 'package.json'
if (exoticManifestFormat) {
await rimraf(path.join(prefix, fileName))
await writeJsonFile(path.join(prefix, 'package.json'), manifest)
}
await fn()
if (exoticManifestFormat) {
await rimraf(path.join(prefix, 'package.json'))
await writeImporterManifest(manifest, true)
}
}

View File

@@ -1,10 +1,9 @@
import { sync as runScriptSync } from '../runScript'
export default function runNpm (args: string[]) {
const result = runScriptSync('npm', args, {
return runScriptSync('npm', args, {
cwd: process.cwd(),
stdio: 'inherit',
userAgent: undefined,
})
process.exit(result.status)
}

View File

@@ -37,7 +37,9 @@ type CANONICAL_COMMAND_NAMES = 'help'
| 'link'
| 'list'
| 'outdated'
| 'pack'
| 'prune'
| 'publish'
| 'rebuild'
| 'recursive'
| 'restart'
@@ -59,7 +61,9 @@ const supportedCmds = new Set<CANONICAL_COMMAND_NAMES>([
'uninstall',
'update',
'link',
'pack',
'prune',
'publish',
'install-test',
'restart',
'server',

View File

@@ -1,24 +0,0 @@
import { ImporterManifest } from '@pnpm/types'
import loadJsonFile = require('load-json-file')
import path = require('path')
export async function readImporterManifest (filename: string) {
return loadJsonFile<ImporterManifest>(filename)
}
export async function readImporterManifestFromDir (dir: string) {
return readImporterManifest(path.join(dir, 'package.json'))
}
export async function safeReadImporterManifest (filename: string): Promise<ImporterManifest | null> {
try {
return await readImporterManifest(filename)
} catch (err) {
if (err['code'] !== 'ENOENT') throw err
return null
}
}
export function safeReadImporterManifestFromDir (dir: string) {
return safeReadImporterManifest(path.join(dir, 'package.json'))
}

View File

@@ -6,7 +6,9 @@ import './link'
import './list'
import './monorepo'
import './outdated'
import './pack'
import './prune'
import './publish'
import './rebuild'
import './recursive'
import './root'

View File

@@ -0,0 +1,49 @@
import prepare, {
prepareWithYamlManifest,
prepareWithJson5Manifest,
} from '@pnpm/prepare'
import exists = require('path-exists')
import tape = require('tape')
import promisifyTape from 'tape-promise'
import { execPnpm } from './utils'
const test = promisifyTape(tape)
const testOnly = promisifyTape(tape.only)
test('pack: package with package.json', async (t: tape.Test) => {
prepare(t, {
name: 'test-publish-package.json',
version: '0.0.0',
})
await execPnpm('pack')
t.ok(await exists('test-publish-package.json-0.0.0.tgz'))
t.ok(await exists('package.json'))
})
test('pack: package with package.yaml', async (t: tape.Test) => {
prepareWithYamlManifest(t, {
name: 'test-publish-package.yaml',
version: '0.0.0',
})
await execPnpm('pack')
t.ok(await exists('test-publish-package.yaml-0.0.0.tgz'))
t.ok(await exists('package.yaml'))
t.notOk(await exists('package.json'))
})
test('pack: package with package.json5', async (t: tape.Test) => {
prepareWithJson5Manifest(t, {
name: 'test-publish-package.json5',
version: '0.0.0',
})
await execPnpm('pack')
t.ok(await exists('test-publish-package.json5-0.0.0.tgz'))
t.ok(await exists('package.json5'))
t.notOk(await exists('package.json'))
})

View File

@@ -0,0 +1,64 @@
import prepare, {
prepareWithYamlManifest,
prepareWithJson5Manifest,
} from '@pnpm/prepare'
import exists = require('path-exists')
import tape = require('tape')
import promisifyTape from 'tape-promise'
import { execPnpm } from './utils'
const test = promisifyTape(tape)
const testOnly = promisifyTape(tape.only)
const CREDENTIALS = [
'--//localhost:4873/:username=username',
`--//localhost:4873/:_password=${Buffer.from('password').toString('base64')}`,
'--//localhost:4873/:email=foo@bar.net',
]
test('publish: package with package.json', async (t: tape.Test) => {
prepare(t, {
name: 'test-publish-package.json',
version: '0.0.0',
})
await execPnpm('publish', ...CREDENTIALS)
})
test('publish: package with package.yaml', async (t: tape.Test) => {
prepareWithYamlManifest(t, {
name: 'test-publish-package.yaml',
version: '0.0.0',
})
await execPnpm('publish', ...CREDENTIALS)
t.ok(await exists('package.yaml'))
t.notOk(await exists('package.json'))
})
test('publish: package with package.json5', async (t: tape.Test) => {
prepareWithJson5Manifest(t, {
name: 'test-publish-package.json5',
version: '0.0.0',
})
await execPnpm('publish', ...CREDENTIALS)
t.ok(await exists('package.json5'))
t.notOk(await exists('package.json'))
})
test('publish: package with package.json5 running publish from different folder', async (t: tape.Test) => {
prepareWithJson5Manifest(t, {
name: 'test-publish-package.json5',
version: '0.0.1',
})
process.chdir('..')
await execPnpm('publish', 'project', ...CREDENTIALS)
t.ok(await exists('project/package.json5'))
t.notOk(await exists('project/package.json'))
})

View File

@@ -14,15 +14,19 @@ import {
const stat = promisify(fs.stat)
type WriteImporterManifest = (manifest: ImporterManifest, force?: boolean) => Promise<void>
export default async function readImporterManifest (importerDir: string): Promise<{
fileName: string,
manifest: ImporterManifest
writeImporterManifest: (manifest: ImporterManifest) => Promise<void>
writeImporterManifest: WriteImporterManifest
}> {
const result = await tryReadImporterManifest(importerDir)
if (result.manifest !== null) {
return result as {
fileName: string,
manifest: ImporterManifest
writeImporterManifest: (manifest: ImporterManifest) => Promise<void>
writeImporterManifest: WriteImporterManifest
}
}
const err = new Error(`No package.json (or package.yaml, or package.json5) was found in "${importerDir}".`)
@@ -36,14 +40,16 @@ export async function readImporterManifestOnly (importerDir: string): Promise<Im
}
export async function tryReadImporterManifest (importerDir: string): Promise<{
fileName: string,
manifest: ImporterManifest | null
writeImporterManifest: (manifest: ImporterManifest) => Promise<void>
writeImporterManifest: WriteImporterManifest
}> {
try {
const manifestPath = path.join(importerDir, 'package.json')
const { data, text } = await readJsonFile(manifestPath)
const { indent } = detectIndent(text)
return {
fileName: 'package.json',
manifest: data,
writeImporterManifest: createManifestWriter({
indent,
@@ -59,6 +65,7 @@ export async function tryReadImporterManifest (importerDir: string): Promise<{
const { data, text } = await readJson5File(manifestPath)
const { indent } = detectIndent(text)
return {
fileName: 'package.json5',
manifest: data,
writeImporterManifest: createManifestWriter({
indent,
@@ -73,6 +80,7 @@ export async function tryReadImporterManifest (importerDir: string): Promise<{
const manifestPath = path.join(importerDir, 'package.yaml')
const manifest = await readPackageYaml(manifestPath)
return {
fileName: 'package.yaml',
manifest,
writeImporterManifest: createManifestWriter({ initialManifest: manifest, manifestPath }),
}
@@ -95,6 +103,7 @@ export async function tryReadImporterManifest (importerDir: string): Promise<{
}
const filePath = path.join(importerDir, 'package.json')
return {
fileName: 'package.json',
manifest: null,
writeImporterManifest: writeImporterManifest.bind(null, filePath),
}
@@ -148,10 +157,10 @@ function createManifestWriter (
indent?: string | number | null | undefined,
manifestPath: string,
},
): ((manifest: ImporterManifest) => Promise<void>) {
): (WriteImporterManifest) {
const stringifiedInitialManifest = JSON.stringify(opts.initialManifest)
return async (updatedManifest: ImporterManifest) => {
if (stringifiedInitialManifest !== JSON.stringify(updatedManifest)) {
return async (updatedManifest: ImporterManifest, force?: boolean) => {
if (force === true || stringifiedInitialManifest !== JSON.stringify(updatedManifest)) {
return writeImporterManifest(opts.manifestPath, updatedManifest, { indent: opts.indent })
}
}

2
pnpm-lock.yaml generated
View File

@@ -1448,6 +1448,7 @@ importers:
tree-kill: 1.2.1
update-notifier: 2.5.0
version-selector-type: 2.0.1
write-json-file: 3.2.0
devDependencies:
'@pnpm/assert-project': 'link:../../privatePackages/assert-project'
'@pnpm/lockfile-types': 'link:../lockfile-types'
@@ -1489,7 +1490,6 @@ importers:
ts-node: 8.1.0_typescript@3.4.5
tslint: 5.16.0_typescript@3.4.5
typescript: 3.4.5
write-json-file: 3.2.0
write-pkg: 4.0.0
write-yaml-file: 2.0.0
specifiers: