Compare commits

..

No commits in common. "04e9e5f71ab354f6a1650e8fbd18c164f04fb5ec" and "1c7b6158f4a4b933614bb513394472f35ba4e7c0" have entirely different histories.

10 changed files with 45 additions and 164 deletions

View File

@ -2,20 +2,21 @@ project:
name: changelord name: changelord
homepage: https://git.babyl.ca/yanick/changelord.js homepage: https://git.babyl.ca/yanick/changelord.js
with_stats: true with_stats: true
next_directory: ./changelog-next
releases: releases:
- version: NEXT - version: NEXT
changes: changes:
- add `git-gather` command
- type: feat - type: feat
desc: add `git-gather` command desc: " add 'next' to alias to 'upcoming'"
- type: feat commit: 363c195477231a6b3b770e74ebfe316296ec5af2
desc: add 'next' to alias to 'upcoming'
- type: feat - type: feat
desc: cutting a release also add a new NEXT release desc: cutting a release also add a new NEXT release
commit: 167f631d1fe4eadba3ed5fdadbe378b8255d4ad2
- type: feat - type: feat
desc: git-gather also filters on descs desc: git-gather also filters on descs
- type: feat - type: feat
desc: add the validate command desc: add the validate command
commit: 5ba75a8e3d42f633e38c3584898ef0085c48fb04
- version: 0.1.0 - version: 0.1.0
changes: changes:
- port the core of the Perl changelord to JavaScript. - port the core of the Perl changelord to JavaScript.

View File

@ -11,14 +11,6 @@ read its [introductory article][blog] on my blog.
pnpm install changelord pnpm install changelord
## `changelog-next` directory
If you want to mininize merge conflicts in `CHANGELOG.yml`,
you can set the option `project.next_directory` to a directory (typically
`./changelog-next`) that will hold yaml files containing the
changes for the NEXT release. Each of those files is expected to
have a list of changes.
## CLI commands ## CLI commands
### Global options ### Global options
@ -49,9 +41,6 @@ sections.
Adds an entry to the `NEXT` release. Adds an entry to the `NEXT` release.
If `project.next_directory` is defined, the entry will be added to that
directory instead of directly into `CHANGELOG.yml`.
$ changelord add --type=maint added a changelog to the project. $ changelord add --type=maint added a changelog to the project.
#### Options #### Options
@ -73,10 +62,6 @@ Cuts the next release. That is, resolves the `NEXT` version number based on the
latest version and the changes in the `NEXT` section, and sets its date as latest version and the changes in the `NEXT` section, and sets its date as
today. Modifies the source file with the result. today. Modifies the source file with the result.
If the `project.next_directory` option is present,
all the changes in that directory are
merged to `CHANGELOG.yml` and the files themselves are deleted.
#### Options #### Options
- `--dry` -- Resolves the next version but only outputs the resulting section - `--dry` -- Resolves the next version but only outputs the resulting section

View File

@ -1,2 +0,0 @@
- desc: support changelog-next directory
type: feat

View File

@ -24,15 +24,11 @@
"author": "Yanick Champoux <yanick@babyl.ca> (http://techblog.babyl.ca/)", "author": "Yanick Champoux <yanick@babyl.ca> (http://techblog.babyl.ca/)",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"@sindresorhus/slugify": "^2.2.1",
"@yanick/updeep-remeda": "^2.2.0", "@yanick/updeep-remeda": "^2.2.0",
"ajv": "^8.12.0", "ajv": "^8.12.0",
"consola": "^3.1.0", "consola": "^3.1.0",
"filenamify": "^6.0.0",
"fs-extra": "^11.1.1", "fs-extra": "^11.1.1",
"globby": "^13.1.4",
"markdown-utils": "^1.0.0", "markdown-utils": "^1.0.0",
"nanoid": "^4.0.2",
"remeda": "^1.14.0", "remeda": "^1.14.0",
"semver": "^7.5.0", "semver": "^7.5.0",
"simple-git": "^3.18.0", "simple-git": "^3.18.0",

View File

