Skip to content

Commit f81a2d6

Browse files
committed
version 1.0.0
0 parents  commit f81a2d6

7 files changed

Lines changed: 228 additions & 0 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/node_modules

README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# ppack
2+
3+
```
4+
$ node src/cli.js --help
5+
6+
Description
7+
Pack packages using PNPM (supports workspaces)
8+
9+
Usage
10+
$ ppack [dir] [options]
11+
12+
Options
13+
-D, --pack-destination Directory in which ppack will save the tarball
14+
-v, --version Displays current version
15+
-h, --help Displays this message
16+
17+
Examples
18+
$ ppack /path/to/package
19+
$ ppack --pack-destination /tmp
20+
```

package.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"name": "@ionlu/ppack",
3+
"version": "1.0.0",
4+
"description": "Pack packages using PNPM (supports workspaces)",
5+
"main": "src/ppack.js",
6+
"author": "Daniel Duton <daniel@ion.lu>",
7+
"license": "MIT",
8+
"bin": {
9+
"ppack": "src/cli.js"
10+
},
11+
"devDependencies": {
12+
"pnpm": "^6.32.3"
13+
},
14+
"peerDependencies": {
15+
"pnpm": "^6.32.3"
16+
},
17+
"dependencies": {
18+
"fs-extra": "^10.0.1",
19+
"sade": "^1.8.1"
20+
}
21+
}

pnpm-lock.yaml

Lines changed: 59 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/cli.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
const path = require('path')
2+
const sade = require('sade')
3+
const { readJson } = require('fs-extra')
4+
const ppack = require('./ppack.js')
5+
6+
readJson(path.resolve(__dirname, '../package.json'))
7+
.then(package => {
8+
sade('ppack [dir]', true)
9+
.version(package.version)
10+
.describe(package.description)
11+
.example('/path/to/package')
12+
.example('--pack-destination /tmp')
13+
.option('-D, --pack-destination', 'Directory in which ppack will save the tarball')
14+
.action((dir, opts) => {
15+
ppack(dir, {
16+
...opts,
17+
log: data => console.log(data)
18+
}).catch(() => { })
19+
})
20+
.parse(process.argv)
21+
})

src/execute.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
const { spawn } = require('child_process')
2+
3+
const execute = function execute (command, args, opts) {
4+
return new Promise((resolve, reject) => {
5+
let stdout = ''
6+
let stderr = ''
7+
8+
const child = spawn(command, args, opts)
9+
10+
child.stdout.on('data', data => {
11+
stdout += data
12+
})
13+
child.stderr.on('data', data => {
14+
stderr += data
15+
})
16+
17+
child.on('error', err => {
18+
reject(err)
19+
})
20+
21+
child.on('close', code => {
22+
if (code === 0) {
23+
resolve(stdout.trim())
24+
} else {
25+
reject(stderr.trim())
26+
}
27+
})
28+
})
29+
}
30+
31+
module.exports = execute

src/ppack.js

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
const path = require('path')
2+
const os = require('os')
3+
const { readJson, writeJson, copy, rm, ensureDir } = require('fs-extra')
4+
const execute = require('./execute.js')
5+
6+
const ppack = async function ppack (dir, opts) {
7+
const packageFolder = dir ? path.resolve(dir) : process.cwd()
8+
const targetFolder = opts['pack-destination'] ? path.resolve(opts['pack-destination']) : packageFolder
9+
const tempFolder = path.resolve(os.tmpdir(), '_ppack_' + Math.random().toString(36).replace(/[^a-z]+/g, ''))
10+
const log = opts.log || (() => { })
11+
12+
// load package file
13+
const packageFile = path.resolve(packageFolder, 'package.json')
14+
const package = await readJson(packageFile)
15+
16+
log(`Packing package ${package.name}:${package.version} started`)
17+
18+
try {
19+
// copy package to temp folder
20+
await copy(packageFolder, tempFolder, {
21+
filter: src => {
22+
return !src.match('node_modules')
23+
}
24+
})
25+
26+
// set pnpm config
27+
await execute('pnpm', ['config', '--location', 'project', 'set', 'shamefully-hoist=true'], {
28+
cwd: tempFolder
29+
})
30+
31+
// update package info
32+
package.bundledDependencies = true
33+
if (package.dependencies) {
34+
await Promise.all(
35+
Object.entries(package.dependencies).map(
36+
async ([name, version]) => {
37+
if (version.match(/^workspace:/)) {
38+
const path = await execute('pnpm', ['--filter', name, 'exec', 'pwd'])
39+
package.dependencies[name] = `link:${path}`
40+
}
41+
}
42+
)
43+
)
44+
}
45+
await writeJson(path.resolve(tempFolder, 'package.json'), package)
46+
47+
// install packages
48+
await execute('pnpm', ['i', '--prefer-offline'], {
49+
cwd: tempFolder
50+
})
51+
52+
// remove dev packages
53+
await execute('pnpm', ['prune'], {
54+
cwd: tempFolder
55+
})
56+
57+
// create targetFolder
58+
await ensureDir(targetFolder)
59+
60+
// create the tarball
61+
await execute('pnpm', ['pack', '--pack-destination', path.resolve(targetFolder)], {
62+
cwd: tempFolder
63+
})
64+
65+
log(`Packing package ${package.name}:${package.version} successful`)
66+
} catch (err) {
67+
log(`Packing package ${package.name}:${package.version} failed with error ${err.message}`)
68+
throw err
69+
} finally {
70+
// cleanup
71+
await rm(tempFolder, { recursive: true, force: true });
72+
}
73+
}
74+
75+
module.exports = ppack

0 commit comments

Comments
 (0)