fork-version 1.4.13 → 1.4.48
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +423 -0
- package/README.md +2 -0
- package/dist/chunk-S2VPLFG2.js +798 -0
- package/dist/chunk-S2VPLFG2.js.map +1 -0
- package/dist/chunk-UJKGEPR3.cjs +821 -0
- package/dist/chunk-UJKGEPR3.cjs.map +1 -0
- package/dist/cli.cjs +69 -11
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.d.cts +0 -0
- package/dist/cli.d.ts +0 -0
- package/dist/cli.js +69 -11
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +27 -11
- package/dist/index.d.cts +129 -96
- package/dist/index.d.ts +129 -96
- package/dist/index.js +1 -1
- package/package.json +90 -77
- package/dist/chunk-4VUFHLIF.cjs +0 -718
- package/dist/chunk-4VUFHLIF.cjs.map +0 -1
- package/dist/chunk-Z5YLEJGR.js +0 -697
- package/dist/chunk-Z5YLEJGR.js.map +0 -1
|
@@ -0,0 +1,798 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { resolve, parse } from 'path';
|
|
3
|
+
import JoyCon from 'joycon';
|
|
4
|
+
import { bundleRequire } from 'bundle-require';
|
|
5
|
+
import meow from 'meow';
|
|
6
|
+
import conventionalChangelogConfigSpec from 'conventional-changelog-config-spec';
|
|
7
|
+
import semver3 from 'semver';
|
|
8
|
+
import conventionalRecommendedBump from 'conventional-recommended-bump';
|
|
9
|
+
import gitSemverTags from 'git-semver-tags';
|
|
10
|
+
import { writeFileSync, lstatSync, readFileSync } from 'fs';
|
|
11
|
+
import conventionalChangelog from 'conventional-changelog';
|
|
12
|
+
import { execFile } from 'child_process';
|
|
13
|
+
import detectIndent from 'detect-indent';
|
|
14
|
+
import { detectNewline } from 'detect-newline';
|
|
15
|
+
|
|
16
|
+
// src/config/schema.ts
|
|
17
|
+
var ChangelogPresetConfigSchema = z.object({
|
|
18
|
+
/**
|
|
19
|
+
* An array of `type` objects representing the explicitly supported commit message types,
|
|
20
|
+
* and whether they should show up in generated `CHANGELOG`s.
|
|
21
|
+
*/
|
|
22
|
+
types: z.array(
|
|
23
|
+
z.object({
|
|
24
|
+
type: z.string(),
|
|
25
|
+
section: z.string().optional(),
|
|
26
|
+
hidden: z.boolean().optional()
|
|
27
|
+
})
|
|
28
|
+
),
|
|
29
|
+
/**
|
|
30
|
+
* A URL representing a specific commit at a hash.
|
|
31
|
+
* @default "{{host}}/{{owner}}/{{repository}}/commit/{{hash}}"
|
|
32
|
+
*/
|
|
33
|
+
commitUrlFormat: z.string(),
|
|
34
|
+
/**
|
|
35
|
+
* A URL representing the comparison between two git SHAs.
|
|
36
|
+
* @default "{{host}}/{{owner}}/{{repository}}/compare/{{previousTag}}...{{currentTag}}"
|
|
37
|
+
*/
|
|
38
|
+
compareUrlFormat: z.string(),
|
|
39
|
+
/**
|
|
40
|
+
* A URL representing the issue format (allowing a different URL format to be swapped in
|
|
41
|
+
* for Gitlab, Bitbucket, etc).
|
|
42
|
+
* @default "{{host}}/{{owner}}/{{repository}}/issues/{{id}}"
|
|
43
|
+
*/
|
|
44
|
+
issueUrlFormat: z.string(),
|
|
45
|
+
/**
|
|
46
|
+
* A URL representing the a user's profile URL on GitHub, Gitlab, etc. This URL is used
|
|
47
|
+
* for substituting @bcoe with https://github.com/bcoe in commit messages.
|
|
48
|
+
* @default "{{host}}/{{user}}"
|
|
49
|
+
*/
|
|
50
|
+
userUrlFormat: z.string(),
|
|
51
|
+
/**
|
|
52
|
+
* A string to be used to format the auto-generated release commit message.
|
|
53
|
+
* @default "chore(release): {{currentTag}}"
|
|
54
|
+
*/
|
|
55
|
+
releaseCommitMessageFormat: z.string(),
|
|
56
|
+
/**
|
|
57
|
+
* An array of prefixes used to detect references to issues
|
|
58
|
+
* @default ["#"]
|
|
59
|
+
*/
|
|
60
|
+
issuePrefixes: z.array(z.string())
|
|
61
|
+
});
|
|
62
|
+
var ForkConfigSchema = z.object({
|
|
63
|
+
/**
|
|
64
|
+
* The path fork-version will run from.
|
|
65
|
+
* @default
|
|
66
|
+
* ```js
|
|
67
|
+
* process.cwd()
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
path: z.string(),
|
|
71
|
+
/**
|
|
72
|
+
* Name of the changelog file.
|
|
73
|
+
* @default "CHANGELOG.md"
|
|
74
|
+
*/
|
|
75
|
+
changelog: z.string(),
|
|
76
|
+
/**
|
|
77
|
+
* The header to be used in the changelog.
|
|
78
|
+
* @default
|
|
79
|
+
* ```markdown
|
|
80
|
+
* # Changelog
|
|
81
|
+
*
|
|
82
|
+
* All notable changes to this project will be documented in this file. See [fork-version](https://github.com/eglavin/fork-version) for commit guidelines.
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
header: z.string(),
|
|
86
|
+
/**
|
|
87
|
+
* Files to be updated.
|
|
88
|
+
* @default
|
|
89
|
+
* ```js
|
|
90
|
+
* ["bower.json", "manifest.json", "npm-shrinkwrap.json", "package-lock.json", "package.json"]
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
files: z.array(z.string()),
|
|
94
|
+
/**
|
|
95
|
+
* Specify a prefix for the git tag fork-version will create.
|
|
96
|
+
*
|
|
97
|
+
* For instance if your version tag is prefixed by "version/" instead of "v" you have to specify
|
|
98
|
+
* `tagPrefix: "version/"`.
|
|
99
|
+
*
|
|
100
|
+
* `tagPrefix` can also be used for a monorepo environment where you might want to deploy
|
|
101
|
+
* multiple package from the same repository. In this case you can specify a prefix for
|
|
102
|
+
* each package:
|
|
103
|
+
*
|
|
104
|
+
* | Value | Tag Created |
|
|
105
|
+
* |:-------------------------|:------------------------------|
|
|
106
|
+
* | "" | `1.2.3` |
|
|
107
|
+
* | "version/" | `version/1.2.3` |
|
|
108
|
+
* | "@eglavin/fork-version-" | `@eglavin/fork-version-1.2.3` |
|
|
109
|
+
*
|
|
110
|
+
* @example "", "version/", "@eglavin/fork-version-"
|
|
111
|
+
* @default "v"
|
|
112
|
+
*/
|
|
113
|
+
tagPrefix: z.string(),
|
|
114
|
+
/**
|
|
115
|
+
* Make a pre-release with optional label, if value is a string it will be used as the
|
|
116
|
+
* pre-release tag.
|
|
117
|
+
*
|
|
118
|
+
* | Value | Version |
|
|
119
|
+
* |:----------|:----------------|
|
|
120
|
+
* | true | "1.2.3-0" |
|
|
121
|
+
* | "alpha" | "1.2.3-alpha-0" |
|
|
122
|
+
* | "beta" | "1.2.3-beta-0" |
|
|
123
|
+
*
|
|
124
|
+
* @example true, "alpha", "beta", "rc"
|
|
125
|
+
* @default undefined
|
|
126
|
+
*/
|
|
127
|
+
preReleaseTag: z.string().or(z.boolean()).optional(),
|
|
128
|
+
/**
|
|
129
|
+
* Commit all staged changes, not just files updated by fork-version.
|
|
130
|
+
* @default false
|
|
131
|
+
*/
|
|
132
|
+
commitAll: z.boolean(),
|
|
133
|
+
/**
|
|
134
|
+
* If set we'll log debug information.
|
|
135
|
+
* @default false
|
|
136
|
+
*/
|
|
137
|
+
debug: z.boolean(),
|
|
138
|
+
/**
|
|
139
|
+
* If true, no output will be written to disk or committed.
|
|
140
|
+
* @default false
|
|
141
|
+
*/
|
|
142
|
+
dryRun: z.boolean(),
|
|
143
|
+
/**
|
|
144
|
+
* If true and we cant find a version in the list of `files`, we'll fallback
|
|
145
|
+
* and attempt to use the latest git tag to get the current version.
|
|
146
|
+
* @default true
|
|
147
|
+
*/
|
|
148
|
+
gitTagFallback: z.boolean(),
|
|
149
|
+
/**
|
|
150
|
+
* If set, we'll gather information about the current version and exit.
|
|
151
|
+
* @default false
|
|
152
|
+
*/
|
|
153
|
+
inspectVersion: z.boolean(),
|
|
154
|
+
/**
|
|
155
|
+
* Should we sign the git commit using GPG?
|
|
156
|
+
* @see {@link https://git-scm.com/docs/git-commit#Documentation/git-commit.txt--Sltkeyidgt GPG Sign Commits}
|
|
157
|
+
* @default false
|
|
158
|
+
*/
|
|
159
|
+
sign: z.boolean(),
|
|
160
|
+
/**
|
|
161
|
+
* If true, no output will be written to stdout.
|
|
162
|
+
* @default false
|
|
163
|
+
*/
|
|
164
|
+
silent: z.boolean(),
|
|
165
|
+
/**
|
|
166
|
+
* If true, allow git to run git commit hooks.
|
|
167
|
+
* @default false
|
|
168
|
+
*/
|
|
169
|
+
verify: z.boolean(),
|
|
170
|
+
/**
|
|
171
|
+
* If set, we'll use this version number instead of trying to find a version from the list of `files`.
|
|
172
|
+
* @example "1.0.0"
|
|
173
|
+
* @default undefined
|
|
174
|
+
*/
|
|
175
|
+
currentVersion: z.string().optional(),
|
|
176
|
+
/**
|
|
177
|
+
* If set, we'll attempt to update the version number to this version, instead of incrementing
|
|
178
|
+
* using "conventional-commit".
|
|
179
|
+
* @example "2.0.0"
|
|
180
|
+
* @default undefined
|
|
181
|
+
*/
|
|
182
|
+
nextVersion: z.string().optional(),
|
|
183
|
+
/**
|
|
184
|
+
* Override the default conventional-changelog preset configuration.
|
|
185
|
+
*/
|
|
186
|
+
changelogPresetConfig: ChangelogPresetConfigSchema.partial()
|
|
187
|
+
});
|
|
188
|
+
function defineConfig(config) {
|
|
189
|
+
return config;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// src/config/defaults.ts
|
|
193
|
+
var DEFAULT_CONFIG = {
|
|
194
|
+
path: process.cwd(),
|
|
195
|
+
changelog: "CHANGELOG.md",
|
|
196
|
+
files: [
|
|
197
|
+
"package.json",
|
|
198
|
+
"package-lock.json",
|
|
199
|
+
"npm-shrinkwrap.json",
|
|
200
|
+
"manifest.json",
|
|
201
|
+
// Chrome extensions
|
|
202
|
+
"bower.json"
|
|
203
|
+
],
|
|
204
|
+
header: `# Changelog
|
|
205
|
+
|
|
206
|
+
All notable changes to this project will be documented in this file. See [fork-version](https://github.com/eglavin/fork-version) for commit guidelines.
|
|
207
|
+
`,
|
|
208
|
+
tagPrefix: "v",
|
|
209
|
+
commitAll: false,
|
|
210
|
+
debug: false,
|
|
211
|
+
dryRun: false,
|
|
212
|
+
gitTagFallback: true,
|
|
213
|
+
inspectVersion: false,
|
|
214
|
+
sign: false,
|
|
215
|
+
silent: false,
|
|
216
|
+
verify: false,
|
|
217
|
+
changelogPresetConfig: {}
|
|
218
|
+
};
|
|
219
|
+
function getCliArguments() {
|
|
220
|
+
return meow(
|
|
221
|
+
`
|
|
222
|
+
Usage:
|
|
223
|
+
$ fork-version [options]
|
|
224
|
+
|
|
225
|
+
Options:
|
|
226
|
+
--path [Default: process.cwd()]
|
|
227
|
+
The path fork-version will run from.
|
|
228
|
+
--changelog [Default: "CHANGELOG.md"]
|
|
229
|
+
Name of the changelog file.
|
|
230
|
+
--header, -H
|
|
231
|
+
The header to be used in the changelog.
|
|
232
|
+
--files, --file, -F [Default: ["bower.json", "manifest.json", "npm-shrinkwrap.json", "package-lock.json", "package.json"]]
|
|
233
|
+
Files to be updated.
|
|
234
|
+
--tag-prefix [Default: "v"]
|
|
235
|
+
Specify a prefix for the git tag "fork-version" will create.
|
|
236
|
+
--pre-release-tag [Default: undefined]
|
|
237
|
+
Make a pre-release with optional label, If value is a string it
|
|
238
|
+
will be used as the pre-release tag.
|
|
239
|
+
|
|
240
|
+
--commit-all
|
|
241
|
+
Commit all staged changes, not just files updated by fork-version.
|
|
242
|
+
--debug
|
|
243
|
+
If true, we'll output debug information.
|
|
244
|
+
--dry-run
|
|
245
|
+
If true, no output will be written to disk or committed.
|
|
246
|
+
--git-tag-fallback [Default: true]
|
|
247
|
+
If true and we cant find a version in the given files, we'll fallback
|
|
248
|
+
and attempt to use the latest git tag for the current version.
|
|
249
|
+
--inspect-version
|
|
250
|
+
If set, we'll gather information about the current version and exit.
|
|
251
|
+
--sign
|
|
252
|
+
Should we sign the git commit using GPG?
|
|
253
|
+
--silent
|
|
254
|
+
If true, no output will be written to stdout.
|
|
255
|
+
--verify
|
|
256
|
+
If true, allow git to run git commit hooks.
|
|
257
|
+
|
|
258
|
+
--current-version
|
|
259
|
+
If set, we'll use this version number instead of trying to find a
|
|
260
|
+
version in a "file".
|
|
261
|
+
--next-version
|
|
262
|
+
If set, we'll attempt to update the version number to this version,
|
|
263
|
+
instead of incrementing using "conventional-commit".
|
|
264
|
+
`,
|
|
265
|
+
{
|
|
266
|
+
importMeta: import.meta,
|
|
267
|
+
flags: {
|
|
268
|
+
path: { type: "string", default: process.cwd() },
|
|
269
|
+
changelog: { type: "string" },
|
|
270
|
+
header: { type: "string", shortFlag: "H" },
|
|
271
|
+
files: { type: "string", isMultiple: true, aliases: ["file"], shortFlag: "F" },
|
|
272
|
+
tagPrefix: { type: "string" },
|
|
273
|
+
preReleaseTag: { type: "string" },
|
|
274
|
+
commitAll: { type: "boolean" },
|
|
275
|
+
debug: { type: "boolean" },
|
|
276
|
+
dryRun: { type: "boolean" },
|
|
277
|
+
gitTagFallback: { type: "boolean" },
|
|
278
|
+
inspectVersion: { type: "boolean" },
|
|
279
|
+
sign: { type: "boolean" },
|
|
280
|
+
silent: { type: "boolean" },
|
|
281
|
+
verify: { type: "boolean" },
|
|
282
|
+
currentVersion: { type: "string" },
|
|
283
|
+
nextVersion: { type: "string" }
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
function getChangelogPresetConfig(usersChangelogPresetConfig) {
|
|
289
|
+
const preset = {
|
|
290
|
+
name: "conventionalcommits"
|
|
291
|
+
};
|
|
292
|
+
if (typeof conventionalChangelogConfigSpec.properties === "object") {
|
|
293
|
+
Object.entries(conventionalChangelogConfigSpec.properties).forEach(([key, value]) => {
|
|
294
|
+
if ("default" in value && value.default !== void 0) {
|
|
295
|
+
preset[key] = value.default;
|
|
296
|
+
}
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
if (usersChangelogPresetConfig && typeof usersChangelogPresetConfig === "object") {
|
|
300
|
+
Object.entries(usersChangelogPresetConfig).forEach(([key, value]) => {
|
|
301
|
+
if (value !== void 0) {
|
|
302
|
+
preset[key] = value;
|
|
303
|
+
}
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
return ChangelogPresetConfigSchema.passthrough().parse(preset);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// src/config/user-config.ts
|
|
310
|
+
async function getUserConfig() {
|
|
311
|
+
const cliArguments = getCliArguments();
|
|
312
|
+
const cwd = cliArguments.flags.path ? resolve(cliArguments.flags.path) : process.cwd();
|
|
313
|
+
const joycon = new JoyCon();
|
|
314
|
+
const configFilePath = await joycon.resolve({
|
|
315
|
+
files: ["fork.config.ts", "fork.config.js", "fork.config.cjs", "fork.config.mjs"],
|
|
316
|
+
cwd,
|
|
317
|
+
stopDir: parse(cwd).root
|
|
318
|
+
});
|
|
319
|
+
if (!configFilePath) {
|
|
320
|
+
return {
|
|
321
|
+
...DEFAULT_CONFIG,
|
|
322
|
+
...cliArguments.flags,
|
|
323
|
+
path: cwd,
|
|
324
|
+
changelogPresetConfig: getChangelogPresetConfig()
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
const foundConfig = await bundleRequire({ filepath: configFilePath });
|
|
328
|
+
const parsedConfig = ForkConfigSchema.partial().safeParse(
|
|
329
|
+
foundConfig.mod.default || foundConfig.mod
|
|
330
|
+
);
|
|
331
|
+
if (!parsedConfig.success) {
|
|
332
|
+
throw parsedConfig.error;
|
|
333
|
+
}
|
|
334
|
+
const usersConfig = {
|
|
335
|
+
...DEFAULT_CONFIG,
|
|
336
|
+
...parsedConfig.data,
|
|
337
|
+
...cliArguments.flags
|
|
338
|
+
};
|
|
339
|
+
const files = mergeFiles(parsedConfig.data?.files, cliArguments.flags?.files);
|
|
340
|
+
return {
|
|
341
|
+
...usersConfig,
|
|
342
|
+
path: cwd,
|
|
343
|
+
files: files.length > 0 ? files : DEFAULT_CONFIG.files,
|
|
344
|
+
changelogPresetConfig: getChangelogPresetConfig(usersConfig?.changelogPresetConfig)
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
function mergeFiles(configFiles, cliFiles) {
|
|
348
|
+
return Array.from(
|
|
349
|
+
new Set(
|
|
350
|
+
[].concat(
|
|
351
|
+
Array.isArray(configFiles) ? configFiles : [],
|
|
352
|
+
Array.isArray(cliFiles) ? cliFiles : []
|
|
353
|
+
)
|
|
354
|
+
)
|
|
355
|
+
);
|
|
356
|
+
}
|
|
357
|
+
async function getLatestGitTagVersion(tagPrefix) {
|
|
358
|
+
const gitTags = await gitSemverTags({ tagPrefix });
|
|
359
|
+
if (!gitTags.length) {
|
|
360
|
+
return "1.0.0";
|
|
361
|
+
}
|
|
362
|
+
const cleanedTags = [];
|
|
363
|
+
for (const tag of gitTags) {
|
|
364
|
+
const cleanedTag = semver3.clean(tag.replace(new RegExp(`^${tagPrefix}`), ""));
|
|
365
|
+
if (cleanedTag) {
|
|
366
|
+
cleanedTags.push(cleanedTag);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
return cleanedTags.sort(semver3.rcompare)[0];
|
|
370
|
+
}
|
|
371
|
+
function getPriority(type) {
|
|
372
|
+
return ["patch", "minor", "major"].indexOf(type ?? "");
|
|
373
|
+
}
|
|
374
|
+
function getVersionType(version) {
|
|
375
|
+
const parseVersion = semver3.parse(version);
|
|
376
|
+
if (parseVersion?.major) {
|
|
377
|
+
return "major";
|
|
378
|
+
} else if (parseVersion?.minor) {
|
|
379
|
+
return "minor";
|
|
380
|
+
} else if (parseVersion?.patch) {
|
|
381
|
+
return "patch";
|
|
382
|
+
}
|
|
383
|
+
return void 0;
|
|
384
|
+
}
|
|
385
|
+
function getReleaseType(releaseType, currentVersion, preReleaseTag) {
|
|
386
|
+
if (!preReleaseTag) {
|
|
387
|
+
return releaseType;
|
|
388
|
+
}
|
|
389
|
+
const currentVersionsIsPreRelease = Array.isArray(semver3.prerelease(currentVersion));
|
|
390
|
+
if (currentVersionsIsPreRelease) {
|
|
391
|
+
const currentReleaseType = getVersionType(currentVersion);
|
|
392
|
+
if (currentReleaseType === releaseType || getPriority(currentReleaseType) > getPriority(releaseType)) {
|
|
393
|
+
return "prerelease";
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
return `pre${releaseType}`;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// src/process/version.ts
|
|
400
|
+
async function getCurrentVersion(config, logger, fileManager) {
|
|
401
|
+
const files = [];
|
|
402
|
+
const versions = /* @__PURE__ */ new Set();
|
|
403
|
+
for (const file of config.files) {
|
|
404
|
+
const fileState = fileManager.read(file);
|
|
405
|
+
if (fileState) {
|
|
406
|
+
files.push(fileState);
|
|
407
|
+
if (config.currentVersion) {
|
|
408
|
+
continue;
|
|
409
|
+
}
|
|
410
|
+
versions.add(fileState.version);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
if (config.currentVersion) {
|
|
414
|
+
versions.add(config.currentVersion);
|
|
415
|
+
}
|
|
416
|
+
if (versions.size === 0) {
|
|
417
|
+
if (config.gitTagFallback) {
|
|
418
|
+
const version = await getLatestGitTagVersion(config.tagPrefix);
|
|
419
|
+
if (version) {
|
|
420
|
+
return {
|
|
421
|
+
files: [],
|
|
422
|
+
version
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
throw new Error("Unable to find current version");
|
|
427
|
+
} else if (versions.size > 1) {
|
|
428
|
+
throw new Error("Found multiple versions");
|
|
429
|
+
}
|
|
430
|
+
const currentVersion = versions.entries().next().value[0];
|
|
431
|
+
if (config.inspectVersion) {
|
|
432
|
+
console.log(currentVersion);
|
|
433
|
+
process.exit(0);
|
|
434
|
+
}
|
|
435
|
+
logger.log(`Current version: ${currentVersion}`);
|
|
436
|
+
return {
|
|
437
|
+
files,
|
|
438
|
+
version: currentVersion
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
async function getNextVersion(config, logger, currentVersion) {
|
|
442
|
+
if (config.nextVersion && semver3.valid(config.nextVersion)) {
|
|
443
|
+
logger.log(`Next version: ${config.nextVersion}`);
|
|
444
|
+
return { version: config.nextVersion };
|
|
445
|
+
}
|
|
446
|
+
const isPreMajor = semver3.lt(currentVersion, "1.0.0");
|
|
447
|
+
let recommendedBump;
|
|
448
|
+
try {
|
|
449
|
+
recommendedBump = await conventionalRecommendedBump({
|
|
450
|
+
preset: {
|
|
451
|
+
name: "conventionalcommits",
|
|
452
|
+
...config.changelogPresetConfig,
|
|
453
|
+
preMajor: isPreMajor
|
|
454
|
+
},
|
|
455
|
+
path: config.path,
|
|
456
|
+
tagPrefix: config.tagPrefix,
|
|
457
|
+
cwd: config.path
|
|
458
|
+
});
|
|
459
|
+
} catch (error) {
|
|
460
|
+
throw new Error(`[conventional-recommended-bump] Unable to determine next version`);
|
|
461
|
+
}
|
|
462
|
+
if (recommendedBump.releaseType) {
|
|
463
|
+
const releaseType = getReleaseType(
|
|
464
|
+
recommendedBump.releaseType,
|
|
465
|
+
currentVersion,
|
|
466
|
+
config.preReleaseTag
|
|
467
|
+
);
|
|
468
|
+
const state = {
|
|
469
|
+
...recommendedBump,
|
|
470
|
+
preMajor: isPreMajor,
|
|
471
|
+
releaseType,
|
|
472
|
+
version: semver3.inc(
|
|
473
|
+
currentVersion,
|
|
474
|
+
releaseType,
|
|
475
|
+
typeof config.preReleaseTag === "string" ? config.preReleaseTag : void 0
|
|
476
|
+
) ?? ""
|
|
477
|
+
};
|
|
478
|
+
logger.log(`Next version: ${state.version} (${state.releaseType})`);
|
|
479
|
+
return state;
|
|
480
|
+
}
|
|
481
|
+
throw new Error("Unable to find next version");
|
|
482
|
+
}
|
|
483
|
+
function fileExists(filePath) {
|
|
484
|
+
try {
|
|
485
|
+
return lstatSync(filePath).isFile();
|
|
486
|
+
} catch (e) {
|
|
487
|
+
return false;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
// src/process/changelog.ts
|
|
492
|
+
var RELEASE_PATTERN = /(^#+ \[?[0-9]+\.[0-9]+\.[0-9]+|<a name=)/m;
|
|
493
|
+
function getOldReleaseContent(filePath, exists) {
|
|
494
|
+
if (exists) {
|
|
495
|
+
const fileContents = readFileSync(filePath, "utf-8");
|
|
496
|
+
const oldContentStart = fileContents.search(RELEASE_PATTERN);
|
|
497
|
+
if (oldContentStart !== -1) {
|
|
498
|
+
return fileContents.substring(oldContentStart);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
return "";
|
|
502
|
+
}
|
|
503
|
+
function getNewReleaseContent(config, logger, nextVersion) {
|
|
504
|
+
return new Promise((onResolve) => {
|
|
505
|
+
let newContent = "";
|
|
506
|
+
conventionalChangelog(
|
|
507
|
+
{
|
|
508
|
+
preset: {
|
|
509
|
+
name: "conventionalcommits",
|
|
510
|
+
...config.changelogPresetConfig
|
|
511
|
+
},
|
|
512
|
+
tagPrefix: config.tagPrefix,
|
|
513
|
+
warn: (...message) => logger.error("conventional-changelog: ", ...message),
|
|
514
|
+
cwd: config.path
|
|
515
|
+
},
|
|
516
|
+
{
|
|
517
|
+
version: nextVersion
|
|
518
|
+
},
|
|
519
|
+
{
|
|
520
|
+
merges: null,
|
|
521
|
+
path: config.path
|
|
522
|
+
}
|
|
523
|
+
).on("error", (error) => {
|
|
524
|
+
logger.error("conventional-changelog: Unable to parse changes");
|
|
525
|
+
throw error;
|
|
526
|
+
}).on("data", (chunk) => {
|
|
527
|
+
newContent += chunk.toString();
|
|
528
|
+
}).on("end", () => {
|
|
529
|
+
onResolve(newContent);
|
|
530
|
+
});
|
|
531
|
+
});
|
|
532
|
+
}
|
|
533
|
+
async function updateChangelog(config, logger, nextVersion) {
|
|
534
|
+
if (config.header.search(RELEASE_PATTERN) !== -1) {
|
|
535
|
+
throw new Error("Header cannot contain release pattern");
|
|
536
|
+
}
|
|
537
|
+
const changelogPath = resolve(config.path, config.changelog);
|
|
538
|
+
if (!config.dryRun && !fileExists(changelogPath)) {
|
|
539
|
+
logger.log(`Creating Changelog file: ${changelogPath}`);
|
|
540
|
+
writeFileSync(changelogPath, "\n", "utf8");
|
|
541
|
+
}
|
|
542
|
+
const oldContent = getOldReleaseContent(changelogPath, fileExists(changelogPath));
|
|
543
|
+
const newContent = await getNewReleaseContent(config, logger, nextVersion);
|
|
544
|
+
logger.log(`Updating Changelog: ${changelogPath}`);
|
|
545
|
+
if (!config.dryRun && newContent) {
|
|
546
|
+
writeFileSync(
|
|
547
|
+
changelogPath,
|
|
548
|
+
`${config.header}
|
|
549
|
+
${newContent}
|
|
550
|
+
${oldContent}
|
|
551
|
+
`,
|
|
552
|
+
"utf8"
|
|
553
|
+
);
|
|
554
|
+
}
|
|
555
|
+
return {
|
|
556
|
+
changelogPath,
|
|
557
|
+
oldContent,
|
|
558
|
+
newContent
|
|
559
|
+
};
|
|
560
|
+
}
|
|
561
|
+
var Git = class {
|
|
562
|
+
constructor(config, logger) {
|
|
563
|
+
this.config = config;
|
|
564
|
+
this.logger = logger;
|
|
565
|
+
this.add = this.add.bind(this);
|
|
566
|
+
this.commit = this.commit.bind(this);
|
|
567
|
+
this.tag = this.tag.bind(this);
|
|
568
|
+
this.revParse = this.revParse.bind(this);
|
|
569
|
+
}
|
|
570
|
+
add(...args) {
|
|
571
|
+
return this.execGit("add", args.filter(Boolean));
|
|
572
|
+
}
|
|
573
|
+
commit(...args) {
|
|
574
|
+
return this.execGit("commit", args.filter(Boolean));
|
|
575
|
+
}
|
|
576
|
+
tag(...args) {
|
|
577
|
+
return this.execGit("tag", args.filter(Boolean));
|
|
578
|
+
}
|
|
579
|
+
revParse(...args) {
|
|
580
|
+
return this.execGit("rev-parse", args.filter(Boolean));
|
|
581
|
+
}
|
|
582
|
+
execGit(command, args) {
|
|
583
|
+
if (this.config.dryRun) {
|
|
584
|
+
return Promise.resolve("");
|
|
585
|
+
}
|
|
586
|
+
this.logger.debug(`Executing: git ${command} ${args.join(" ")}`);
|
|
587
|
+
return new Promise((onResolve, onReject) => {
|
|
588
|
+
execFile(
|
|
589
|
+
"git",
|
|
590
|
+
[command, ...args],
|
|
591
|
+
{
|
|
592
|
+
cwd: this.config.path
|
|
593
|
+
},
|
|
594
|
+
(error, stdout, stderr) => {
|
|
595
|
+
if (error) {
|
|
596
|
+
this.logger.error(`git ${command}:`);
|
|
597
|
+
onReject(error);
|
|
598
|
+
}
|
|
599
|
+
onResolve(stdout ? stdout : stderr);
|
|
600
|
+
}
|
|
601
|
+
);
|
|
602
|
+
});
|
|
603
|
+
}
|
|
604
|
+
};
|
|
605
|
+
|
|
606
|
+
// src/utils/format-commit-message.ts
|
|
607
|
+
function formatCommitMessage(message, version) {
|
|
608
|
+
if (!message) {
|
|
609
|
+
message = "chore(release): {{currentTag}}";
|
|
610
|
+
}
|
|
611
|
+
return message.replace(new RegExp("{{currentTag}}", "g"), version);
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
// src/process/commit.ts
|
|
615
|
+
async function commitChanges(config, logger, files, nextVersion) {
|
|
616
|
+
const git = new Git(config, logger);
|
|
617
|
+
logger.log("Committing changes");
|
|
618
|
+
const filesToCommit = [];
|
|
619
|
+
if (fileExists(resolve(config.path, config.changelog))) {
|
|
620
|
+
filesToCommit.push(resolve(config.path, config.changelog));
|
|
621
|
+
}
|
|
622
|
+
for (const file of files) {
|
|
623
|
+
filesToCommit.push(file.path);
|
|
624
|
+
}
|
|
625
|
+
if (filesToCommit.length === 0) {
|
|
626
|
+
return {
|
|
627
|
+
filesToCommit
|
|
628
|
+
};
|
|
629
|
+
}
|
|
630
|
+
const shouldVerify = config.verify ? void 0 : "--no-verify";
|
|
631
|
+
const shouldSign = config.sign ? "--gpg-sign" : void 0;
|
|
632
|
+
if (config.commitAll) {
|
|
633
|
+
return {
|
|
634
|
+
filesToCommit,
|
|
635
|
+
gitAddOutput: await git.add("--all"),
|
|
636
|
+
gitCommitOutput: await git.commit(
|
|
637
|
+
shouldVerify,
|
|
638
|
+
shouldSign,
|
|
639
|
+
"--message",
|
|
640
|
+
formatCommitMessage(config.changelogPresetConfig?.releaseCommitMessageFormat, nextVersion)
|
|
641
|
+
)
|
|
642
|
+
};
|
|
643
|
+
}
|
|
644
|
+
return {
|
|
645
|
+
filesToCommit,
|
|
646
|
+
gitAddOutput: await git.add(...filesToCommit),
|
|
647
|
+
gitCommitOutput: await git.commit(
|
|
648
|
+
shouldVerify,
|
|
649
|
+
shouldSign,
|
|
650
|
+
...filesToCommit,
|
|
651
|
+
"--message",
|
|
652
|
+
formatCommitMessage(config.changelogPresetConfig?.releaseCommitMessageFormat, nextVersion)
|
|
653
|
+
)
|
|
654
|
+
};
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
// src/process/tag.ts
|
|
658
|
+
async function tagChanges(config, logger, nextVersion) {
|
|
659
|
+
const git = new Git(config, logger);
|
|
660
|
+
const tag = `${config.tagPrefix}${nextVersion}`;
|
|
661
|
+
logger.log(`Creating Tag: ${tag}`);
|
|
662
|
+
const gitTagOutput = await git.tag(
|
|
663
|
+
config.sign ? "--sign" : "--annotate",
|
|
664
|
+
tag,
|
|
665
|
+
"--message",
|
|
666
|
+
formatCommitMessage(config.changelogPresetConfig?.releaseCommitMessageFormat, nextVersion)
|
|
667
|
+
);
|
|
668
|
+
return {
|
|
669
|
+
gitTagOutput
|
|
670
|
+
};
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
// src/libs/stringify-package.ts
|
|
674
|
+
var DEFAULT_INDENT = 2;
|
|
675
|
+
var CRLF = "\r\n";
|
|
676
|
+
var LF = "\n";
|
|
677
|
+
function stringifyPackage(data, indent, newline) {
|
|
678
|
+
const stringified = JSON.stringify(data, null, indent ?? DEFAULT_INDENT);
|
|
679
|
+
if (newline === CRLF) {
|
|
680
|
+
return stringified.replace(new RegExp(LF, "g"), CRLF);
|
|
681
|
+
}
|
|
682
|
+
return stringified;
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
// src/strategies/json-package.ts
|
|
686
|
+
var JSONPackage = class {
|
|
687
|
+
constructor(config, logger) {
|
|
688
|
+
this.config = config;
|
|
689
|
+
this.logger = logger;
|
|
690
|
+
}
|
|
691
|
+
read(fileName) {
|
|
692
|
+
const filePath = resolve(this.config.path, fileName);
|
|
693
|
+
if (fileExists(filePath)) {
|
|
694
|
+
const fileContents = readFileSync(filePath, "utf8");
|
|
695
|
+
const parsedJson = JSON.parse(fileContents);
|
|
696
|
+
if (parsedJson.version) {
|
|
697
|
+
return {
|
|
698
|
+
name: fileName,
|
|
699
|
+
path: filePath,
|
|
700
|
+
version: parsedJson.version,
|
|
701
|
+
isPrivate: typeof parsedJson?.private === "boolean" ? parsedJson.private : true
|
|
702
|
+
};
|
|
703
|
+
}
|
|
704
|
+
this.logger.warn(`Unable to determine json package file: ${fileName}`);
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
write(filePath, newVersion) {
|
|
708
|
+
const fileContents = readFileSync(filePath, "utf8");
|
|
709
|
+
const parsedJson = JSON.parse(fileContents);
|
|
710
|
+
parsedJson.version = newVersion;
|
|
711
|
+
if (parsedJson.packages?.[""]) {
|
|
712
|
+
parsedJson.packages[""].version = newVersion;
|
|
713
|
+
}
|
|
714
|
+
writeFileSync(
|
|
715
|
+
filePath,
|
|
716
|
+
stringifyPackage(parsedJson, detectIndent(fileContents).amount, detectNewline(fileContents)),
|
|
717
|
+
"utf8"
|
|
718
|
+
);
|
|
719
|
+
}
|
|
720
|
+
};
|
|
721
|
+
var PlainText = class {
|
|
722
|
+
constructor(config, logger) {
|
|
723
|
+
this.config = config;
|
|
724
|
+
this.logger = logger;
|
|
725
|
+
}
|
|
726
|
+
read(fileName) {
|
|
727
|
+
const filePath = resolve(this.config.path, fileName);
|
|
728
|
+
if (fileExists(filePath)) {
|
|
729
|
+
const fileContents = readFileSync(filePath, "utf8");
|
|
730
|
+
return {
|
|
731
|
+
name: fileName,
|
|
732
|
+
path: filePath,
|
|
733
|
+
version: fileContents || ""
|
|
734
|
+
};
|
|
735
|
+
}
|
|
736
|
+
this.logger.warn(`Unable to determine plain text file: ${fileName}`);
|
|
737
|
+
}
|
|
738
|
+
write(filePath, newVersion) {
|
|
739
|
+
writeFileSync(filePath, newVersion, "utf8");
|
|
740
|
+
}
|
|
741
|
+
};
|
|
742
|
+
|
|
743
|
+
// src/strategies/file-manager.ts
|
|
744
|
+
var FileManager = class {
|
|
745
|
+
constructor(config, logger) {
|
|
746
|
+
this.config = config;
|
|
747
|
+
this.logger = logger;
|
|
748
|
+
this.JSONPackage = new JSONPackage(config, logger);
|
|
749
|
+
this.PlainText = new PlainText(config, logger);
|
|
750
|
+
}
|
|
751
|
+
JSONPackage;
|
|
752
|
+
PlainText;
|
|
753
|
+
/**
|
|
754
|
+
* Get the state from the given file name.
|
|
755
|
+
*
|
|
756
|
+
* @example
|
|
757
|
+
* ```ts
|
|
758
|
+
* fileManager.read("package.json");
|
|
759
|
+
* ```
|
|
760
|
+
*
|
|
761
|
+
* @returns
|
|
762
|
+
* ```json
|
|
763
|
+
* { "name": "package.json", "path": "/path/to/package.json", "version": "1.2.3", "isPrivate": true }
|
|
764
|
+
* ```
|
|
765
|
+
*/
|
|
766
|
+
read(fileName) {
|
|
767
|
+
if (fileName.toLowerCase().endsWith(".json")) {
|
|
768
|
+
return this.JSONPackage.read(fileName);
|
|
769
|
+
} else if (fileName.toLowerCase().endsWith("version.txt")) {
|
|
770
|
+
return this.PlainText.read(fileName);
|
|
771
|
+
}
|
|
772
|
+
this.logger.error(`Unsupported file type: ${fileName}`);
|
|
773
|
+
}
|
|
774
|
+
/**
|
|
775
|
+
* Write the new version to the given file path.
|
|
776
|
+
*
|
|
777
|
+
* @example
|
|
778
|
+
* ```ts
|
|
779
|
+
* fileManager.write("/path/to/package.json", "1.2.3");
|
|
780
|
+
* ```
|
|
781
|
+
*/
|
|
782
|
+
write(filePath, newVersion) {
|
|
783
|
+
if (this.config.dryRun) {
|
|
784
|
+
this.logger.log(`[Dry run]: Not updating ${filePath}`);
|
|
785
|
+
return;
|
|
786
|
+
}
|
|
787
|
+
if (filePath.toLowerCase().endsWith(".json")) {
|
|
788
|
+
return this.JSONPackage.write(filePath, newVersion);
|
|
789
|
+
} else if (filePath.toLowerCase().endsWith("version.txt")) {
|
|
790
|
+
return this.PlainText.write(filePath, newVersion);
|
|
791
|
+
}
|
|
792
|
+
this.logger.error(`Unsupported file type: ${filePath}`);
|
|
793
|
+
}
|
|
794
|
+
};
|
|
795
|
+
|
|
796
|
+
export { FileManager, ForkConfigSchema, Git, commitChanges, defineConfig, getCurrentVersion, getNextVersion, getUserConfig, tagChanges, updateChangelog };
|
|
797
|
+
//# sourceMappingURL=out.js.map
|
|
798
|
+
//# sourceMappingURL=chunk-S2VPLFG2.js.map
|