Compare commits
No commits in common. "063ee5d02b522bf666ffa8c2a8455c305011781f" and "0d1fca8dbb5a90ef3454f4ccb1da286aabcd4e84" have entirely different histories.
063ee5d02b
...
0d1fca8dbb
86
README.md
86
README.md
@ -1,86 +0,0 @@
|
|||||||
# Changelord, registrar of deeds extraordinaire
|
|
||||||
|
|
||||||
Changelord is a changelog manager scratching my particular itches.
|
|
||||||
It's cli-based, and keep its data in a YAML file adhering
|
|
||||||
to a well-defined schema.
|
|
||||||
|
|
||||||
The first iteration of `changelord` was written [in Perl][original]. You can
|
|
||||||
read its [introductory article][blog] on my blog.
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
pnpm install changelord
|
|
||||||
|
|
||||||
## CLI commands
|
|
||||||
|
|
||||||
### Global options
|
|
||||||
|
|
||||||
#### `--help`
|
|
||||||
|
|
||||||
Outputs the list of commands and options.
|
|
||||||
|
|
||||||
#### `--version`
|
|
||||||
|
|
||||||
Outputs the `changelord` version.
|
|
||||||
|
|
||||||
#### `--source`
|
|
||||||
|
|
||||||
Specifies which source yaml file to use. Defaults to the `CHANGELOG.yml` file
|
|
||||||
in the current directory.
|
|
||||||
|
|
||||||
### `changelord init`
|
|
||||||
|
|
||||||
Initializes the changelog source file. The YAML file is made of three
|
|
||||||
sections.
|
|
||||||
|
|
||||||
- `project` -- contains information and configuration about the project itself.
|
|
||||||
- `releases` -- the entries for the changelog proper.
|
|
||||||
- `change_types` -- defines all types of changes this project supports.
|
|
||||||
|
|
||||||
### `changelord add`
|
|
||||||
|
|
||||||
Adds an entry to the `NEXT` release.
|
|
||||||
|
|
||||||
$ changelord add --type=maint added a changelog to the project.
|
|
||||||
|
|
||||||
#### Options
|
|
||||||
|
|
||||||
- `--type` -- type of change.
|
|
||||||
- `--ticket` -- associated ticket.
|
|
||||||
|
|
||||||
### `changelord print`
|
|
||||||
|
|
||||||
Renders the changelog as markdown.
|
|
||||||
|
|
||||||
#### Options
|
|
||||||
|
|
||||||
- `--no-next` -- don't show the `NEXT` section.
|
|
||||||
|
|
||||||
### `changelord cut`
|
|
||||||
|
|
||||||
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
|
|
||||||
today. Modifies the source file with the result.
|
|
||||||
|
|
||||||
#### Options
|
|
||||||
|
|
||||||
- `--dry` -- Resolves the next version but only outputs the resulting section
|
|
||||||
without changing the source file.
|
|
||||||
|
|
||||||
### `changelord schema`
|
|
||||||
|
|
||||||
Outputs the JSON schema defining the structure of the source file.
|
|
||||||
|
|
||||||
### `changelord upcoming`
|
|
||||||
|
|
||||||
Outputs the changes listed in the `NEXT` release.
|
|
||||||
|
|
||||||
### `changelord latest-version`
|
|
||||||
|
|
||||||
Outputs the latest non-NEXT release.
|
|
||||||
|
|
||||||
$ changelord latest-version
|
|
||||||
3.2.0
|
|
||||||
|
|
||||||
[blog]: https://techblog.babyl.ca/entry/changelord/
|
|
||||||
[original]: https://metacpan.org/dist/App-Changelord/view/bin/changelord
|
|
@ -1,22 +1,6 @@
|
|||||||
# https://taskfile.dev
|
# https://taskfile.dev
|
||||||
version: "3"
|
version: '3'
|
||||||
|
|
||||||
vars:
|
|
||||||
PARENT_BRANCH: main
|
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
test: vitest run src
|
test: vitest run src
|
||||||
test:dev: vitest src
|
test:dev: vitest src
|
||||||
|
|
||||||
integrate:
|
|
||||||
deps: [test]
|
|
||||||
preconditions:
|
|
||||||
- sh: git is-clean
|
|
||||||
msg: checkout not clean
|
|
||||||
- sh: git diff-ls {{.PARENT_BRANCH}} | grep test
|
|
||||||
msg: no tests were added
|
|
||||||
- sh: git diff-ls {{.PARENT_BRANCH}} | grep CHANGELOG.yml
|
|
||||||
msg: no changelog entry detected
|
|
||||||
cmds:
|
|
||||||
- git checkout {{.PARENT_BRANCH}}
|
|
||||||
- git weld -
|
|
||||||
|
10
package.json
10
package.json
@ -3,18 +3,10 @@
|
|||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"description": "cli-based changelog manager",
|
"description": "cli-based changelog manager",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "src/changelord.js",
|
"main": "src/index.js",
|
||||||
"bin": {
|
"bin": {
|
||||||
"changelord": "./src/changelord.js"
|
"changelord": "./src/changelord.js"
|
||||||
},
|
},
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://git.babyl.ca/yanick/changelord.js.git"
|
|
||||||
},
|
|
||||||
"bugs": {
|
|
||||||
"url": "https://git.babyl.ca/yanick/changelord.js/issues"
|
|
||||||
},
|
|
||||||
"homepage": "https://git.babyl.ca/yanick/changelord.js",
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
},
|
},
|
||||||
|
@ -13,23 +13,22 @@ import schema from "./command/schema.js";
|
|||||||
import add from "./command/add.js";
|
import add from "./command/add.js";
|
||||||
import cut from "./command/cut.js";
|
import cut from "./command/cut.js";
|
||||||
import upcoming from "./command/upcoming.js";
|
import upcoming from "./command/upcoming.js";
|
||||||
import latest from "./command/latest-version.js";
|
|
||||||
|
|
||||||
consola.raw = (...args) => console.log(...args);
|
consola.raw = (...args) => console.log(...args);
|
||||||
|
|
||||||
yargs(hideBin(process.argv))
|
yargs(hideBin(process.argv))
|
||||||
.config({
|
.config({
|
||||||
consola,
|
consola,
|
||||||
})
|
})
|
||||||
.default("source", join(process.cwd(), "CHANGELOG.yml"))
|
.default("source", join(process.cwd(), "CHANGELOG.yml"))
|
||||||
.describe("source", "changelog source")
|
.describe("source", "changelog source")
|
||||||
.command(init)
|
.command(print)
|
||||||
.command(add)
|
.command(init)
|
||||||
.command(print)
|
.command(add)
|
||||||
.command(cut)
|
.command(schema)
|
||||||
.command(schema)
|
.command(cut)
|
||||||
.command(upcoming)
|
.command(print)
|
||||||
.command(latest)
|
.command(upcoming)
|
||||||
.strictCommands()
|
.strictCommands()
|
||||||
.help()
|
.help()
|
||||||
.parse();
|
.parse();
|
||||||
|
@ -3,51 +3,49 @@ 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`);
|
||||||
|
|
||||||
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")
|
.string("type")
|
||||||
.string("type")
|
.middleware((argv) => {
|
||||||
.describe("type", "type of change")
|
argv.add_to_next = async (entry) => {
|
||||||
.middleware((argv) => {
|
const changelog = yaml.parse(await fs.readFile(argv.source, "utf-8"));
|
||||||
argv.add_to_next = async (entry) => {
|
|
||||||
const changelog = yaml.parse(await fs.readFile(argv.source, "utf-8"));
|
|
||||||
|
|
||||||
let next = changelog.releases.find(u.matches({ version: "NEXT" }));
|
let next = changelog.releases.find(u.matches({ version: "NEXT" }));
|
||||||
if (!next) {
|
if (!next) {
|
||||||
next = { version: "NEXT", changes: [] };
|
next = { version: "NEXT", changes: [] };
|
||||||
changelog.releases.unshift(next);
|
changelog.releases.unshift(next);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Object.keys(entry).length === 1) {
|
if (Object.keys(entry).length === 1) {
|
||||||
entry = entry.desc;
|
entry = entry.desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
next.changes.push(entry);
|
next.changes.push(entry);
|
||||||
|
|
||||||
return fs.writeFile(argv.source, yaml.stringify(changelog));
|
return fs.writeFile(argv.source, yaml.stringify(changelog));
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
handler,
|
handler,
|
||||||
};
|
};
|
||||||
|
@ -6,7 +6,7 @@ import { simpleGit } from "simple-git";
|
|||||||
|
|
||||||
const code_churn = async (previous_version) => {
|
const code_churn = async (previous_version) => {
|
||||||
previous_version = previous_version
|
previous_version = previous_version
|
||||||
? "v" + previous_version.version
|
? "v" + previous_version
|
||||||
: "4b825dc642cb6eb9a060e54bf8d69288fbee4904"; // empty tree sha1
|
: "4b825dc642cb6eb9a060e54bf8d69288fbee4904"; // empty tree sha1
|
||||||
|
|
||||||
return simpleGit().diff(["--shortstat", previous_version, "HEAD"]);
|
return simpleGit().diff(["--shortstat", previous_version, "HEAD"]);
|
||||||
@ -47,10 +47,7 @@ const handler = async (config) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
next.version = semverInc(
|
next.version = semverInc(previous_version ?? "0.0.0", bumper);
|
||||||
previous_version ? previous_version.version : "0.0.0",
|
|
||||||
bumper
|
|
||||||
);
|
|
||||||
|
|
||||||
if (config.dry) {
|
if (config.dry) {
|
||||||
config.consola.info("running in dry mode, not saving\n", next);
|
config.consola.info("running in dry mode, not saving\n", next);
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
import yaml from "yaml";
|
|
||||||
import fs from "fs-extra";
|
|
||||||
|
|
||||||
const handler = async (config) => {
|
|
||||||
const changelog = yaml.parse(await fs.readFile(config.source, "utf-8"));
|
|
||||||
|
|
||||||
const latest_version = changelog.releases.find(
|
|
||||||
({ version }) => version !== "NEXT"
|
|
||||||
);
|
|
||||||
|
|
||||||
if (config.json) {
|
|
||||||
config.consola.raw(latest_version);
|
|
||||||
} else {
|
|
||||||
config.consola.raw(latest_version.version);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export default {
|
|
||||||
command: "latest-version",
|
|
||||||
desc: "output the latest version present in the changelog",
|
|
||||||
builder: (yargs) => {
|
|
||||||
yargs
|
|
||||||
.boolean("json")
|
|
||||||
.describe("json", "output latest version entry as json");
|
|
||||||
},
|
|
||||||
handler,
|
|
||||||
};
|
|
Loading…
Reference in New Issue
Block a user