-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
pack.ts
135 lines (109 loc) Β· 4.78 KB
/
pack.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import {BaseCommand, WorkspaceRequiredError} from '@yarnpkg/cli';
import {Cache, Configuration, MessageName, Project, StreamReport, Workspace, formatUtils, structUtils, ThrowReport} from '@yarnpkg/core';
import {npath, ppath, xfs} from '@yarnpkg/fslib';
import {Command, Option, Usage} from 'clipanion';
import * as packUtils from '../packUtils';
// eslint-disable-next-line arca/no-default-export
export default class PackCommand extends BaseCommand {
static paths = [
[`pack`],
];
static usage: Usage = Command.Usage({
description: `generate a tarball from the active workspace`,
details: `
This command will turn the active workspace into a compressed archive suitable for publishing. The archive will by default be stored at the root of the workspace (\`package.tgz\`).
If the \`-o,---out\` is set the archive will be created at the specified path. The \`%s\` and \`%v\` variables can be used within the path and will be respectively replaced by the package name and version.
`,
examples: [[
`Create an archive from the active workspace`,
`yarn pack`,
], [
`List the files that would be made part of the workspace's archive`,
`yarn pack --dry-run`,
], [
`Name and output the archive in a dedicated folder`,
`yarn pack --out /artifacts/%s-%v.tgz`,
]],
});
installIfNeeded = Option.Boolean(`--install-if-needed`, false, {
description: `Run a preliminary \`yarn install\` if the package contains build scripts`,
});
dryRun = Option.Boolean(`-n,--dry-run`, false, {
description: `Print the file paths without actually generating the package archive`,
});
json = Option.Boolean(`--json`, false, {
description: `Format the output as an NDJSON stream`,
});
out = Option.String(`-o,--out`, {
description: `Create the archive at the specified path`,
});
// Legacy option
filename = Option.String(`--filename`, {hidden: true});
async execute() {
const configuration = await Configuration.find(this.context.cwd, this.context.plugins);
const {project, workspace} = await Project.find(configuration, this.context.cwd);
if (!workspace)
throw new WorkspaceRequiredError(project.cwd, this.context.cwd);
if (await packUtils.hasPackScripts(workspace)) {
if (this.installIfNeeded) {
await project.install({
cache: await Cache.find(configuration),
report: new ThrowReport(),
});
} else {
await project.restoreInstallState();
}
}
const out = this.out ?? this.filename;
const target = typeof out !== `undefined`
? ppath.resolve(this.context.cwd, interpolateOutputName(out, {workspace}))
: ppath.resolve(workspace.cwd, `package.tgz`);
const report = await StreamReport.start({
configuration,
stdout: this.context.stdout,
json: this.json,
}, async report => {
await packUtils.prepareForPack(workspace, {report}, async () => {
report.reportJson({base: npath.fromPortablePath(workspace.cwd)});
const files = await packUtils.genPackList(workspace);
for (const file of files) {
report.reportInfo(null, npath.fromPortablePath(file));
report.reportJson({location: npath.fromPortablePath(file)});
}
if (!this.dryRun) {
const pack = await packUtils.genPackStream(workspace, files);
const write = xfs.createWriteStream(target);
pack.pipe(write);
await new Promise(resolve => {
write.on(`finish`, resolve);
});
}
});
if (!this.dryRun) {
report.reportInfo(MessageName.UNNAMED, `Package archive generated in ${formatUtils.pretty(configuration, target, formatUtils.Type.PATH)}`);
report.reportJson({output: npath.fromPortablePath(target)});
}
});
return report.exitCode();
}
}
function interpolateOutputName(name: string, {workspace}: {workspace: Workspace}) {
const interpolated = name
.replace(`%s`, prettyWorkspaceIdent(workspace))
.replace(`%v`, prettyWorkspaceVersion(workspace));
return npath.toPortablePath(interpolated);
}
function prettyWorkspaceIdent(workspace: Workspace) {
if (workspace.manifest.name !== null) {
return structUtils.slugifyIdent(workspace.manifest.name);
} else {
return `package`;
}
}
function prettyWorkspaceVersion(workspace: Workspace) {
if (workspace.manifest.version !== null) {
return workspace.manifest.version;
} else {
return `unknown`;
}
}