clq

command module
v1.8.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 13, 2024 License: GPL-3.0 Imports: 15 Imported by: 0

README

clq — Changelog validation and query tool

GitHub Release Date version Docker Image Version

ci coverage status Go Report Card GitHub Super-Linter

usage

clq always validates the complete changelog, stopping at its first error. If a query is given, clq then queries the changelog and returns the query result. clq handles standard input — when no arguments are present or an argument is "-" — or any number of files.

clq exits with a status of 0 if all files are valid, and with a non-zero status if any file fails to validate. It writes to standard output the result of the query if a query was given.

clq writes validation error to standard error.

When processing multiple files, clq prefixes every line on standard out and standard error with the filename.

Usage: clq { options } <path to changelog.md>

Options are:
  -changeMap name
      name of a file defining the mapping from change kind to semantic version change
  -output format
      the format to apply to the result of a (complex) query. Supports json and md (markdown); defaults to json
  -query string
      A query to extract information out of the change log
  -release
      Enable release-mode validation
  -with-filename
      Always print filename headers with output lines

Example:

  • clq CHANGELOG.md
    validates the file.
  • clq -release CHANGELOG.md
    validates the file and further enforces that the most recent release is neither [Unreleased] nor has been [YANKED]. This validation is recommended before cutting a release or merging to main.
  • clq -query releases[0].version CHANGELOG.md
    validates the complete changelog and returns the version of the most recent release.
Execution with Docker

A small minimal docker image offers a simple no-installation executable. This image’s label is the release version, with a secondary label ending in -slim, for example: 1.2.3-slim.

A single changelog file can be validated with a simple docker run -i denisa/clq < CHANGELOG.md.

To operate on multiple files is more complex and we recommend either multiple individual invocations, or the installation of native binaries.

Alternatively, the image is compatible with Whalebrew. After a one time installation whalebrew install denisa/clq, a one or more changelog files can be validated with a simple clq CHANGELOG.md or clq */CHANGELOG.md.

The project also generates a 2nd docker image whose label ends wih -alpine, for example: 1.2.3-alpine. This image, larger, is for use by the clq-action.

GitHub action

clq-action documents how to integrate clq in a GitHub workflow.

Grammar for supported Changelog

CHANGELOG       = INTRODUCTION, RELEASES;
INTRODUCTION    = TITLE, { ? markdown paragraph ? };
TITLE           = "# ", ? inline content ?, LINE-ENDING;
RELEASES        = [ UNRELEASED ], { RELEASED | YANKED };
UNRELEASED      = UNRELEASED-HEAD, { CHANGES };
RELEASED        = RELEASED-HEAD, { CHANGES };
YANKED          = YANKED-HEAD, { CHANGES };
UNRELEASED-HEAD = "## [Unreleased]", LINE-ENDING;
RELEASED-HEAD   = "## [", SEMVER, "] - ", ISO-DATE, [ LABEL ], LINE-ENDING;
LABEL           = ? inline content, but not "[YANKED]" ?
YANKED-HEAD     = "## ", SEMVER, " - ", ISO-DATE, " [YANKED]", LINE-ENDING;
CHANGES         = CHANGE-KIND, { CHANGE-DESC };
CHANGE-KIND     = "### ", ( "Added" | "Changed" | "Deprecated" | "Removed" | "Fixed" | "Security" ), LINE-ENDING;
CHANGE-DESC     = "- ", ? inline content ?, LINE-ENDING;
SEMVER          = ? see https://semver.org ?;
ISO-DATE        = YEAR, "-", MONTH, "-" DAY;
YEAR            = DIGIT, DIGIT, DIGIT, DIGIT;
MONTH           = DIGIT, DIGIT;
DAY             = DIGIT, DIGIT;
LINE-ENDING     = "U+000A" | "U+000D" | "U+000DU+000A";
DIGIT           = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9";

Note:

  • The most recent version comes first.
  • The only deviation from the official spec is the optional LABEL on a release entry. The label is convenient for teams that want to highlight individual releases by naming them. Such might be the case for releases cut, for example, for a quarterly demo: ## [1.5.2] - 2019.10.02 Espelho

Validation

clq supports two validation modes, feature and release. The feature mode is best used for feature branches: development work is in progress and the only requirement is for the changelog to be valid but not necessarily current. On the opposite, the release mode applies to release branches and, therefore, pull-requests.

By default, clq operates in the feature mode. In that mode, clq validates that the changelog file conforms to the grammar. It further validates that the releases are sorted chronologically from most recent to oldest, that the versions numbers are properly decreasing and that the version change between any two versions is justified by the change kinds present, according to a mapping from the type of change to the type of version change.

