Compare commits
3 Commits
2e9d0d4b66
...
1c7b6158f4
Author | SHA1 | Date | |
---|---|---|---|
1c7b6158f4 | |||
031f2cb825 | |||
5ba75a8e3d |
@ -2,7 +2,6 @@ project:
|
||||
name: changelord
|
||||
homepage: https://git.babyl.ca/yanick/changelord.js
|
||||
with_stats: true
|
||||
ticket_url: null
|
||||
releases:
|
||||
- version: NEXT
|
||||
changes:
|
||||
@ -15,6 +14,9 @@ releases:
|
||||
commit: 167f631d1fe4eadba3ed5fdadbe378b8255d4ad2
|
||||
- type: feat
|
||||
desc: git-gather also filters on descs
|
||||
- type: feat
|
||||
desc: add the validate command
|
||||
commit: 5ba75a8e3d42f633e38c3584898ef0085c48fb04
|
||||
- version: 0.1.0
|
||||
changes:
|
||||
- port the core of the Perl changelord to JavaScript.
|
||||
|
@ -82,6 +82,10 @@ Outputs the latest non-NEXT release.
|
||||
$ changelord latest-version
|
||||
3.2.0
|
||||
|
||||
### `changelord validate`
|
||||
|
||||
Validates the changelog source against its json schema.
|
||||
|
||||
### `changelord git-gather`
|
||||
|
||||
Gathers change entries from git commits. If any are found, they are
|
||||
|
@ -25,6 +25,7 @@
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@yanick/updeep-remeda": "^2.2.0",
|
||||
"ajv": "^8.12.0",
|
||||
"consola": "^3.1.0",
|
||||
"fs-extra": "^11.1.1",
|
||||
"markdown-utils": "^1.0.0",
|
||||
|
113
src/changelog-schema.js
Normal file
113
src/changelog-schema.js
Normal file
@ -0,0 +1,113 @@
|
||||
export default {
|
||||
type: "object",
|
||||
additionalProperties: false,
|
||||
properties: {
|
||||
change_types: {
|
||||
items: {
|
||||
additionalProperties: false,
|
||||
properties: {
|
||||
keywords: {
|
||||
items: {
|
||||
type: "string",
|
||||
},
|
||||
type: "array",
|
||||
},
|
||||
level: {
|
||||
enum: ["major", "minor", "patch"],
|
||||
},
|
||||
title: {
|
||||
type: "string",
|
||||
},
|
||||
},
|
||||
type: "object",
|
||||
},
|
||||
type: "array",
|
||||
},
|
||||
project: {
|
||||
additionalProperties: false,
|
||||
properties: {
|
||||
homepage: {
|
||||
description: "url of the project's homepage",
|
||||
examples: ["https://github.com/yanick/app-changelord"],
|
||||
type: ["string", "null"],
|
||||
},
|
||||
name: {
|
||||
description: "name of the project",
|
||||
examples: ["App::Changelord"],
|
||||
type: ["null", "string"],
|
||||
},
|
||||
ticket_url: {
|
||||
description:
|
||||
"perl code that takes a ticket string (e.g. 'GH123') via the `$_` variable and turns it into a link.",
|
||||
examples: [
|
||||
"s!GH(\\d+)!https://github.com/yanick/App-Changelord/issue/$1/",
|
||||
{
|
||||
'/^\\d+$/ ? "https://.../$_"': "undef",
|
||||
},
|
||||
],
|
||||
type: "string",
|
||||
},
|
||||
with_stats: {
|
||||
description: "if true, add git statistics when bumping the version.",
|
||||
},
|
||||
},
|
||||
type: "object",
|
||||
},
|
||||
releases: {
|
||||
items: {
|
||||
oneOf: [
|
||||
{
|
||||
type: "string",
|
||||
},
|
||||
{
|
||||
additionalProperties: false,
|
||||
properties: {
|
||||
changes: {
|
||||
items: {
|
||||
$ref: "#/$defs/change",
|
||||
},
|
||||
type: "array",
|
||||
},
|
||||
date: {
|
||||
type: ["null", "string"],
|
||||
},
|
||||
version: {
|
||||
type: ["null", "string"],
|
||||
},
|
||||
},
|
||||
type: "object",
|
||||
},
|
||||
],
|
||||
},
|
||||
type: "array",
|
||||
},
|
||||
},
|
||||
$defs: {
|
||||
change: {
|
||||
oneOf: [
|
||||
{
|
||||
type: "string",
|
||||
},
|
||||
{
|
||||
additionalProperties: false,
|
||||
properties: {
|
||||
commit: {
|
||||
type: ["string", "null"],
|
||||
},
|
||||
desc: {
|
||||
type: "string",
|
||||
},
|
||||
ticket: {
|
||||
type: ["string", "null"],
|
||||
},
|
||||
type: {
|
||||
type: ["string", "null"],
|
||||
},
|
||||
},
|
||||
required: ["desc"],
|
||||
type: "object",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
@ -1,59 +0,0 @@
|
||||
type: object
|
||||
additionalProperties: false
|
||||
properties:
|
||||
project:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
properties:
|
||||
homepage:
|
||||
type: [ string, 'null' ]
|
||||
description: url of the project's homepage
|
||||
examples:
|
||||
- https://github.com/yanick/app-changelord
|
||||
name:
|
||||
type: [ 'null', string ]
|
||||
description: name of the project
|
||||
examples:
|
||||
- App::Changelord
|
||||
ticket_url:
|
||||
type: string
|
||||
description: perl code that takes a ticket string (e.g. 'GH123') via the `$_` variable and turns it into a link.
|
||||
examples:
|
||||
- s!GH(\d+)!https://github.com/yanick/App-Changelord/issue/$1/
|
||||
- /^\d+$/ ? "https://.../$_" : undef
|
||||
with_stats:
|
||||
description: if true, add git statistics when bumping the version.
|
||||
change_types:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
properties:
|
||||
keywords:
|
||||
type: array
|
||||
items: { type: string }
|
||||
level: { enum: [ major, minor, patch ] }
|
||||
title: { type: string }
|
||||
releases:
|
||||
type: array
|
||||
items:
|
||||
oneOf:
|
||||
- type: string
|
||||
- type: object
|
||||
additionalProperties: false
|
||||
properties:
|
||||
version: { type: [ 'null', string ] }
|
||||
date: { type: ['null',string] }
|
||||
changes: { type: 'array', items: { $ref: '#/$defs/change' } }
|
||||
$defs:
|
||||
change:
|
||||
oneOf:
|
||||
- type: string
|
||||
- type: object
|
||||
required: [ desc ]
|
||||
additionalProperties: false
|
||||
properties:
|
||||
desc: { type: string }
|
||||
ticket: { type: [ string, 'null' ] }
|
||||
type: { type: [ string, 'null' ] }
|
||||
commit: { type: [ string, 'null' ] }
|
@ -9,6 +9,7 @@ import consola from "consola";
|
||||
import u from "@yanick/updeep-remeda";
|
||||
import { once } from "remeda";
|
||||
import simpleGit from "simple-git";
|
||||
import Ajv from "ajv";
|
||||
|
||||
import print from "./command/print.js";
|
||||
import init from "./command/init.js";
|
||||
@ -17,7 +18,9 @@ import add from "./command/add.js";
|
||||
import cut from "./command/cut.js";
|
||||
import upcoming, { next_release } from "./command/upcoming.js";
|
||||
import latest, { latest_version } from "./command/latest-version.js";
|
||||
import validate from "./command/validate.js";
|
||||
import git_gather from "./command/git-gather.js";
|
||||
import schemaV1 from "./changelog-schema.js";
|
||||
|
||||
consola.raw = (...args) => console.log(...args);
|
||||
|
||||
@ -26,7 +29,18 @@ yargs(hideBin(process.argv))
|
||||
config.git = once(simpleGit);
|
||||
config.consola = consola;
|
||||
config.changelog = once(() =>
|
||||
fs.readFile(config.source, "utf-8").then(yaml.parse)
|
||||
fs
|
||||
.readFile(config.source, "utf-8")
|
||||
.then(yaml.parse)
|
||||
.then((doc) => {
|
||||
const ajv = new Ajv();
|
||||
const validate = ajv.compile(schemaV1);
|
||||
const valid = validate(doc);
|
||||
if (valid) return doc;
|
||||
|
||||
config.consola.error("invalid changelog: ", validate.errors);
|
||||
throw "changelog is invalid";
|
||||
})
|
||||
);
|
||||
config.save_changelog = async (changelog) => {
|
||||
if (!changelog) changelog = await config.changelog();
|
||||
@ -36,7 +50,9 @@ yargs(hideBin(process.argv))
|
||||
config.latest_version = latest_version.bind(config);
|
||||
return config;
|
||||
})
|
||||
.middleware((argv) => {
|
||||
.middleware((argv, yargs) => {
|
||||
argv.yargs = yargs;
|
||||
|
||||
argv.add_to_next = async (entry) => {
|
||||
const changelog = yaml.parse(await fs.readFile(argv.source, "utf-8"));
|
||||
|
||||
@ -70,6 +86,7 @@ yargs(hideBin(process.argv))
|
||||
})
|
||||
.command(latest)
|
||||
.command(git_gather)
|
||||
.command(validate)
|
||||
.strictCommands()
|
||||
.help()
|
||||
.parse();
|
||||
|
@ -19,7 +19,6 @@ export const base_changelog = {
|
||||
name: null,
|
||||
homepage: null,
|
||||
with_stats: true,
|
||||
ticket_url: null,
|
||||
},
|
||||
releases: [{ version: "NEXT", changes: [] }],
|
||||
change_types,
|
||||
|
@ -103,7 +103,7 @@ export const render_release = (config, source) => (release) => {
|
||||
};
|
||||
|
||||
const handler = async (config) => {
|
||||
const source = await fs.readFile(config.source, "utf-8").then(yaml.parse);
|
||||
const source = await config.changelog();
|
||||
|
||||
let output = "";
|
||||
|
||||
|
@ -1,12 +1,9 @@
|
||||
import fs from "fs-extra";
|
||||
import yaml from "yaml";
|
||||
import schemaV1 from "../changelog-schema.js";
|
||||
|
||||
const handler = async ({ consola }) => {
|
||||
consola.raw(
|
||||
await fs.readFile(
|
||||
new URL("../changelog-schema.yml", import.meta.url),
|
||||
"utf-8"
|
||||
)
|
||||
);
|
||||
consola.raw(yaml.stringify(schemaV1));
|
||||
};
|
||||
|
||||
export default {
|
||||
|
16
src/command/validate.js
Normal file
16
src/command/validate.js
Normal file
@ -0,0 +1,16 @@
|
||||
const handler = async (config) => {
|
||||
config.consola.start("validating changelog...");
|
||||
|
||||
try {
|
||||
await config.changelog();
|
||||
config.consola.success("valid!");
|
||||
} catch (e) {
|
||||
config.yargs.exit(1, "changelog is invalid :-(");
|
||||
}
|
||||
};
|
||||
|
||||
export default {
|
||||
command: "validate",
|
||||
desc: "validate the changelog against its json schema",
|
||||
handler,
|
||||
};
|
16
src/command/validate.test.js
Normal file
16
src/command/validate.test.js
Normal file
@ -0,0 +1,16 @@
|
||||
import { test, expect, vi } from "vitest";
|
||||
import validate from "./validate.js";
|
||||
|
||||
test("basic", async () => {
|
||||
const success = vi.fn();
|
||||
const noop = () => true;
|
||||
await validate.handler({
|
||||
changelog: () => ({}),
|
||||
consola: {
|
||||
start: noop,
|
||||
success,
|
||||
},
|
||||
});
|
||||
|
||||
expect(success).toHaveBeenCalled();
|
||||
});
|
Loading…
Reference in New Issue
Block a user