@ -50,11 +50,6 @@ export default {
with_stats: { with_stats: {
description: "if true, add git statistics when bumping the version.", description: "if true, add git statistics when bumping the version.",
}, },
next_directory: {
type: "string",
description:
"directory where the changes for the NEXT release are stashed",
},
}, },
type: "object", type: "object",
}, },

View File

@ -10,8 +10,6 @@ import u from "@yanick/updeep-remeda";
import { once } from "remeda"; import { once } from "remeda";
import simpleGit from "simple-git"; import simpleGit from "simple-git";
import Ajv from "ajv"; import Ajv from "ajv";
import { nanoid } from "nanoid";
import slugify from "@sindresorhus/slugify";
import print from "./command/print.js"; import print from "./command/print.js";
import init from "./command/init.js"; import init from "./command/init.js";
@ -23,8 +21,6 @@ import latest, { latest_version } from "./command/latest-version.js";
import validate from "./command/validate.js"; import validate from "./command/validate.js";
import git_gather from "./command/git-gather.js"; import git_gather from "./command/git-gather.js";
import schemaV1 from "./changelog-schema.js"; import schemaV1 from "./changelog-schema.js";
import { globby } from "globby";
import { flatMap } from "remeda";
consola.raw = (...args) => console.log(...args); consola.raw = (...args) => console.log(...args);
@ -36,27 +32,6 @@ yargs(hideBin(process.argv))
fs fs
.readFile(config.source, "utf-8") .readFile(config.source, "utf-8")
.then(yaml.parse) .then(yaml.parse)
.then(async (doc) => {
if (!doc.project.next_directory) return doc;
const changes = await globby([
doc.project.next_directory + "/*.yml",
doc.project.next_directory + "/*.yaml",
])
.then((files) =>
Promise.all(
files.map((f) => fs.readFile(f, "utf-8").then(yaml.parse))
)
)
.then((r) => r.flat());
if (changes.length)
doc.releases
.find((r) => r.version === "NEXT")
.changes.push(...changes);
return doc;
})
.then((doc) => { .then((doc) => {
const ajv = new Ajv(); const ajv = new Ajv();
const validate = ajv.compile(schemaV1); const validate = ajv.compile(schemaV1);
@ -67,13 +42,6 @@ yargs(hideBin(process.argv))
throw "changelog is invalid"; throw "changelog is invalid";
}) })
); );
config.delete_next_dir_entries = async () => {
const changelog = await config.changelog();
return globby([
changelog.project.next_directory + "/*.yml",
changelog.project.next_directory + "/*.yaml",
]).then((files) => Promise.all(files.map((f) => fs.remove(f))));
};
config.save_changelog = async (changelog) => { config.save_changelog = async (changelog) => {
if (!changelog) changelog = await config.changelog(); if (!changelog) changelog = await config.changelog();
return fs.writeFile(config.source, yaml.stringify(changelog)); return fs.writeFile(config.source, yaml.stringify(changelog));
@ -86,39 +54,12 @@ yargs(hideBin(process.argv))
argv.yargs = yargs; argv.yargs = yargs;
argv.add_to_next = async (entry) => { argv.add_to_next = async (entry) => {
const dir = await argv.changelog().then((c) => c.project.next_directory); const changelog = yaml.parse(await fs.readFile(argv.source, "utf-8"));
if (dir) {
await fs.ensureDir(dir);
const filename = join(
dir,
[
new Date().toISOString(),
entry.ticket,
entry.feat,
slugify(entry.desc, {
separator: "_",
}).slice(0, 10),
]
.filter((x) => x)
.join("-") + ".yml"
);
argv.consola.info(`writing change to ${filename}`);
if (fs.existsSync(filename)) {
argv.consola.error(`file ${filename} already exist`);
yargs.exit(1);
}
if (Object.keys(entry).length === 1) {
entry = entry.desc;
}
return fs.writeFile(filename, yaml.stringify([entry]));
}
const changelog = await argv.changelog();
let next = changelog.releases.find(u.matches({ version: "NEXT" })); let next = changelog.releases.find(u.matches({ version: "NEXT" }));
if (!next) { if (!next) {
changelog.releases.unshift(base_next_version); next = { version: "NEXT", changes: [] };
changelog.releases.unshift(next);
} }
if (Object.keys(entry).length === 1) { if (Object.keys(entry).length === 1) {
@ -127,7 +68,7 @@ yargs(hideBin(process.argv))
next.changes.push(entry); next.changes.push(entry);
return argv.save_changelog(); return fs.writeFile(argv.source, yaml.stringify(changelog));
}; };
}) })
.default("source", join(process.cwd(), "CHANGELOG.yml")) .default("source", join(process.cwd(), "CHANGELOG.yml"))