By default, the rules are:

  • major release trigger:
    • Added for new features.
    • Removed for now removed features.
  • minor release trigger:
    • Changed for changes in existing functionality.
    • Deprecated for soon-to-be removed features.
  • bugfix release trigger:
    • Fixed for any bugfixes.
    • Security in case of vulnerabilities.

The changeMap option lets these rules be customized with a simple json file. In this example, an Added section only triggers a minor version change:

[
  {
    "name": "Added",
    "increment": "minor"
  },
  {
    "name": "Changed",
    "increment": "minor"
  },
  {
    "name": "Deprecated",
    "increment": "minor"
  },
  {
    "name": "Fixed",
    "increment": "patch"
  },
  {
    "name": "Removed",
    "increment": "major"
  },
  {
    "name": "Security",
    "increment": "patch"
  }
]

clq is generally lenient with the spaces, accepting them between square brackets for example.

When the release mode is activated (with the -release option), clq further validates that the first entry in the changelog is an actual release entry.

Note that prereleases might or might not be supported at this time.

(Astérix & Obélix, Le tour de Gaule d’Astérix, 1953)

Emoji

The changeMap option further lets emoji be assigned to the change kinds with the optional emoji attribute in the json file. The example extend on the previous one and define emoji for each change kinds:

[
  {
    "name": "Added",
    "increment": "minor",
    "emoji": "✨"
  },
  {
    "name": "Changed",
    "increment": "major",
    "emoji": "💥"
  },
  {
    "name": "Deprecated",
    "increment": "minor",
    "emoji": "👎"
  },
  {
    "name": "Fixed",
    "increment": "patch",
    "emoji": "🐛"
  },
  {
    "name": "Removed",
    "increment": "major",
    "emoji": "🗑️"
  },
  {
    "name": "Security",
    "increment": "patch",
    "emoji": "🔒"
  }
]

Experimental Extension to the standard

It is possible to use the change map file to define other change kinds, be they translation of the standard one, or new ones. It is also possible to assign change kinds to the 'build' SemVer though those cannot be the single contribution of a release, as they would not increment the release number. Please see a French translation and using build for documentation.

Query Expression Language

A query is a sequence of query elements leading through the structure of the changelog to the desired field. The first query element is always a field from the changelog.

QUERY            = ( SIMPLE_QUERY | COMPLEX_QUERY );
SIMPLE_QUERY     = { ARRAY_FIELD, "." }, FIELD;
COMPLEX_QUERY    = { ARRAY_FIELD, "." }, ARRAY_FIELD, ["/"];
ARRAY_FIELD      = FIELD, "[", [SELECTOR], "]";
FIELD            = ? see the Document Model section below ?;
SELECTOR         = DIGIT+;
DIGIT            = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9";

A simple query returns the value of a single field. It is not formatted.

A complex query returns all the values of the selected object. The object is formatted according to the value of the -output option. If the query ends with a "/", it also returns the child elements. If the selector is missing, the query returns a collection of objects.

For the sample changelog

# Change log

## [Unreleased]

### Added

- waldo
- fred

## [1.0.0] - 2020-06-20

### Removed

- foo
- bar
  • releases[1].version
    -> 1.0.0
  • releases[1]
    -> {"version":"1.0.0", "date":"2020-06-20"}
  • releases[0].changes[]
    -> [{"title":"Added"}]
  • releases[0].changes[]/
    -> [{"title":"Added", "descriptions":["waldo", "fred"]}]
Document Model
changelog
  • releases[] all the releases defined in the changelog.
    releases can be indexed, starting at 0, to access a single release.
  • title the title of the changelog
release
  • changes[] all the changes for that release.
    changes cannot be indexed.
  • date the release date, blank if it has not yet been released
  • label the optional release label
  • status one of prereleased, released, unreleased and yanked.
  • title the version, date and optional label
  • version the release version
change
  • descriptions[] all the change descriptions;
    descriptions cannot be indexed.
  • title, the change kind.

Reference

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
internal
changelog
Package changelog keeps track of the current state during the traversal of a changelog document.
Package changelog keeps track of the current state during the traversal of a changelog document.
config
Package config provides methods to track choices made on the command line
Package config provides methods to track choices made on the command line
output
Package output provides for a plugin mechanism through which multiple output formats are supported.
Package output provides for a plugin mechanism through which multiple output formats are supported.
query
Package query implements a simple streaming query language to identify parts of a CHANGELOG.
Package query implements a simple streaming query language to identify parts of a CHANGELOG.
semver
Package semver provides helpers to work with semantic version.
Package semver provides helpers to work with semantic version.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL