Skip to content

Commit

Permalink
fix: npm pack filename on scoped packages (#5894)
Browse files Browse the repository at this point in the history
When running `npm pack` on a scoped package, the file name would
be incorrect, since the `@` character should be removed, and the
`/` character be replaced with a `-` character
  • Loading branch information
HenryNguyen5 committed Nov 30, 2022
1 parent 40f2c21 commit ffbdea2
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 3 deletions.
4 changes: 3 additions & 1 deletion lib/utils/tar.js
Expand Up @@ -120,7 +120,9 @@ const getContents = async (manifest, tarball) => {
unpackedSize: totalEntrySize,
shasum,
integrity: ssri.parse(integrity.sha512[0]),
filename: `${manifest.name}-${manifest.version}.tgz`,
// @scope/packagename.tgz => scope-packagename.tgz
// we can safely use these global replace rules due to npm package naming rules
filename: `${manifest.name.replace('@', '').replace('/', '-')}-${manifest.version}.tgz`,
files: uppers.concat(others),
entryCount: totalEntries,
bundled: Array.from(bundled),
Expand Down
30 changes: 30 additions & 0 deletions tap-snapshots/test/lib/commands/pack.js.test.cjs
Expand Up @@ -56,6 +56,36 @@ Array [
]
`

exports[`test/lib/commands/pack.js TAP should log scoped package output as valid json > logs pack contents 1`] = `
Array []
`

exports[`test/lib/commands/pack.js TAP should log scoped package output as valid json > outputs as json 1`] = `
Array [
Array [
Object {
"bundled": Array [],
"entryCount": 1,
"filename": "myscope-test-package-1.0.0.tgz",
"files": Array [
Object {
"mode": 420,
"path": "package.json",
"size": 50,
},
],
"id": "@myscope/test-package@1.0.0",
"integrity": "sha512-bUu8iTm2E5DZMrwKeyx963K6ViEmaFocXh75EujgI+FHSaJeqvObcdk1KFwdx8CbOgsfNHEvWNQw/bONAJsoNw==",
"name": "@myscope/test-package",
"shasum": "7e6eb2e1ca46bed6b8fa8e144e0fcd1b22fe2d98",
"size": 145,
"unpackedSize": 50,
"version": "1.0.0",
},
],
]
`

exports[`test/lib/commands/pack.js TAP should pack current directory with no arguments > logs pack contents 1`] = `
Array [
undefined,
Expand Down
4 changes: 2 additions & 2 deletions tap-snapshots/test/lib/commands/publish.js.test.cjs
Expand Up @@ -136,7 +136,7 @@ Array [
String(
name: @npm/test-package
version: 1.0.0
filename: @npm/test-package-1.0.0.tgz
filename: npm-test-package-1.0.0.tgz
package size: 147 B
unpacked size: 55 B
shasum:{sha}
Expand Down Expand Up @@ -191,7 +191,7 @@ Array [
String(
name: @npm/test-package
version: 1.0.0
filename: @npm/test-package-1.0.0.tgz
filename: npm-test-package-1.0.0.tgz
package size: 147 B
unpacked size: 55 B
shasum:{sha}
Expand Down
30 changes: 30 additions & 0 deletions tap-snapshots/test/lib/utils/tar.js.test.cjs
Expand Up @@ -33,4 +33,34 @@ own files: 5
total files: 5
`

exports[`test/lib/utils/tar.js TAP should log tarball contents of a scoped package > must match snapshot 1`] = `
package: @myscope/my-cool-pkg@1.0.0
=== Tarball Contents ===
4B cat
4B chai
4B dog
123B package.json
=== Bundled Dependencies ===
bundle-dep
=== Tarball Details ===
name: @myscope/my-cool-pkg
version: 1.0.0
filename: myscope-my-cool-pkg-1.0.0.tgz
package size: 280 B
unpacked size: 135 B
shasum: a4f63307f2211e8fde72cd39bc1176b4fe997b71
integrity: sha512-b+RavF8JiErJt[...]YpwkJc8ycaabA==
bundled deps: 1
bundled files: 0
own files: 5
total files: 5
`
18 changes: 18 additions & 0 deletions test/lib/commands/pack.js
Expand Up @@ -77,6 +77,24 @@ t.test('should log output as valid json', async t => {
t.ok(fs.statSync(path.resolve(npm.prefix, filename)))
})

t.test('should log scoped package output as valid json', async t => {
const { npm, outputs, logs } = await loadMockNpm(t, {
prefixDir: {
'package.json': JSON.stringify({
name: '@myscope/test-package',
version: '1.0.0',
}),
},
})
process.chdir(npm.prefix)
npm.config.set('json', true)
await npm.exec('pack', [])
const filename = 'myscope-test-package-1.0.0.tgz'
t.matchSnapshot(outputs.map(JSON.parse), 'outputs as json')
t.matchSnapshot(logs.notice.map(([, m]) => m), 'logs pack contents')
t.ok(fs.statSync(path.resolve(npm.prefix, filename)))
})

t.test('dry run', async t => {
const { npm, outputs, logs } = await loadMockNpm(t, {
prefixDir: {
Expand Down
32 changes: 32 additions & 0 deletions test/lib/utils/tar.js
Expand Up @@ -51,6 +51,38 @@ t.test('should log tarball contents', async (t) => {
t.matchSnapshot(printLogs(tarballContents))
})

t.test('should log tarball contents of a scoped package', async (t) => {
const testDir = t.testdir({
'package.json': JSON.stringify({
name: '@myscope/my-cool-pkg',
version: '1.0.0',
bundleDependencies: [
'bundle-dep',
],
dependencies: {
'bundle-dep': '1.0.0',
},
}),
cat: 'meow',
chai: 'blub',
dog: 'woof',
node_modules: {
'bundle-dep': {
'package.json': '',
},
},
})

const tarball = await pack(testDir)
const tarballContents = await getContents({
_id: '1',
name: '@myscope/my-cool-pkg',
version: '1.0.0',
}, tarball)

t.matchSnapshot(printLogs(tarballContents))
})

t.test('should log tarball contents with unicode', async (t) => {
const { logTar } = mockTar({
notice: (str) => {
Expand Down

0 comments on commit ffbdea2

Please sign in to comment.