fork-version 5.0.2 → 5.1.1
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 +38 -0
- package/README.md +105 -35
- package/dist/cli.js +1 -1
- package/dist/commands/inspect.d.ts +1 -1
- package/dist/commands/main.d.ts +1 -1
- package/dist/commands/main.js +1 -1
- package/dist/config/load-config.js +6 -6
- package/dist/config/schema.d.ts +52 -2
- package/dist/config/schema.js +8 -2
- package/dist/config/types.d.ts +6 -0
- package/dist/files/arm-bicep.js +6 -8
- package/dist/files/file-manager.d.ts +51 -14
- package/dist/files/file-manager.js +32 -19
- package/dist/files/install-shield-ism.js +6 -8
- package/dist/files/json-package.js +9 -11
- package/dist/files/ms-build-project.js +6 -8
- package/dist/files/plain-text.js +5 -7
- package/dist/files/yaml-package.js +11 -32
- package/dist/index.d.ts +3 -3
- package/dist/index.js +2 -2
- package/dist/process/changelog.d.ts +1 -1
- package/dist/process/changelog.js +6 -6
- package/dist/process/commit.d.ts +1 -1
- package/dist/process/get-commits.d.ts +1 -1
- package/dist/process/get-current-version.d.ts +1 -1
- package/dist/process/get-current-version.js +1 -1
- package/dist/process/get-next-version.d.ts +1 -1
- package/dist/process/tag.d.ts +1 -1
- package/dist/utils/extract-build-metadata.js +37 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,43 @@
|
|
|
1
1
|
# Fork Version
|
|
2
2
|
|
|
3
|
+
## [5.1.1](https://github.com/eglavin/fork-version/compare/v5.1.0...v5.1.1) (2026-04-12)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Docs
|
|
7
|
+
|
|
8
|
+
* add all files and custom file manager examples ([43c85a4](https://github.com/eglavin/fork-version/commit/43c85a482906f73c7b45a28a522bec150b3f2cff))
|
|
9
|
+
* update build metadata info in readme ([e03c362](https://github.com/eglavin/fork-version/commit/e03c362094b7f0685fd386c7754f705a4d727472))
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
### Refactor
|
|
13
|
+
|
|
14
|
+
* move build metadata out of yaml class ([59627fc](https://github.com/eglavin/fork-version/commit/59627fc903bcd5aae1b44954fd6183417025a2f3))
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
## [5.1.0](https://github.com/eglavin/fork-version/compare/v5.0.2...v5.1.0) (2026-04-11)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Features
|
|
21
|
+
|
|
22
|
+
* implement custom user provided file managers ([9c6ed7c](https://github.com/eglavin/fork-version/commit/9c6ed7ccf39c736dfdb53b959f989c4139892523))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
### Docs
|
|
26
|
+
|
|
27
|
+
* update readme with details on using custom file managers ([57a6f17](https://github.com/eglavin/fork-version/commit/57a6f174473992b113c47acee53f24a82db4e56d))
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
### Refactor
|
|
31
|
+
|
|
32
|
+
* remove name property from file managers ([202fc21](https://github.com/eglavin/fork-version/commit/202fc21c49f13081d352f2e5c549a8ea3c68de7f))
|
|
33
|
+
* use loose object when validating custom file managers ([3b3f8a9](https://github.com/eglavin/fork-version/commit/3b3f8a92d082d9374f6fba8acd39655cc7405e39))
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
### Test
|
|
37
|
+
|
|
38
|
+
* add custom file manager object test ([6b58f40](https://github.com/eglavin/fork-version/commit/6b58f404ce6c4059ab43dfe2ccc3a189ae098f65))
|
|
39
|
+
|
|
40
|
+
|
|
3
41
|
## [5.0.2](https://github.com/eglavin/fork-version/compare/v5.0.1...v5.0.2) (2026-04-10)
|
|
4
42
|
|
|
5
43
|
|
package/README.md
CHANGED
|
@@ -292,36 +292,37 @@ Alternatively you can define your config using a key in your `package.json` file
|
|
|
292
292
|
|
|
293
293
|
#### Config Properties
|
|
294
294
|
|
|
295
|
-
| Property | Type
|
|
296
|
-
| :---------------------------------------------------- |
|
|
297
|
-
| command | string
|
|
298
|
-
| [files](#configfiles) | Array\<string>
|
|
299
|
-
| [
|
|
300
|
-
|
|
|
301
|
-
|
|
|
302
|
-
|
|
|
303
|
-
|
|
|
304
|
-
| [
|
|
305
|
-
|
|
|
306
|
-
|
|
|
307
|
-
|
|
|
308
|
-
|
|
|
309
|
-
|
|
|
310
|
-
|
|
|
311
|
-
|
|
|
312
|
-
|
|
|
313
|
-
|
|
|
314
|
-
|
|
|
315
|
-
|
|
|
316
|
-
|
|
|
317
|
-
|
|
|
318
|
-
|
|
|
319
|
-
|
|
|
320
|
-
|
|
|
321
|
-
|
|
|
322
|
-
|
|
|
323
|
-
|
|
|
324
|
-
|
|
|
295
|
+
| Property | Type | Default | Description |
|
|
296
|
+
| :---------------------------------------------------- | :------------------- | :---------------------- | :------------------------------------------------------------------------------------------------------------------ |
|
|
297
|
+
| command | string | `main` | The command to run. Can be one of: main, inspect-version, inspect-tag, validate-config. Defaults to main. |
|
|
298
|
+
| [files](#configfiles) | Array\<string> | `["package.json", ...]` | List of the files to be updated |
|
|
299
|
+
| [customFileManagers](#custom-file-updaters) | Array\<IFileManager> | - | Support for user provided custom file managers |
|
|
300
|
+
| [glob](#configglob) | string | - | Glob pattern to match files to be updated |
|
|
301
|
+
| path | string | `process.cwd()` | The path Fork-Version will run from |
|
|
302
|
+
| changelog | string | `CHANGELOG.md` | Name of the changelog file |
|
|
303
|
+
| header | string | `# Changelog...` | The header text for the changelog |
|
|
304
|
+
| [tagPrefix](#configtagprefix) | string | `v` | Prefix for the created tag |
|
|
305
|
+
| [preRelease](#configprerelease) | string / boolean | - | Make a pre-release with optional label if given value is a string |
|
|
306
|
+
| currentVersion | string | - | Use this version instead of trying to determine one |
|
|
307
|
+
| nextVersion | string | - | Attempt to update to this version, instead of incrementing using "conventional-commit" |
|
|
308
|
+
| [releaseAs](#configreleaseas) | string | - | Release as increments the version by the specified level. Overrides the default behaviour of "conventional-commit". |
|
|
309
|
+
| allowMultipleVersions | boolean | true | Don't throw an error if multiple versions are found in the given files. |
|
|
310
|
+
| commitAll | boolean | false | Commit all changes, not just files updated by Fork-Version |
|
|
311
|
+
| changelogAll | boolean | false | If this flag is set, all default commit types will be added to the changelog, not just `feat` and `fix`. |
|
|
312
|
+
| debug | boolean | false | Output debug information |
|
|
313
|
+
| dryRun | boolean | false | No output will be written to disk or committed |
|
|
314
|
+
| silent | boolean | false | Run without logging to the terminal |
|
|
315
|
+
| gitTagFallback | boolean | true | If unable to find a version in the given files, fallback and attempt to use the latest git tag |
|
|
316
|
+
| sign | boolean | false | Sign the commit with the systems GPG key |
|
|
317
|
+
| verify | boolean | false | Run user defined git hooks before committing |
|
|
318
|
+
| asJson | boolean | false | Print inspected output as a parsable json string |
|
|
319
|
+
| skipBump | boolean | false | Skip the bump step |
|
|
320
|
+
| skipChangelog | boolean | false | Skip the changelog step |
|
|
321
|
+
| skipCommit | boolean | false | Skip the commit step |
|
|
322
|
+
| skipTag | boolean | false | Skip the tag step |
|
|
323
|
+
| [changelogPresetConfig](#configchangelogpresetconfig) | object | {} | Override defaults from the "conventional-changelog-conventionalcommits" preset configuration |
|
|
324
|
+
| releaseMessageSuffix | string | - | Add a suffix to the end of the release message |
|
|
325
|
+
| [commitParserOptions](#configcommitparseroptions) | object | {} | Options to pass to commits parser |
|
|
325
326
|
|
|
326
327
|
##### config.files
|
|
327
328
|
|
|
@@ -337,7 +338,7 @@ By default Fork-Version will attempt to read versions from and update these file
|
|
|
337
338
|
- "manifest.json"
|
|
338
339
|
- "bower.json"
|
|
339
340
|
|
|
340
|
-
See the [Supported File Types](#supported-file-types) section below to see the currently supported file types.
|
|
341
|
+
See the [Supported File Types](#supported-file-types) section below to see the currently supported file types and the [Custom File Updater's](#custom-file-updaters) section below to see how to support other file types.
|
|
341
342
|
|
|
342
343
|
##### config.glob
|
|
343
344
|
|
|
@@ -469,6 +470,16 @@ If you are using one of the following Git hosts, Fork-Version will automatically
|
|
|
469
470
|
- [MS Build](#ms-build)
|
|
470
471
|
- [ARM Bicep](#arm-bicep)
|
|
471
472
|
- [Install Shield ISM](#install-shield-ism)
|
|
473
|
+
- [Custom File Updater's](#custom-file-updaters)
|
|
474
|
+
|
|
475
|
+
> [!Note]
|
|
476
|
+
> If your version strings include build metadata like one of the following examples:
|
|
477
|
+
>
|
|
478
|
+
> - 1.2.3+49a3f2b
|
|
479
|
+
> - 1.2.3-0+49a3f2b
|
|
480
|
+
> - 1.2.3-alpha.0+49a3f2b
|
|
481
|
+
>
|
|
482
|
+
> this metadata will be retained without modification.
|
|
472
483
|
|
|
473
484
|
#### Json Package
|
|
474
485
|
|
|
@@ -493,9 +504,6 @@ publish_to: 'none'
|
|
|
493
504
|
version: 1.2.3
|
|
494
505
|
```
|
|
495
506
|
|
|
496
|
-
> [!NOTE]
|
|
497
|
-
> If you're using Fork-Version for a flutter project, Fork-Version will split the version and the builder number on the "+" character, the version will be updated and the builder number will be left as is.
|
|
498
|
-
|
|
499
507
|
#### Plain Text
|
|
500
508
|
|
|
501
509
|
A plain text file is a file which contains just the version as the content. Files that end with `version.txt` will be treated as a plain text version file.
|
|
@@ -546,7 +554,69 @@ An Install Shield `*.ism` file can be either binary or an xml file. Fork-Version
|
|
|
546
554
|
|
|
547
555
|
#### Custom File Updater's
|
|
548
556
|
|
|
549
|
-
|
|
557
|
+
***Released in version 5.1.0***
|
|
558
|
+
|
|
559
|
+
If you have a file type that isn't supported by default, you can create a custom file manager to read and write the updated version to that file.
|
|
560
|
+
|
|
561
|
+
To do this you will need to create a class or an object that implements the `IFileManager` interface and add an instance of that class or object to the `customFileManagers` array in your config.
|
|
562
|
+
|
|
563
|
+
The following example show a custom file manager for a json file with the name of `test.json` with the following structure:
|
|
564
|
+
|
|
565
|
+
Example `test.json` file:
|
|
566
|
+
|
|
567
|
+
```json
|
|
568
|
+
{
|
|
569
|
+
"package": {
|
|
570
|
+
"version": "1.2.3"
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
Example Custom File Manager implementation:
|
|
576
|
+
|
|
577
|
+
```ts
|
|
578
|
+
// fork.config.ts
|
|
579
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
580
|
+
import { defineConfig, MissingPropertyException, type FileState, type IFileManager } from "fork-version";
|
|
581
|
+
|
|
582
|
+
class CustomFileManager implements IFileManager {
|
|
583
|
+
async read(filePath: string): Promise<FileState | undefined> {
|
|
584
|
+
const fileContent = await readFile(filePath, "utf-8");
|
|
585
|
+
if (fileContent) {
|
|
586
|
+
const parsedContent = JSON.parse(fileContent);
|
|
587
|
+
if ("package" in parsedContent && "version" in parsedContent.package) {
|
|
588
|
+
return {
|
|
589
|
+
path: filePath,
|
|
590
|
+
version: parsedContent.package.version,
|
|
591
|
+
};
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
throw new MissingPropertyException("My Custom File", "package.version");
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
async write(fileState: FileState, newVersion: string): Promise<void> {
|
|
598
|
+
const fileContent = await readFile(fileState.path, "utf-8");
|
|
599
|
+
if (fileContent) {
|
|
600
|
+
const parsedContent = JSON.parse(fileContent);
|
|
601
|
+
if ("package" in parsedContent && "version" in parsedContent.package) {
|
|
602
|
+
parsedContent.package.version = newVersion;
|
|
603
|
+
const updatedContent = JSON.stringify(parsedContent, null, 2);
|
|
604
|
+
await writeFile(fileState.path, updatedContent, "utf-8");
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
isSupportedFile(fileName: string) {
|
|
610
|
+
return fileName === "test.json";
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
export default defineConfig({
|
|
615
|
+
customFileManagers: [new CustomFileManager()],
|
|
616
|
+
});
|
|
617
|
+
```
|
|
618
|
+
|
|
619
|
+
> [See `IFileManager` interface to see the required methods and properties for a custom file manager.](./src/files/file-manager.ts)
|
|
550
620
|
|
|
551
621
|
### Code Usage
|
|
552
622
|
|
package/dist/cli.js
CHANGED
|
@@ -30,7 +30,7 @@ async function runFork() {
|
|
|
30
30
|
const result = await main(config, logger, fileManager, git);
|
|
31
31
|
const branchName = await git.getBranchName();
|
|
32
32
|
logger.log(`\nRun \`git push --follow-tags origin ${branchName}\` to push the changes and the tag.`);
|
|
33
|
-
if (result.current.files.some((file) => file.
|
|
33
|
+
if (result.current.files.some((file) => file.path.endsWith("package.json") && !file.isPrivate)) {
|
|
34
34
|
const npmTag = typeof config.preRelease === "string" ? config.preRelease : "prerelease";
|
|
35
35
|
logger.log(`${result.next.releaseType}`.startsWith("pre") ? `Run \`npm publish --tag ${npmTag}\` to publish the package.` : "Run `npm publish` to publish the package.");
|
|
36
36
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { ForkConfig } from "../config/types.js";
|
|
2
1
|
import { Logger } from "../services/logger.js";
|
|
3
2
|
import { FileManager } from "../files/file-manager.js";
|
|
3
|
+
import { ForkConfig } from "../config/types.js";
|
|
4
4
|
import { Git } from "../services/git.js";
|
|
5
5
|
|
|
6
6
|
//#region src/commands/inspect.d.ts
|
package/dist/commands/main.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { ForkConfig } from "../config/types.js";
|
|
2
1
|
import { Logger } from "../services/logger.js";
|
|
3
2
|
import { FileManager } from "../files/file-manager.js";
|
|
3
|
+
import { ForkConfig } from "../config/types.js";
|
|
4
4
|
import { Git } from "../services/git.js";
|
|
5
5
|
import { CommitsSinceTag } from "../process/get-commits.js";
|
|
6
6
|
import { CurrentVersion } from "../process/get-current-version.js";
|
package/dist/commands/main.js
CHANGED
|
@@ -14,7 +14,7 @@ async function main(config, logger, fileManager, git) {
|
|
|
14
14
|
logger.log("Updating files: ");
|
|
15
15
|
for (const outFile of current.files) {
|
|
16
16
|
logger.log(` - ${outFile.path}`);
|
|
17
|
-
fileManager.write(outFile, next.version);
|
|
17
|
+
await fileManager.write(outFile, next.version);
|
|
18
18
|
}
|
|
19
19
|
await updateChangelog(config, logger, next.version);
|
|
20
20
|
await commitChanges(config, logger, git, current.files, next.version);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ForkConfigJSONSchema, ForkConfigJSSchema } from "./schema.js";
|
|
2
2
|
import { parse } from "node:path";
|
|
3
|
-
import {
|
|
3
|
+
import { readFile } from "node:fs/promises";
|
|
4
4
|
import JoyCon from "joycon";
|
|
5
5
|
import { bundleRequire } from "bundle-require";
|
|
6
6
|
//#region src/config/load-config.ts
|
|
@@ -23,21 +23,21 @@ async function loadConfigFile(cwd) {
|
|
|
23
23
|
]);
|
|
24
24
|
if (!configFilePath) return {};
|
|
25
25
|
if (configFilePath.endsWith("json")) {
|
|
26
|
-
const fileContent = JSON.parse(
|
|
26
|
+
const fileContent = JSON.parse(await readFile(configFilePath, "utf8"));
|
|
27
27
|
if (configFilePath.endsWith("package.json")) {
|
|
28
28
|
if (fileContent[PACKAGE_JSON_CONFIG_KEY] && typeof fileContent[PACKAGE_JSON_CONFIG_KEY] === "object") {
|
|
29
|
-
const parsed =
|
|
29
|
+
const parsed = ForkConfigJSONSchema.partial().safeParse(fileContent[PACKAGE_JSON_CONFIG_KEY]);
|
|
30
30
|
if (!parsed.success) throw new Error(`Validation error in: ${configFilePath}`, { cause: parsed.error });
|
|
31
31
|
return parsed.data;
|
|
32
32
|
}
|
|
33
33
|
return {};
|
|
34
34
|
}
|
|
35
|
-
const parsed =
|
|
35
|
+
const parsed = ForkConfigJSONSchema.partial().safeParse(fileContent);
|
|
36
36
|
if (!parsed.success) throw new Error(`Validation error in: ${configFilePath}`, { cause: parsed.error });
|
|
37
37
|
return parsed.data;
|
|
38
38
|
}
|
|
39
39
|
const fileContent = await bundleRequire({ filepath: configFilePath });
|
|
40
|
-
const parsed =
|
|
40
|
+
const parsed = ForkConfigJSSchema.partial().safeParse(fileContent.mod.default || fileContent.mod);
|
|
41
41
|
if (!parsed.success) throw new Error(`Validation error in: ${configFilePath}`, { cause: parsed.error });
|
|
42
42
|
return parsed.data;
|
|
43
43
|
}
|
package/dist/config/schema.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
|
|
3
3
|
//#region src/config/schema.d.ts
|
|
4
|
-
declare const
|
|
4
|
+
declare const ForkConfigJSONSchema: z.ZodObject<{
|
|
5
5
|
command: z.ZodLiteral<"main" | "inspect" | "inspect-version" | "inspect-tag" | "validate-config">;
|
|
6
6
|
inspectVersion: z.ZodOptional<z.ZodBoolean>;
|
|
7
7
|
files: z.ZodArray<z.ZodString>;
|
|
@@ -46,5 +46,55 @@ declare const ForkConfigSchema: z.ZodObject<{
|
|
|
46
46
|
releaseMessageSuffix: z.ZodOptional<z.ZodString>;
|
|
47
47
|
commitParserOptions: z.ZodOptional<z.ZodObject<{}, z.core.$loose>>;
|
|
48
48
|
}, z.core.$strip>;
|
|
49
|
+
declare const ForkConfigJSSchema: z.ZodObject<{
|
|
50
|
+
command: z.ZodOptional<z.ZodLiteral<"main" | "inspect" | "inspect-version" | "inspect-tag" | "validate-config">>;
|
|
51
|
+
inspectVersion: z.ZodOptional<z.ZodOptional<z.ZodBoolean>>;
|
|
52
|
+
files: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
53
|
+
glob: z.ZodOptional<z.ZodOptional<z.ZodString>>;
|
|
54
|
+
path: z.ZodOptional<z.ZodString>;
|
|
55
|
+
changelog: z.ZodOptional<z.ZodString>;
|
|
56
|
+
header: z.ZodOptional<z.ZodString>;
|
|
57
|
+
tagPrefix: z.ZodOptional<z.ZodString>;
|
|
58
|
+
preRelease: z.ZodOptional<z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodBoolean]>>>;
|
|
59
|
+
currentVersion: z.ZodOptional<z.ZodOptional<z.ZodString>>;
|
|
60
|
+
nextVersion: z.ZodOptional<z.ZodOptional<z.ZodString>>;
|
|
61
|
+
releaseAs: z.ZodOptional<z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"major">, z.ZodLiteral<"minor">, z.ZodLiteral<"patch">]>>>;
|
|
62
|
+
allowMultipleVersions: z.ZodOptional<z.ZodBoolean>;
|
|
63
|
+
commitAll: z.ZodOptional<z.ZodBoolean>;
|
|
64
|
+
changelogAll: z.ZodOptional<z.ZodBoolean>;
|
|
65
|
+
debug: z.ZodOptional<z.ZodBoolean>;
|
|
66
|
+
dryRun: z.ZodOptional<z.ZodBoolean>;
|
|
67
|
+
silent: z.ZodOptional<z.ZodBoolean>;
|
|
68
|
+
gitTagFallback: z.ZodOptional<z.ZodBoolean>;
|
|
69
|
+
sign: z.ZodOptional<z.ZodBoolean>;
|
|
70
|
+
verify: z.ZodOptional<z.ZodBoolean>;
|
|
71
|
+
asJson: z.ZodOptional<z.ZodBoolean>;
|
|
72
|
+
skipBump: z.ZodOptional<z.ZodBoolean>;
|
|
73
|
+
skipChangelog: z.ZodOptional<z.ZodBoolean>;
|
|
74
|
+
skipCommit: z.ZodOptional<z.ZodBoolean>;
|
|
75
|
+
skipTag: z.ZodOptional<z.ZodBoolean>;
|
|
76
|
+
detectedGitHost: z.ZodOptional<z.ZodOptional<z.ZodString>>;
|
|
77
|
+
changelogPresetConfig: z.ZodOptional<z.ZodOptional<z.ZodObject<{
|
|
78
|
+
types: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
79
|
+
type: z.ZodString;
|
|
80
|
+
scope: z.ZodOptional<z.ZodString>;
|
|
81
|
+
section: z.ZodOptional<z.ZodString>;
|
|
82
|
+
hidden: z.ZodOptional<z.ZodBoolean>;
|
|
83
|
+
}, z.core.$strip>>>;
|
|
84
|
+
commitUrlFormat: z.ZodOptional<z.ZodString>;
|
|
85
|
+
compareUrlFormat: z.ZodOptional<z.ZodString>;
|
|
86
|
+
issueUrlFormat: z.ZodOptional<z.ZodString>;
|
|
87
|
+
userUrlFormat: z.ZodOptional<z.ZodString>;
|
|
88
|
+
releaseCommitMessageFormat: z.ZodOptional<z.ZodString>;
|
|
89
|
+
issuePrefixes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
90
|
+
}, z.core.$strip>>>;
|
|
91
|
+
releaseMessageSuffix: z.ZodOptional<z.ZodOptional<z.ZodString>>;
|
|
92
|
+
commitParserOptions: z.ZodOptional<z.ZodOptional<z.ZodObject<{}, z.core.$loose>>>;
|
|
93
|
+
customFileManagers: z.ZodArray<z.ZodObject<{
|
|
94
|
+
read: z.ZodFunction<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>;
|
|
95
|
+
write: z.ZodFunction<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>;
|
|
96
|
+
isSupportedFile: z.ZodFunction<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>;
|
|
97
|
+
}, z.core.$loose>>;
|
|
98
|
+
}, z.core.$strip>;
|
|
49
99
|
//#endregion
|
|
50
|
-
export {
|
|
100
|
+
export { ForkConfigJSONSchema, ForkConfigJSSchema };
|
package/dist/config/schema.js
CHANGED
|
@@ -15,7 +15,7 @@ const ChangelogPresetConfigSchema = z.object({
|
|
|
15
15
|
releaseCommitMessageFormat: z.string().describe("A string to be used to format the auto-generated release commit message."),
|
|
16
16
|
issuePrefixes: z.array(z.string()).describe("List of prefixes used to detect references to issues.")
|
|
17
17
|
});
|
|
18
|
-
const
|
|
18
|
+
const ForkConfigJSONSchema = z.object({
|
|
19
19
|
command: z.literal([
|
|
20
20
|
"main",
|
|
21
21
|
"inspect",
|
|
@@ -57,5 +57,11 @@ const ForkConfigSchema = z.object({
|
|
|
57
57
|
releaseMessageSuffix: z.string().optional().describe("Add a suffix to the release commit message."),
|
|
58
58
|
commitParserOptions: z.looseObject({}).optional().describe("Options to pass to commits parser.")
|
|
59
59
|
});
|
|
60
|
+
const CustomFileManagerSchema = z.looseObject({
|
|
61
|
+
read: z.function(),
|
|
62
|
+
write: z.function(),
|
|
63
|
+
isSupportedFile: z.function()
|
|
64
|
+
});
|
|
65
|
+
const ForkConfigJSSchema = ForkConfigJSONSchema.partial().extend({ customFileManagers: z.array(CustomFileManagerSchema).describe("List of custom file managers to use. See documentation for details.") });
|
|
60
66
|
//#endregion
|
|
61
|
-
export { ChangelogPresetConfigSchema, ChangelogPresetConfigTypeSchema,
|
|
67
|
+
export { ChangelogPresetConfigSchema, ChangelogPresetConfigTypeSchema, ForkConfigJSONSchema, ForkConfigJSSchema };
|
package/dist/config/types.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { getCliArguments } from "./cli-arguments.js";
|
|
2
2
|
import { ParserOptions } from "../commit-parser/options.js";
|
|
3
|
+
import { IFileManager } from "../files/file-manager.js";
|
|
3
4
|
|
|
4
5
|
//#region src/config/types.d.ts
|
|
5
6
|
interface ChangelogPresetConfigType {
|
|
@@ -87,6 +88,11 @@ interface ForkConfig {
|
|
|
87
88
|
* ```
|
|
88
89
|
*/
|
|
89
90
|
files: string[];
|
|
91
|
+
/**
|
|
92
|
+
* List of custom file managers to use. See documentation for details.
|
|
93
|
+
* @default undefined
|
|
94
|
+
*/
|
|
95
|
+
customFileManagers?: IFileManager[];
|
|
90
96
|
/**
|
|
91
97
|
* Glob pattern to match files to be updated.
|
|
92
98
|
*
|
package/dist/files/arm-bicep.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { MissingPropertyException } from "./file-manager.js";
|
|
2
|
-
import {
|
|
3
|
-
import { readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
4
3
|
//#region src/files/arm-bicep.ts
|
|
5
4
|
/**
|
|
6
5
|
* An ARM bicep file with metadata and variable called contentVersion.
|
|
@@ -16,19 +15,18 @@ var ARMBicep = class {
|
|
|
16
15
|
#metadataRegex = /(metadata contentVersion *= *['"])(?<version>[^'"]+)(['"])/;
|
|
17
16
|
/** https://regex101.com/r/iKCTF9/1 */
|
|
18
17
|
#varRegex = /(var contentVersion(?: string)? *= *['"])(?<version>[^'"]+)(['"])/;
|
|
19
|
-
read(filePath) {
|
|
20
|
-
const fileContents =
|
|
18
|
+
async read(filePath) {
|
|
19
|
+
const fileContents = await readFile(filePath, "utf8");
|
|
21
20
|
const metadataMatch = this.#metadataRegex.exec(fileContents);
|
|
22
21
|
if (metadataMatch?.groups?.version) return {
|
|
23
|
-
name: basename(filePath),
|
|
24
22
|
path: filePath,
|
|
25
23
|
version: metadataMatch.groups.version
|
|
26
24
|
};
|
|
27
25
|
throw new MissingPropertyException("ARM Bicep", "metadata contentVersion");
|
|
28
26
|
}
|
|
29
|
-
write(fileState, newVersion) {
|
|
30
|
-
const updatedContent =
|
|
31
|
-
|
|
27
|
+
async write(fileState, newVersion) {
|
|
28
|
+
const updatedContent = (await readFile(fileState.path, "utf8")).replace(this.#metadataRegex, `$1${newVersion}$3`).replace(this.#varRegex, `$1${newVersion}$3`);
|
|
29
|
+
await writeFile(fileState.path, updatedContent, "utf8");
|
|
32
30
|
}
|
|
33
31
|
isSupportedFile(fileName) {
|
|
34
32
|
return fileName.endsWith(".bicep");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ForkConfig } from "../config/types.js";
|
|
2
1
|
import { Logger } from "../services/logger.js";
|
|
2
|
+
import { ForkConfig } from "../config/types.js";
|
|
3
3
|
|
|
4
4
|
//#region src/files/file-manager.d.ts
|
|
5
5
|
/**
|
|
@@ -12,45 +12,82 @@ declare class MissingPropertyException extends Error {
|
|
|
12
12
|
constructor(fileType: string, propertyName: string);
|
|
13
13
|
}
|
|
14
14
|
interface FileState {
|
|
15
|
-
name: string;
|
|
16
15
|
path: string;
|
|
17
16
|
version: string;
|
|
17
|
+
buildMetadata?: string;
|
|
18
18
|
[other: string]: unknown;
|
|
19
19
|
}
|
|
20
20
|
interface IFileManager {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
/**
|
|
22
|
+
* Function to read the file and return its current state.
|
|
23
|
+
* @param filePath The path of the file to read, can be either an absolute path or a file name relative to the config path.
|
|
24
|
+
* @returns The state of the file, including its current version and any other relevant information.
|
|
25
|
+
* @throws {MissingPropertyException} If the file is missing a required property.
|
|
26
|
+
* @throws {Error} If an unexpected error occurs while reading the file.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* const fileState = await fileManager.read("package.json");
|
|
31
|
+
*
|
|
32
|
+
* // Returns
|
|
33
|
+
* { path: "package.json", version: "1.2.3" }
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
read(filePath: string): Promise<FileState | undefined>;
|
|
37
|
+
/**
|
|
38
|
+
* Function to write the new version to the file.
|
|
39
|
+
* @param fileState The current state of the file, including its path and current version.
|
|
40
|
+
* @param newVersion The new version string to write to the file.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```ts
|
|
44
|
+
* await fileManager.write(
|
|
45
|
+
* { path: "package.json", version: "1.2.2" },
|
|
46
|
+
* "1.2.3"
|
|
47
|
+
* );
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
write(fileState: FileState, newVersion: string): Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* Determine if the file manager supports the given file based on its name or path.
|
|
53
|
+
* File name will be transformed to lower case before checking for support to allow for case-insensitive file matching.
|
|
54
|
+
* @param filePath The name or path of the file to check.
|
|
55
|
+
* @returns `true` if the file is supported by this file manager, `false` otherwise.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```ts
|
|
59
|
+
* fileManager.isSupportedFile("package.json");
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
isSupportedFile(filePath: string): boolean;
|
|
24
63
|
}
|
|
25
64
|
declare class FileManager {
|
|
26
65
|
#private;
|
|
27
66
|
constructor(config: ForkConfig, logger: Logger);
|
|
28
67
|
/**
|
|
29
|
-
* Get the state from the given file
|
|
68
|
+
* Get the state from the given file.
|
|
30
69
|
*
|
|
31
70
|
* @example
|
|
32
71
|
* ```ts
|
|
33
72
|
* fileManager.read("package.json");
|
|
34
|
-
* ```
|
|
35
73
|
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* { "name": "package.json", "path": "/path/to/package.json", "version": "1.2.3", "isPrivate": true }
|
|
74
|
+
* // Returns
|
|
75
|
+
* { path: "package.json", version: "1.2.3" }
|
|
39
76
|
* ```
|
|
40
77
|
*/
|
|
41
|
-
read(pathOrName: string): FileState | undefined
|
|
78
|
+
read(pathOrName: string): Promise<FileState | undefined>;
|
|
42
79
|
/**
|
|
43
|
-
* Write
|
|
80
|
+
* Write new version to the given file.
|
|
44
81
|
*
|
|
45
82
|
* @example
|
|
46
83
|
* ```ts
|
|
47
84
|
* fileManager.write(
|
|
48
|
-
* {
|
|
85
|
+
* { path: "package.json", version: "1.2.2" },
|
|
49
86
|
* "1.2.3"
|
|
50
87
|
* );
|
|
51
88
|
* ```
|
|
52
89
|
*/
|
|
53
|
-
write(fileState: FileState, newVersion: string): void
|
|
90
|
+
write(fileState: FileState, newVersion: string): Promise<void>;
|
|
54
91
|
}
|
|
55
92
|
//#endregion
|
|
56
93
|
export { FileManager, FileState, IFileManager, MissingPropertyException };
|
|
@@ -5,7 +5,8 @@ import { PlainText } from "./plain-text.js";
|
|
|
5
5
|
import { MSBuildProject } from "./ms-build-project.js";
|
|
6
6
|
import { ARMBicep } from "./arm-bicep.js";
|
|
7
7
|
import { InstallShieldISM } from "./install-shield-ism.js";
|
|
8
|
-
import {
|
|
8
|
+
import { extractBuildMetadata } from "../utils/extract-build-metadata.js";
|
|
9
|
+
import { isAbsolute, relative, resolve } from "node:path";
|
|
9
10
|
//#region src/files/file-manager.ts
|
|
10
11
|
/**
|
|
11
12
|
* Exception thrown if a file manager encounters a file missing a required property,
|
|
@@ -28,7 +29,7 @@ var FileManager = class {
|
|
|
28
29
|
constructor(config, logger) {
|
|
29
30
|
this.#config = config;
|
|
30
31
|
this.#logger = logger;
|
|
31
|
-
|
|
32
|
+
const builtinFileManagers = [
|
|
32
33
|
new JSONPackage(),
|
|
33
34
|
new YAMLPackage(),
|
|
34
35
|
new PlainText(),
|
|
@@ -36,51 +37,63 @@ var FileManager = class {
|
|
|
36
37
|
new ARMBicep(),
|
|
37
38
|
new InstallShieldISM()
|
|
38
39
|
];
|
|
40
|
+
if (config.customFileManagers) this.#fileManagers = [...config.customFileManagers, ...builtinFileManagers];
|
|
41
|
+
else this.#fileManagers = builtinFileManagers;
|
|
39
42
|
}
|
|
40
43
|
/**
|
|
41
|
-
* Get the state from the given file
|
|
44
|
+
* Get the state from the given file.
|
|
42
45
|
*
|
|
43
46
|
* @example
|
|
44
47
|
* ```ts
|
|
45
48
|
* fileManager.read("package.json");
|
|
46
|
-
* ```
|
|
47
49
|
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* { "name": "package.json", "path": "/path/to/package.json", "version": "1.2.3", "isPrivate": true }
|
|
50
|
+
* // Returns
|
|
51
|
+
* { path: "package.json", version: "1.2.3" }
|
|
51
52
|
* ```
|
|
52
53
|
*/
|
|
53
|
-
read(pathOrName) {
|
|
54
|
-
const _fileName = pathOrName.toLowerCase();
|
|
54
|
+
async read(pathOrName) {
|
|
55
55
|
const filePath = isAbsolute(pathOrName) ? pathOrName : resolve(this.#config.path, pathOrName);
|
|
56
|
+
const relativePath = relative(this.#config.path, filePath);
|
|
57
|
+
const fileNameLower = relativePath.toLocaleLowerCase();
|
|
56
58
|
if (!fileExists(filePath)) return;
|
|
57
|
-
for (const fileManager of this.#fileManagers) if (fileManager.isSupportedFile(
|
|
59
|
+
for (const fileManager of this.#fileManagers) if (fileManager.isSupportedFile(fileNameLower)) {
|
|
58
60
|
try {
|
|
59
|
-
|
|
61
|
+
const fileState = await fileManager.read(filePath);
|
|
62
|
+
if (fileState) {
|
|
63
|
+
const { version, buildMetadata } = extractBuildMetadata(fileState.version);
|
|
64
|
+
if (buildMetadata) {
|
|
65
|
+
fileState.version = version;
|
|
66
|
+
fileState.buildMetadata = buildMetadata;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return fileState;
|
|
60
70
|
} catch (error) {
|
|
61
|
-
if (error instanceof MissingPropertyException) this.#logger.warn(`[File Manager] Missing '${error.propertyName}' property in ${error.fileType} file: ${
|
|
71
|
+
if (error instanceof MissingPropertyException) this.#logger.warn(`[File Manager] Missing '${error.propertyName}' property in ${error.fileType} file: ${relativePath}`);
|
|
62
72
|
else throw new Error(`An unexpected error occurred while reading file: ${filePath}`, { cause: error });
|
|
63
73
|
}
|
|
64
74
|
return;
|
|
65
75
|
}
|
|
66
|
-
this.#logger.error(`[File Manager] Unsupported file: ${
|
|
76
|
+
this.#logger.error(`[File Manager] Unsupported file: ${relativePath}`);
|
|
67
77
|
}
|
|
68
78
|
/**
|
|
69
|
-
* Write
|
|
79
|
+
* Write new version to the given file.
|
|
70
80
|
*
|
|
71
81
|
* @example
|
|
72
82
|
* ```ts
|
|
73
83
|
* fileManager.write(
|
|
74
|
-
* {
|
|
84
|
+
* { path: "package.json", version: "1.2.2" },
|
|
75
85
|
* "1.2.3"
|
|
76
86
|
* );
|
|
77
87
|
* ```
|
|
78
88
|
*/
|
|
79
|
-
write(fileState, newVersion) {
|
|
89
|
+
async write(fileState, newVersion) {
|
|
80
90
|
if (this.#config.dryRun) return;
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
91
|
+
const relativePath = relative(this.#config.path, fileState.path);
|
|
92
|
+
const fileNameLower = relativePath.toLocaleLowerCase();
|
|
93
|
+
let updatedVersion = newVersion;
|
|
94
|
+
if (fileState?.buildMetadata) updatedVersion += `+${fileState.buildMetadata}`;
|
|
95
|
+
for (const fileManager of this.#fileManagers) if (fileManager.isSupportedFile(fileNameLower)) return await fileManager.write(fileState, updatedVersion);
|
|
96
|
+
this.#logger.error(`[File Manager] Unsupported file: ${relativePath}`);
|
|
84
97
|
}
|
|
85
98
|
};
|
|
86
99
|
//#endregion
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { MissingPropertyException } from "./file-manager.js";
|
|
2
|
-
import {
|
|
3
|
-
import { readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
4
3
|
import * as cheerio from "cheerio/slim";
|
|
5
4
|
//#region src/files/install-shield-ism.ts
|
|
6
5
|
/**
|
|
@@ -29,23 +28,22 @@ var InstallShieldISM = class {
|
|
|
29
28
|
xmlMode: true,
|
|
30
29
|
xml: { decodeEntities: false }
|
|
31
30
|
};
|
|
32
|
-
read(filePath) {
|
|
33
|
-
const fileContents =
|
|
31
|
+
async read(filePath) {
|
|
32
|
+
const fileContents = await readFile(filePath, "utf8");
|
|
34
33
|
const version = cheerio.load(fileContents, this.#cheerioOptions)("msi > table[name=\"Property\"] > row > td:contains(\"ProductVersion\")").next().text().trim();
|
|
35
34
|
if (version) return {
|
|
36
|
-
name: basename(filePath),
|
|
37
35
|
path: filePath,
|
|
38
36
|
version
|
|
39
37
|
};
|
|
40
38
|
throw new MissingPropertyException("InstallShield ISM", "ProductVersion");
|
|
41
39
|
}
|
|
42
|
-
write(fileState, newVersion) {
|
|
43
|
-
const fileContents =
|
|
40
|
+
async write(fileState, newVersion) {
|
|
41
|
+
const fileContents = await readFile(fileState.path, "utf8");
|
|
44
42
|
const $ = cheerio.load(fileContents, this.#cheerioOptions);
|
|
45
43
|
const versionCell = $("msi > table[name=\"Property\"] > row > td:contains(\"ProductVersion\")").next();
|
|
46
44
|
if (versionCell.length > 0) versionCell.text(newVersion);
|
|
47
45
|
const updatedContent = $.xml().replaceAll("\"/>", "\" />");
|
|
48
|
-
|
|
46
|
+
await writeFile(fileState.path, updatedContent, "utf8");
|
|
49
47
|
}
|
|
50
48
|
isSupportedFile(fileName) {
|
|
51
49
|
return fileName.endsWith(".ism");
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { MissingPropertyException } from "./file-manager.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { applyEdits, modify, parse as parse$1 } from "jsonc-parser";
|
|
2
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
3
|
+
import { applyEdits, modify, parse } from "jsonc-parser";
|
|
5
4
|
//#region src/files/json-package.ts
|
|
6
5
|
/**
|
|
7
6
|
* A json package file should have a version property, like what can be seen
|
|
@@ -33,28 +32,27 @@ var JSONPackage = class {
|
|
|
33
32
|
#setStringInJsonc(jsonc, jsonPath, newString) {
|
|
34
33
|
return applyEdits(jsonc, modify(jsonc, jsonPath, newString, {}));
|
|
35
34
|
}
|
|
36
|
-
read(filePath) {
|
|
37
|
-
const fileContents =
|
|
35
|
+
async read(filePath) {
|
|
36
|
+
const fileContents = await readFile(filePath, "utf8");
|
|
38
37
|
const parseErrors = [];
|
|
39
|
-
const parsedJson = parse
|
|
38
|
+
const parsedJson = parse(fileContents, parseErrors, this.#jsoncOptions);
|
|
40
39
|
if (parsedJson?.version && parseErrors.length === 0) return {
|
|
41
|
-
name: basename(filePath),
|
|
42
40
|
path: filePath,
|
|
43
41
|
version: parsedJson.version,
|
|
44
42
|
isPrivate: typeof parsedJson?.private === "boolean" ? parsedJson.private : true
|
|
45
43
|
};
|
|
46
44
|
throw new MissingPropertyException("JSON", "version");
|
|
47
45
|
}
|
|
48
|
-
write(fileState, newVersion) {
|
|
49
|
-
let fileContents =
|
|
50
|
-
const parsedJson = parse
|
|
46
|
+
async write(fileState, newVersion) {
|
|
47
|
+
let fileContents = await readFile(fileState.path, "utf8");
|
|
48
|
+
const parsedJson = parse(fileContents, [], this.#jsoncOptions);
|
|
51
49
|
fileContents = this.#setStringInJsonc(fileContents, ["version"], newVersion);
|
|
52
50
|
if (parsedJson?.packages?.[""]) fileContents = this.#setStringInJsonc(fileContents, [
|
|
53
51
|
"packages",
|
|
54
52
|
"",
|
|
55
53
|
"version"
|
|
56
54
|
], newVersion);
|
|
57
|
-
|
|
55
|
+
await writeFile(fileState.path, fileContents, "utf8");
|
|
58
56
|
}
|
|
59
57
|
isSupportedFile(fileName) {
|
|
60
58
|
return fileName.endsWith(".json") || fileName.endsWith(".jsonc");
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { MissingPropertyException } from "./file-manager.js";
|
|
2
|
-
import {
|
|
3
|
-
import { readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
4
3
|
import * as cheerio from "cheerio/slim";
|
|
5
4
|
//#region src/files/ms-build-project.ts
|
|
6
5
|
/**
|
|
@@ -22,22 +21,21 @@ var MSBuildProject = class {
|
|
|
22
21
|
xmlMode: true,
|
|
23
22
|
xml: { decodeEntities: false }
|
|
24
23
|
};
|
|
25
|
-
read(filePath) {
|
|
26
|
-
const fileContents =
|
|
24
|
+
async read(filePath) {
|
|
25
|
+
const fileContents = await readFile(filePath, "utf8");
|
|
27
26
|
const version = cheerio.load(fileContents, this.#cheerioOptions)("Project > PropertyGroup > Version").text();
|
|
28
27
|
if (version) return {
|
|
29
|
-
name: basename(filePath),
|
|
30
28
|
path: filePath,
|
|
31
29
|
version
|
|
32
30
|
};
|
|
33
31
|
throw new MissingPropertyException("MSBuild", "Version");
|
|
34
32
|
}
|
|
35
|
-
write(fileState, newVersion) {
|
|
36
|
-
const fileContents =
|
|
33
|
+
async write(fileState, newVersion) {
|
|
34
|
+
const fileContents = await readFile(fileState.path, "utf8");
|
|
37
35
|
const $ = cheerio.load(fileContents, this.#cheerioOptions);
|
|
38
36
|
$("Project > PropertyGroup > Version").text(newVersion);
|
|
39
37
|
const updatedContent = $.xml().replaceAll("\"/>", "\" />");
|
|
40
|
-
|
|
38
|
+
await writeFile(fileState.path, updatedContent, "utf8");
|
|
41
39
|
}
|
|
42
40
|
isSupportedFile(fileName) {
|
|
43
41
|
return [
|
package/dist/files/plain-text.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { MissingPropertyException } from "./file-manager.js";
|
|
2
|
-
import {
|
|
3
|
-
import { readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
4
3
|
//#region src/files/plain-text.ts
|
|
5
4
|
/**
|
|
6
5
|
* A plain text file will have just the version as the content.
|
|
@@ -11,17 +10,16 @@ import { readFileSync, writeFileSync } from "node:fs";
|
|
|
11
10
|
* ```
|
|
12
11
|
*/
|
|
13
12
|
var PlainText = class {
|
|
14
|
-
read(filePath) {
|
|
15
|
-
const fileContents =
|
|
13
|
+
async read(filePath) {
|
|
14
|
+
const fileContents = (await readFile(filePath, "utf8")).trim();
|
|
16
15
|
if (fileContents) return {
|
|
17
|
-
name: basename(filePath),
|
|
18
16
|
path: filePath,
|
|
19
17
|
version: fileContents
|
|
20
18
|
};
|
|
21
19
|
throw new MissingPropertyException("Plain Text", "version");
|
|
22
20
|
}
|
|
23
|
-
write(fileState, newVersion) {
|
|
24
|
-
|
|
21
|
+
async write(fileState, newVersion) {
|
|
22
|
+
await writeFile(fileState.path, newVersion, "utf8");
|
|
25
23
|
}
|
|
26
24
|
isSupportedFile(fileName) {
|
|
27
25
|
return fileName.endsWith("version.txt");
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { MissingPropertyException } from "./file-manager.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { parse as parse$1, parseDocument } from "yaml";
|
|
2
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
3
|
+
import { parse, parseDocument } from "yaml";
|
|
5
4
|
//#region src/files/yaml-package.ts
|
|
6
5
|
/**
|
|
7
6
|
* A yaml package file should have a version property on the top level, like what can be seen
|
|
@@ -16,38 +15,18 @@ import { parse as parse$1, parseDocument } from "yaml";
|
|
|
16
15
|
* ```
|
|
17
16
|
*/
|
|
18
17
|
var YAMLPackage = class {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
#handleBuildNumber(fileVersion) {
|
|
25
|
-
const [version, builderNumber] = fileVersion.split("+");
|
|
26
|
-
if (/^\d+$/.test(builderNumber)) return {
|
|
27
|
-
version,
|
|
28
|
-
builderNumber
|
|
18
|
+
async read(filePath) {
|
|
19
|
+
const fileVersion = parse(await readFile(filePath, "utf8"))?.version;
|
|
20
|
+
if (fileVersion) return {
|
|
21
|
+
path: filePath,
|
|
22
|
+
version: fileVersion
|
|
29
23
|
};
|
|
30
|
-
return { version: fileVersion };
|
|
31
|
-
}
|
|
32
|
-
read(filePath) {
|
|
33
|
-
const fileVersion = parse$1(readFileSync(filePath, "utf-8"))?.version;
|
|
34
|
-
if (fileVersion) {
|
|
35
|
-
const parsedVersion = this.#handleBuildNumber(fileVersion);
|
|
36
|
-
return {
|
|
37
|
-
name: basename(filePath),
|
|
38
|
-
path: filePath,
|
|
39
|
-
version: parsedVersion.version || "",
|
|
40
|
-
builderNumber: parsedVersion.builderNumber ?? void 0
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
24
|
throw new MissingPropertyException("YAML", "version");
|
|
44
25
|
}
|
|
45
|
-
write(fileState, newVersion) {
|
|
46
|
-
const yamlDocument = parseDocument(
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
yamlDocument.set("version", newFileVersion);
|
|
50
|
-
writeFileSync(fileState.path, yamlDocument.toString(), "utf8");
|
|
26
|
+
async write(fileState, newVersion) {
|
|
27
|
+
const yamlDocument = parseDocument(await readFile(fileState.path, "utf8"));
|
|
28
|
+
yamlDocument.set("version", newVersion);
|
|
29
|
+
await writeFile(fileState.path, yamlDocument.toString(), "utf8");
|
|
51
30
|
}
|
|
52
31
|
isSupportedFile(fileName) {
|
|
53
32
|
return fileName.endsWith(".yaml") || fileName.endsWith(".yml");
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ParserOptions, createParserOptions } from "./commit-parser/options.js";
|
|
2
|
-
import { ChangelogPresetConfig, ChangelogPresetConfigType, Config, ForkConfig } from "./config/types.js";
|
|
3
2
|
import { Logger } from "./services/logger.js";
|
|
4
3
|
import { FileManager, FileState, IFileManager, MissingPropertyException } from "./files/file-manager.js";
|
|
4
|
+
import { ChangelogPresetConfig, ChangelogPresetConfigType, Config, ForkConfig } from "./config/types.js";
|
|
5
5
|
import { Git } from "./services/git.js";
|
|
6
6
|
import { inspect } from "./commands/inspect.js";
|
|
7
7
|
import { main } from "./commands/main.js";
|
|
@@ -9,7 +9,7 @@ import { validateConfig } from "./commands/validate-config.js";
|
|
|
9
9
|
import { Commit, CommitMerge, CommitNote, CommitReference, CommitRevert } from "./commit-parser/types.js";
|
|
10
10
|
import { CommitParser } from "./commit-parser/commit-parser.js";
|
|
11
11
|
import { filterRevertedCommits } from "./commit-parser/filter-reverted-commits.js";
|
|
12
|
-
import {
|
|
12
|
+
import { ForkConfigJSONSchema, ForkConfigJSSchema } from "./config/schema.js";
|
|
13
13
|
import { defineConfig } from "./config/define-config.js";
|
|
14
14
|
import { getUserConfig } from "./config/user-config.js";
|
|
15
15
|
import { CommitsSinceTag, getCommitsSinceTag } from "./process/get-commits.js";
|
|
@@ -18,4 +18,4 @@ import { NextVersion, getNextVersion } from "./process/get-next-version.js";
|
|
|
18
18
|
import { updateChangelog } from "./process/changelog.js";
|
|
19
19
|
import { commitChanges } from "./process/commit.js";
|
|
20
20
|
import { tagChanges } from "./process/tag.js";
|
|
21
|
-
export { type ChangelogPresetConfig, type ChangelogPresetConfigType, type Commit, type CommitMerge, type CommitNote, CommitParser, type CommitReference, type CommitRevert, type CommitsSinceTag, type Config, type CurrentVersion, FileManager, type FileState, type ForkConfig,
|
|
21
|
+
export { type ChangelogPresetConfig, type ChangelogPresetConfigType, type Commit, type CommitMerge, type CommitNote, CommitParser, type CommitReference, type CommitRevert, type CommitsSinceTag, type Config, type CurrentVersion, FileManager, type FileState, type ForkConfig, ForkConfigJSONSchema, ForkConfigJSSchema, Git, type IFileManager, Logger, MissingPropertyException, type NextVersion, type ParserOptions, commitChanges, createParserOptions, defineConfig, filterRevertedCommits, getCommitsSinceTag, getCurrentVersion, getNextVersion, getUserConfig, inspect, main, tagChanges, updateChangelog, validateConfig };
|
package/dist/index.js
CHANGED
|
@@ -10,10 +10,10 @@ import { commitChanges } from "./process/commit.js";
|
|
|
10
10
|
import { tagChanges } from "./process/tag.js";
|
|
11
11
|
import { main } from "./commands/main.js";
|
|
12
12
|
import { validateConfig } from "./commands/validate-config.js";
|
|
13
|
-
import {
|
|
13
|
+
import { ForkConfigJSONSchema, ForkConfigJSSchema } from "./config/schema.js";
|
|
14
14
|
import { defineConfig } from "./config/define-config.js";
|
|
15
15
|
import { Git } from "./services/git.js";
|
|
16
16
|
import { getUserConfig } from "./config/user-config.js";
|
|
17
17
|
import { FileManager, MissingPropertyException } from "./files/file-manager.js";
|
|
18
18
|
import { Logger } from "./services/logger.js";
|
|
19
|
-
export { CommitParser, FileManager,
|
|
19
|
+
export { CommitParser, FileManager, ForkConfigJSONSchema, ForkConfigJSSchema, Git, Logger, MissingPropertyException, commitChanges, createParserOptions, defineConfig, filterRevertedCommits, getCommitsSinceTag, getCurrentVersion, getNextVersion, getUserConfig, inspect, main, tagChanges, updateChangelog, validateConfig };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ForkConfig } from "../config/types.js";
|
|
2
1
|
import { Logger } from "../services/logger.js";
|
|
2
|
+
import { ForkConfig } from "../config/types.js";
|
|
3
3
|
|
|
4
4
|
//#region src/process/changelog.d.ts
|
|
5
5
|
declare function updateChangelog(config: ForkConfig, logger: Logger, nextVersion: string): Promise<void>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { fileExists } from "../utils/file-state.js";
|
|
2
2
|
import { resolve } from "node:path";
|
|
3
|
-
import {
|
|
3
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
4
4
|
import conventionalChangelog from "conventional-changelog";
|
|
5
5
|
//#region src/process/changelog.ts
|
|
6
6
|
/**
|
|
@@ -13,9 +13,9 @@ const RELEASE_PATTERN = /(^#+ \[?[0-9]+\.[0-9]+\.[0-9]+|<a name=)/m;
|
|
|
13
13
|
* Get the existing changelog content from the latest release onwards.
|
|
14
14
|
* @see {@link RELEASE_PATTERN}
|
|
15
15
|
*/
|
|
16
|
-
function getOldReleaseContent(filePath, exists) {
|
|
16
|
+
async function getOldReleaseContent(filePath, exists) {
|
|
17
17
|
if (exists) {
|
|
18
|
-
const fileContents =
|
|
18
|
+
const fileContents = await readFile(filePath, "utf8");
|
|
19
19
|
const oldContentStart = fileContents.search(RELEASE_PATTERN);
|
|
20
20
|
if (oldContentStart !== -1) return fileContents.substring(oldContentStart);
|
|
21
21
|
}
|
|
@@ -56,11 +56,11 @@ async function updateChangelog(config, logger, nextVersion) {
|
|
|
56
56
|
const changelogPath = resolve(config.path, config.changelog);
|
|
57
57
|
if (!config.dryRun && !fileExists(changelogPath)) {
|
|
58
58
|
logger.log(`Creating changelog: ${changelogPath}`);
|
|
59
|
-
|
|
59
|
+
await writeFile(changelogPath, "\n", "utf8");
|
|
60
60
|
} else logger.log(`Updating changelog: ${changelogPath}`);
|
|
61
|
-
const oldContent = getOldReleaseContent(changelogPath, fileExists(changelogPath));
|
|
61
|
+
const oldContent = await getOldReleaseContent(changelogPath, fileExists(changelogPath));
|
|
62
62
|
const newContent = await getNewReleaseContent(config, logger, nextVersion);
|
|
63
|
-
if (!config.dryRun && newContent)
|
|
63
|
+
if (!config.dryRun && newContent) await writeFile(changelogPath, `${config.header}
|
|
64
64
|
${newContent}
|
|
65
65
|
${oldContent}
|
|
66
66
|
`.trim(), "utf8");
|
package/dist/process/commit.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { ForkConfig } from "../config/types.js";
|
|
2
1
|
import { Logger } from "../services/logger.js";
|
|
3
2
|
import { FileState } from "../files/file-manager.js";
|
|
3
|
+
import { ForkConfig } from "../config/types.js";
|
|
4
4
|
import { Git } from "../services/git.js";
|
|
5
5
|
|
|
6
6
|
//#region src/process/commit.d.ts
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { ForkConfig } from "../config/types.js";
|
|
2
1
|
import { Logger } from "../services/logger.js";
|
|
3
2
|
import { FileManager, FileState } from "../files/file-manager.js";
|
|
3
|
+
import { ForkConfig } from "../config/types.js";
|
|
4
4
|
import { Git } from "../services/git.js";
|
|
5
5
|
|
|
6
6
|
//#region src/process/get-current-version.d.ts
|
|
@@ -8,7 +8,7 @@ async function getCurrentVersion(config, logger, git, fileManager, filesToUpdate
|
|
|
8
8
|
logger.debug(`[Git Ignored] ${file}`);
|
|
9
9
|
continue;
|
|
10
10
|
}
|
|
11
|
-
const fileState = fileManager.read(file);
|
|
11
|
+
const fileState = await fileManager.read(file);
|
|
12
12
|
if (fileState) {
|
|
13
13
|
files.push(fileState);
|
|
14
14
|
if (!config.currentVersion) versions.add(fileState.version);
|
package/dist/process/tag.d.ts
CHANGED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
//#region src/utils/extract-build-metadata.ts
|
|
2
|
+
/**
|
|
3
|
+
* This function is used to separate build metadata from the version string.
|
|
4
|
+
* Build metadata is denoted by a plus sign (`+`) followed by a string of characters.
|
|
5
|
+
*
|
|
6
|
+
* Example version strings including build metadata:
|
|
7
|
+
* - `1.2.3+49a3f2b`
|
|
8
|
+
* - `1.2.3-0+49a3f2b`
|
|
9
|
+
* - `1.2.3-alpha.0+49a3f2b`
|
|
10
|
+
*
|
|
11
|
+
* In the above examples, the build metadata is `+49a3f2b`, which should be
|
|
12
|
+
* ignored when determining the next version.
|
|
13
|
+
*
|
|
14
|
+
* @param version The version string to extract build metadata from.
|
|
15
|
+
* @return Both the version string without build metadata and the extracted build metadata (if any).
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* const versionWithMetadata = "1.2.3+49a3f2b";
|
|
20
|
+
* const { version, buildMetadata } = extractBuildMetadata(versionWithMetadata);
|
|
21
|
+
* console.log(version); // Output: "1.2.3"
|
|
22
|
+
* console.log(buildMetadata); // Output: "49a3f2b"
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
function extractBuildMetadata(version) {
|
|
26
|
+
const plusIndex = version.indexOf("+");
|
|
27
|
+
if (plusIndex === -1) return {
|
|
28
|
+
version,
|
|
29
|
+
buildMetadata: void 0
|
|
30
|
+
};
|
|
31
|
+
return {
|
|
32
|
+
version: version.substring(0, plusIndex),
|
|
33
|
+
buildMetadata: version.substring(plusIndex + 1) || void 0
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
//#endregion
|
|
37
|
+
export { extractBuildMetadata };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fork-version",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.1.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Fork-Version automates version control tasks such as determining, updating, and committing versions, files, and changelogs, simplifying the process when adhering to the conventional commit standard.",
|
|
6
6
|
"keywords": [
|