View File

@ -3,32 +3,32 @@ import yaml from "yaml";
import u from "@yanick/updeep-remeda"; import u from "@yanick/updeep-remeda";
const handler = async (config) => { const handler = async (config) => {
if (!config.change) if (!config.change)
throw new Error("can't add a change without a description"); throw new Error("can't add a change without a description");
const entry = { const entry = {
desc: config.change.join(" "), desc: config.change.join(" "),
}; };
if (config.ticket) entry.ticket = config.ticket; if (config.ticket) entry.ticket = config.ticket;
if (config.type) entry.type = config.type; if (config.type) entry.type = config.type;
config.consola.start(`adding '${entry.desc}' to the changelog`); config.consola.start(`adding '${entry.desc}' to the changelog`);
await config.add_to_next(entry); config.add_to_next(entry);
config.consola.success("done!"); config.consola.success("done!");
}; };
export default { export default {
command: "add [change...]", command: "add [change...]",
desc: "add a change to the NEXT release", desc: "add a change to the NEXT release",
builder: (yargs) => { builder: (yargs) => {
yargs yargs
.string("ticket") .string("ticket")
.describe("ticket", "ticket associated with the change") .describe("ticket", "ticket associated with the change")
.string("type") .string("type")
.describe("type", "type of change"); .describe("type", "type of change");
}, },
handler, handler,
}; };

View File

@ -62,12 +62,6 @@ const handler = async (config) => {
config.consola.info("running in dry mode, not saving\n", next); config.consola.info("running in dry mode, not saving\n", next);
} else { } else {
await config.save_changelog(changelog); await config.save_changelog(changelog);
if (changelog.project?.next_directory) {
config.consola.info(
`removing files in ${changelog.project.next_directory}`
);
await config.delete_next_dir_entries();
}
} }
config.consola.success(`version ${next.version} is cut!`); config.consola.success(`version ${next.version} is cut!`);

View File

@ -4,28 +4,28 @@ import yaml from "yaml";
import { render_release } from "./print.js"; import { render_release } from "./print.js";
export async function next_release() { export async function next_release() {
const source = await this.changelog(); const source = await fs.readFile(this.source, "utf-8").then(yaml.parse);
return ( return (
source.releases.find(u.matches({ version: "NEXT" })) ?? { source.releases.find(u.matches({ version: "NEXT" })) ?? {
version: "NEXT", version: "NEXT",
changes: [], changes: [],
} }
); );
} }
const handler = async (config) => { const handler = async (config) => {
const source = await config.changelog(); const source = await fs.readFile(config.source, "utf-8").then(yaml.parse);
const { body } = render_release( const res = render_release(
{ ...config, next: true }, { ...config, next: true },
source source
)(await config.next_release()); )(source.releases.find(u.matches({ version: "NEXT" })));
config.consola.raw("\n" + body); config.consola.raw("\n" + res.body);
}; };
export default { export default {
command: "upcoming", command: "upcoming",
desc: "output the changes in NEXT", desc: "output the changes in NEXT",
handler, handler,
}; };

View File

@ -1,29 +0,0 @@
import { test, expect, vi } from "vitest";
import upcoming from "./upcoming.js";
test("basic", async () => {
const changelog = {
releases: [{ version: "NEXT", changes: [] }, { version: "1.0.0" }],
change_types: [],
};
const noop = () => {};
const config = {
consola: {
start: noop,
raw: vi.fn(),
},
changelog: () => changelog,
next_release: () => ({
changes: [],
}),
latest_version: () => ({ version: "1.2.3" }),
git: () => ({
log: () => ({ all: [] }),
}),
};
await upcoming.handler(config);
expect(config.consola.raw).toHaveBeenCalled();
});