mirror of
https://github.com/git-chglog/git-chglog.git
synced 2026-01-23 18:35:06 +00:00
Compare commits
68 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
83fc0386ad | ||
|
|
65fd9c7cb6 | ||
|
|
6a6993d52d | ||
|
|
09d3a61821 | ||
|
|
d93ef22384 | ||
|
|
ffadcdb2f8 | ||
|
|
09ccd2f09b | ||
|
|
d7f33d0797 | ||
|
|
78063fb71f | ||
|
|
06336286cf | ||
|
|
6ad9b5c2db | ||
|
|
26c9a7c721 | ||
|
|
f3cf5b67a0 | ||
|
|
b0f4afeff4 | ||
|
|
f608376b8d | ||
|
|
6ff4d21a0e | ||
|
|
13cb5b3dc4 | ||
|
|
1dbe8da4a3 | ||
|
|
7d4f3e8dff | ||
|
|
36320619c5 | ||
|
|
4f3ff62db6 | ||
|
|
5896ad91ce | ||
|
|
cbab5b89dc | ||
|
|
66a1d9ea5a | ||
|
|
d1dc1da744 | ||
|
|
03f0a44924 | ||
|
|
9558380243 | ||
|
|
3d8006051f | ||
|
|
2861505ecb | ||
|
|
899c1ede45 | ||
|
|
93707ab667 | ||
|
|
7a3896821b | ||
|
|
0022ecf864 | ||
|
|
82ead28bee | ||
|
|
21b98bd56f | ||
|
|
45e01f0f7f | ||
|
|
6a18b6ef90 | ||
|
|
b38b5032cf | ||
|
|
9842899ea1 | ||
|
|
ac01b30c39 | ||
|
|
cefdc53e29 | ||
|
|
c257740de9 | ||
|
|
bfac4702a7 | ||
|
|
57aad771c8 | ||
|
|
bc0f363327 | ||
|
|
fdd421b057 | ||
|
|
7cc56b1256 | ||
|
|
f76afed086 | ||
|
|
2307bff72f | ||
|
|
8d9e00b699 | ||
|
|
b02996e027 | ||
|
|
2f5b47b0f7 | ||
|
|
4f3fdc4dae | ||
|
|
e523fd471a | ||
|
|
34b9d5c997 | ||
|
|
b44eb4e011 | ||
|
|
4d8b2b6be7 | ||
|
|
3113e42524 | ||
|
|
9a0d584745 | ||
|
|
2caa67cc76 | ||
|
|
9926e07971 | ||
|
|
ebff3d0beb | ||
|
|
9a1a9a525c | ||
|
|
ae3382b7c8 | ||
|
|
2c3d3f400e | ||
|
|
c3ee560429 | ||
|
|
500a5db7e9 | ||
|
|
a7ea397268 |
55 changed files with 1877 additions and 564 deletions
|
|
@ -1,21 +0,0 @@
|
|||
version: "{build}"
|
||||
|
||||
clone_depth: 1
|
||||
clone_folder: c:\gopath\src\github.com\git-chglog\git-chglog
|
||||
|
||||
environment:
|
||||
GOPATH: c:\gopath
|
||||
|
||||
install:
|
||||
- echo %PATH%
|
||||
- echo %GOPATH%
|
||||
- go version
|
||||
- go env
|
||||
- set PATH=%PATH%;%GOPATH%\bin
|
||||
|
||||
test_script:
|
||||
- go build github.com/git-chglog/git-chglog/cmd/git-chglog
|
||||
- for /f "" %%G in ('go list github.com/git-chglog/git-chglog/...') do ( go test -v %%G & IF ERRORLEVEL == 1 EXIT 1)
|
||||
|
||||
build: off
|
||||
deploy: off
|
||||
|
|
@ -29,6 +29,13 @@
|
|||
{{ end }}
|
||||
{{ end -}}
|
||||
|
||||
{{- if .MergeCommits -}}
|
||||
### Pull Requests
|
||||
{{ range .MergeCommits -}}
|
||||
- {{ .Header }}
|
||||
{{ end }}
|
||||
{{ end -}}
|
||||
|
||||
{{- if .NoteGroups -}}
|
||||
{{ range .NoteGroups -}}
|
||||
### {{ .Title }}
|
||||
|
|
|
|||
|
|
@ -11,16 +11,19 @@ options:
|
|||
- fix
|
||||
- perf
|
||||
- refactor
|
||||
- chore
|
||||
commit_groups:
|
||||
title_maps:
|
||||
feat: Features
|
||||
fix: Bug Fixes
|
||||
perf: Performance Improvements
|
||||
refactor: Code Refactoring
|
||||
chore: Chores
|
||||
header:
|
||||
pattern: "^(\\w*)\\:\\s(.*)$"
|
||||
pattern: "^(\\w*)(?:\\(([\\w\\$\\.\\-\\*\\s]*)\\))?\\:\\s(.*)$"
|
||||
pattern_maps:
|
||||
- Type
|
||||
- Scope
|
||||
- Subject
|
||||
notes:
|
||||
keywords:
|
||||
|
|
|
|||
105
.github/workflows/ci.yml
vendored
Normal file
105
.github/workflows/ci.yml
vendored
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
name: ci
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: ["opened", "synchronize"]
|
||||
paths-ignore:
|
||||
- "README.md"
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths-ignore:
|
||||
- "README.md"
|
||||
|
||||
env:
|
||||
GO_VERSION: "1.24"
|
||||
GOLANGCI_VERSION: "v1.64.8"
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
|
||||
- name: Run tests
|
||||
run: make test
|
||||
|
||||
- name: Install goveralls
|
||||
run: |
|
||||
go install github.com/mattn/goveralls@latest
|
||||
echo $GOPATH
|
||||
ls -lash $GOPATH
|
||||
which goveralls
|
||||
working-directory: /tmp
|
||||
|
||||
- name: Send coverage
|
||||
run: goveralls -coverprofile=cover.out -service=github
|
||||
env:
|
||||
COVERALLS_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
lint:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@v6
|
||||
with:
|
||||
version: ${{ env.GOLANGCI_VERSION }}
|
||||
|
||||
docker-image-tests:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
|
||||
- name: Run tests
|
||||
run: make build
|
||||
|
||||
- name: Test docker image
|
||||
run: |
|
||||
docker build -t git-chglog:ci-build .
|
||||
docker run -v ${GITHUB_WORKSPACE}:/workdir -w /workdir git-chglog:ci-build > ${GITHUB_WORKSPACE}/ci-build.md
|
||||
head ${GITHUB_WORKSPACE}/ci-build.md
|
||||
|
||||
goreleaser-test:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
|
||||
- name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v4
|
||||
with:
|
||||
version: latest
|
||||
args: release --clean --skip=publish --snapshot
|
||||
34
.github/workflows/publish.yml
vendored
Normal file
34
.github/workflows/publish.yml
vendored
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
name: publish
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
env:
|
||||
GO_VERSION: "1.24"
|
||||
DOCKER_REGISTRY: "quay.io"
|
||||
|
||||
jobs:
|
||||
docker:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
|
||||
- name: Login to Docker Registry
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ${{ env.DOCKER_REGISTRY }}
|
||||
username: ${{ secrets.QUAY_IO_USER }}
|
||||
password: ${{ secrets.QUAY_IO_TOKEN }}
|
||||
|
||||
- name: Build and Push docker image
|
||||
run: DOCKER_TAG=edge make docker push
|
||||
27
.github/workflows/release.yml
vendored
27
.github/workflows/release.yml
vendored
|
|
@ -1,26 +1,39 @@
|
|||
name: goreleaser
|
||||
name: release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- '*'
|
||||
- "*"
|
||||
|
||||
env:
|
||||
GO_VERSION: "1.24"
|
||||
DOCKER_REGISTRY: "quay.io"
|
||||
|
||||
jobs:
|
||||
goreleaser:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v2
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: 1.15
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
|
||||
- name: Login to Docker Registry
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ${{ env.DOCKER_REGISTRY }}
|
||||
username: ${{ secrets.QUAY_IO_USER }}
|
||||
password: ${{ secrets.QUAY_IO_TOKEN }}
|
||||
|
||||
- name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v2
|
||||
uses: goreleaser/goreleaser-action@v4
|
||||
with:
|
||||
version: latest
|
||||
args: release --rm-dist
|
||||
args: release --clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GORELEASER_TOKEN }}
|
||||
|
|
|
|||
37
.github/workflows/test.yml
vendored
37
.github/workflows/test.yml
vendored
|
|
@ -1,37 +0,0 @@
|
|||
name: tests
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: ['opened', 'synchronize']
|
||||
paths-ignore:
|
||||
- 'README.md'
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths-ignore:
|
||||
- 'README.md'
|
||||
jobs:
|
||||
unit:
|
||||
runs-on: ubuntu-20.04
|
||||
strategy:
|
||||
fail-fast: true
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.15
|
||||
- name: Run tests
|
||||
run: |
|
||||
make test
|
||||
- name: Install goveralls
|
||||
env:
|
||||
GO111MODULE: off
|
||||
run: go get github.com/mattn/goveralls
|
||||
- name: Send coverage
|
||||
env:
|
||||
COVERALLS_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: goveralls -coverprofile=cover.out -service=github
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -39,6 +39,9 @@ Icon
|
|||
*.iml
|
||||
.idea
|
||||
|
||||
# vscode IDE
|
||||
.vscode
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
|
|
|
|||
103
.golangci.yml
Normal file
103
.golangci.yml
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
# https://golangci-lint.run/usage/configuration/
|
||||
run:
|
||||
timeout: 10m
|
||||
|
||||
tests: true
|
||||
|
||||
linters-settings:
|
||||
gofmt:
|
||||
# simplify code: gofmt with `-s` option, true by default
|
||||
simplify: true
|
||||
|
||||
goimports:
|
||||
# put imports beginning with prefix after 3rd-party packages;
|
||||
# it's a comma-separated list of prefixes
|
||||
local-prefixes: github.com/git-chglog/git-chglog
|
||||
|
||||
gocyclo:
|
||||
# minimal code complexity to report, 30 by default (but we recommend 10-20)
|
||||
min-complexity: 10
|
||||
|
||||
dupl:
|
||||
# tokens count to trigger issue, 150 by default
|
||||
threshold: 100
|
||||
|
||||
goconst:
|
||||
# minimal length of string constant, 3 by default
|
||||
min-len: 3
|
||||
# minimal occurrences count to trigger, 3 by default
|
||||
min-occurrences: 5
|
||||
|
||||
lll:
|
||||
# tab width in spaces. Default to 1.
|
||||
tab-width: 1
|
||||
|
||||
unparam:
|
||||
# Inspect exported functions, default is false. Set to true if no external program/library imports your code.
|
||||
# XXX: if you enable this setting, unparam will report a lot of false-positives in text editors:
|
||||
# if it's called for subdir of a project it can't find external interfaces. All text editor integrations
|
||||
# with golangci-lint call it on a directory with the changed file.
|
||||
check-exported: false
|
||||
|
||||
nakedret:
|
||||
# make an issue if func has more lines of code than this setting and it has naked returns; default is 30
|
||||
max-func-lines: 30
|
||||
|
||||
prealloc:
|
||||
# XXX: we don't recommend using this linter before doing performance profiling.
|
||||
# For most programs usage of prealloc will be a premature optimization.
|
||||
|
||||
# Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.
|
||||
# True by default.
|
||||
simple: true
|
||||
range-loops: true # Report preallocation suggestions on range loops, true by default
|
||||
for-loops: false # Report preallocation suggestions on for loops, false by default
|
||||
|
||||
misspell:
|
||||
locale: US
|
||||
|
||||
linters:
|
||||
enable:
|
||||
- gosimple
|
||||
- staticcheck
|
||||
- unused
|
||||
- gocyclo
|
||||
- goconst
|
||||
- goimports
|
||||
- gofmt # We enable this as well as goimports for its simplify mode.
|
||||
- prealloc
|
||||
- unconvert
|
||||
- misspell
|
||||
- nakedret
|
||||
- dupl
|
||||
#- depguard TODO fix later
|
||||
|
||||
presets:
|
||||
- bugs
|
||||
- unused
|
||||
fast: false
|
||||
|
||||
issues:
|
||||
# Excluding configuration per-path and per-linter
|
||||
exclude-rules:
|
||||
# Exclude some linters from running on tests files.
|
||||
- path: _test(ing)?\.go
|
||||
linters:
|
||||
- gocyclo
|
||||
- errcheck
|
||||
- dupl
|
||||
- gosec
|
||||
- unparam
|
||||
- testifylint
|
||||
- depguard
|
||||
|
||||
# Show only new issues: if there are unstaged changes or untracked files,
|
||||
# only those changes are analyzed, else only changes in HEAD~ are analyzed.
|
||||
# It's a super-useful option for integration of golangci-lint into existing
|
||||
# large codebase. It's not practical to fix all existing issues at the moment
|
||||
# of integration: much better don't allow issues in new code.
|
||||
# Default is false.
|
||||
new: false
|
||||
|
||||
# Maximum count of issues with the same text. Set to 0 to disable. Default is 3.
|
||||
max-same-issues: 0
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
version: 2
|
||||
|
||||
# This is an example .goreleaser.yml file with some sane defaults.
|
||||
# Make sure to check the documentation at http://goreleaser.com
|
||||
project_name: git-chglog
|
||||
|
|
@ -16,11 +18,10 @@ builds:
|
|||
- windows
|
||||
- darwin
|
||||
goarch:
|
||||
- 386
|
||||
- amd64
|
||||
- arm
|
||||
- arm64
|
||||
goarm:
|
||||
- 6
|
||||
|
||||
archives:
|
||||
- format_overrides:
|
||||
|
|
@ -28,19 +29,24 @@ archives:
|
|||
format: zip
|
||||
|
||||
checksum:
|
||||
name_template: 'checksums.txt'
|
||||
name_template: "checksums.txt"
|
||||
|
||||
changelog:
|
||||
sort: desc
|
||||
filters:
|
||||
exclude:
|
||||
- '^Merge'
|
||||
- "^Merge"
|
||||
|
||||
snapshot:
|
||||
name_template: "{{ .Tag }}-next"
|
||||
|
||||
dockers:
|
||||
- image_templates:
|
||||
- "quay.io/git-chglog/git-chglog:{{ .RawVersion }}"
|
||||
- "quay.io/git-chglog/git-chglog:latest"
|
||||
|
||||
brews:
|
||||
- tap:
|
||||
- repository:
|
||||
owner: git-chglog
|
||||
name: homebrew-git-chglog
|
||||
homepage: "https://godoc.org/github.com/git-chglog/git-chglog"
|
||||
|
|
@ -48,4 +54,4 @@ brews:
|
|||
test: |
|
||||
system "#{bin}/git-chglog --help"
|
||||
install: |
|
||||
bin.install "git-chglog"
|
||||
bin.install "git-chglog"
|
||||
|
|
|
|||
323
CHANGELOG.md
323
CHANGELOG.md
|
|
@ -1,38 +1,203 @@
|
|||
# CHANGELOG
|
||||
All notable changes to this project will be documented in this file.
|
||||
This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html)
|
||||
|
||||
<a name="unreleased"></a>
|
||||
## [Unreleased]
|
||||
|
||||
|
||||
<a name="v0.15.4"></a>
|
||||
## [v0.15.4] - 2023-02-15
|
||||
### Bug Fixes
|
||||
- release process ([#231](https://github.com/git-chglog/git-chglog/issues/231))
|
||||
- **ci:** add integration test with docker image ([#226](https://github.com/git-chglog/git-chglog/issues/226))
|
||||
- **deps:** update module github.com/urfave/cli/v2 to v2.24.3 ([#227](https://github.com/git-chglog/git-chglog/issues/227))
|
||||
- **deps:** update module github.com/fatih/color to v1.14.1 ([#224](https://github.com/git-chglog/git-chglog/issues/224))
|
||||
- **deps:** update all non-major dependencies ([#223](https://github.com/git-chglog/git-chglog/issues/223))
|
||||
|
||||
### Chores
|
||||
- new release due to shecksum mismatch. Closes [#232](https://github.com/git-chglog/git-chglog/issues/232)
|
||||
- update changelog for v0.15.3
|
||||
- update changelog for v0.15.3
|
||||
- bump docker/login-action to v2. Closes [#206](https://github.com/git-chglog/git-chglog/issues/206)
|
||||
- bump goreleaser/goreleaser-action to v4. Closes [#208](https://github.com/git-chglog/git-chglog/issues/208)
|
||||
|
||||
|
||||
<a name="v0.15.2"></a>
|
||||
## [v0.15.2] - 2023-01-22
|
||||
### Bug Fixes
|
||||
- typo in readme ([#196](https://github.com/git-chglog/git-chglog/issues/196))
|
||||
- **deps:** update module gopkg.in/yaml.v2 to v3 ([#221](https://github.com/git-chglog/git-chglog/issues/221))
|
||||
|
||||
### Chores
|
||||
- update changelog for v0.15.2
|
||||
- update changelog for v0.15.2
|
||||
- update Go install instructions ([#205](https://github.com/git-chglog/git-chglog/issues/205))
|
||||
- bump golang to 1.19 ([#218](https://github.com/git-chglog/git-chglog/issues/218))
|
||||
- **deps:** update all non-major dependencies ([#220](https://github.com/git-chglog/git-chglog/issues/220))
|
||||
|
||||
|
||||
<a name="v0.15.1"></a>
|
||||
## [v0.15.1] - 2021-12-14
|
||||
### Bug Fixes
|
||||
- **deps:** update all non-major dependencies ([#179](https://github.com/git-chglog/git-chglog/issues/179))
|
||||
- **deps:** update module github.com/andygrunwald/go-jira to v1.14.0 ([#167](https://github.com/git-chglog/git-chglog/issues/167))
|
||||
- **deps:** update module github.com/alecaivazis/survey/v2 to v2.2.16 ([#165](https://github.com/git-chglog/git-chglog/issues/165))
|
||||
- **deps:** update module github.com/alecaivazis/survey/v2 to v2.2.15 ([#163](https://github.com/git-chglog/git-chglog/issues/163))
|
||||
|
||||
### Chores
|
||||
- update changelog for v0.15.1
|
||||
- ignore .vscode
|
||||
- **deps:** update all non-major dependencies docker tags ([#168](https://github.com/git-chglog/git-chglog/issues/168))
|
||||
|
||||
|
||||
<a name="v0.15.0"></a>
|
||||
## [v0.15.0] - 2021-07-09
|
||||
### Bug Fixes
|
||||
- **deps:** update module github.com/alecaivazis/survey/v2 to v2.2.14 ([#158](https://github.com/git-chglog/git-chglog/issues/158))
|
||||
- **deps:** update module github.com/alecaivazis/survey/v2 to v2.2.13 ([#156](https://github.com/git-chglog/git-chglog/issues/156))
|
||||
- **deps:** update module github.com/fatih/color to v1.12.0 ([#150](https://github.com/git-chglog/git-chglog/issues/150))
|
||||
- **deps:** update module github.com/fatih/color to v1.11.0 ([#149](https://github.com/git-chglog/git-chglog/issues/149))
|
||||
- **deps:** update module github.com/alecaivazis/survey/v2 to v2.2.12 ([#147](https://github.com/git-chglog/git-chglog/issues/147))
|
||||
|
||||
### Chores
|
||||
- update changelog for v0.15.0
|
||||
- **deps:** update alpine docker tag to v3.14.0 ([#153](https://github.com/git-chglog/git-chglog/issues/153))
|
||||
|
||||
### Features
|
||||
- Automatic link for gitlab merge requests ([#160](https://github.com/git-chglog/git-chglog/issues/160))
|
||||
|
||||
|
||||
<a name="v0.14.2"></a>
|
||||
## [v0.14.2] - 2021-04-16
|
||||
### Bug Fixes
|
||||
- add CommitGroupTitleOrder back to Options ([#143](https://github.com/git-chglog/git-chglog/issues/143))
|
||||
|
||||
### Chores
|
||||
- update changelog for v0.14.2
|
||||
- **deps:** update alpine docker tag to v3.13.5 ([#144](https://github.com/git-chglog/git-chglog/issues/144))
|
||||
|
||||
|
||||
<a name="v0.14.1"></a>
|
||||
## [v0.14.1] - 2021-04-13
|
||||
### Bug Fixes
|
||||
- **template:** address regression in string functions for template engine ([#142](https://github.com/git-chglog/git-chglog/issues/142))
|
||||
|
||||
### Chores
|
||||
- update changelog for v0.14.1
|
||||
- add docker target to Makefile ([#138](https://github.com/git-chglog/git-chglog/issues/138))
|
||||
- add make release target ([#130](https://github.com/git-chglog/git-chglog/issues/130))
|
||||
- **deps:** update alpine docker tag to v3.13.4 ([#136](https://github.com/git-chglog/git-chglog/issues/136))
|
||||
|
||||
### Features
|
||||
- add docker image on release and master ([#135](https://github.com/git-chglog/git-chglog/issues/135))
|
||||
|
||||
|
||||
<a name="v0.14.0"></a>
|
||||
## [v0.14.0] - 2021-03-28
|
||||
### Chores
|
||||
- update changelog for v0.14.0
|
||||
- **CHANGELOG:** regenerate CHANGELOG with type-scope and KAC template ([#129](https://github.com/git-chglog/git-chglog/issues/129))
|
||||
|
||||
### Features
|
||||
- add sprig template functions support ([#131](https://github.com/git-chglog/git-chglog/issues/131))
|
||||
- add `--sort [TYPE]` flag ([#78](https://github.com/git-chglog/git-chglog/issues/78))
|
||||
|
||||
|
||||
<a name="v0.13.0"></a>
|
||||
## [v0.13.0] - 2021-03-23
|
||||
### Chores
|
||||
- update changelog for v0.13.0
|
||||
- use ldflags to pass version to build process ([#127](https://github.com/git-chglog/git-chglog/issues/127))
|
||||
|
||||
### Features
|
||||
- add support for rendering .Body after .Subject as part of list ([#121](https://github.com/git-chglog/git-chglog/issues/121))
|
||||
|
||||
|
||||
<a name="v0.12.0"></a>
|
||||
## [v0.12.0] - 2021-03-20
|
||||
### Chores
|
||||
- update changelog for v0.12.0
|
||||
- bumps version to v0.12.0
|
||||
- bump golang to 1.16 ([#118](https://github.com/git-chglog/git-chglog/issues/118))
|
||||
- **ci:** add golangci-lint action and apply linting changes ([#120](https://github.com/git-chglog/git-chglog/issues/120))
|
||||
|
||||
### Features
|
||||
- allow tag sorting by semver ([#124](https://github.com/git-chglog/git-chglog/issues/124))
|
||||
|
||||
### BREAKING CHANGE
|
||||
|
||||
`JiraIssueId` has been renamed to `JiraIssueID`. This impacts the value for `pattern_maps` in `config.yml`.
|
||||
|
||||
* chore(ci): add golangci-lint action
|
||||
|
||||
* chore(lint): address errcheck lint failures
|
||||
|
||||
* chore(lint): address misspell lint failures
|
||||
|
||||
* chore(lint): address gocritic lint failures
|
||||
|
||||
* chore(lint): address golint lint failures
|
||||
|
||||
* chore(lint): address structcheck lint failures
|
||||
|
||||
* chore(lint): address gosimple lint failures
|
||||
|
||||
* chore(lint): address gofmt lint failures
|
||||
|
||||
* chore(ci): port to official golangci-lint github action
|
||||
|
||||
* Update golangci configuration for better coverage
|
||||
|
||||
|
||||
<a name="v0.11.2"></a>
|
||||
## [v0.11.2] - 2021-03-13
|
||||
### Bug Fixes
|
||||
- `--template` and `--repository-url` flags not being used ([#119](https://github.com/git-chglog/git-chglog/issues/119))
|
||||
|
||||
### Chores
|
||||
- update changelog for v0.11.2
|
||||
- bumps version to v0.11.2
|
||||
|
||||
|
||||
<a name="v0.11.1"></a>
|
||||
## [v0.11.1] - 2021-03-12
|
||||
|
||||
### Bug Fixes
|
||||
- **short flags**: correctly define cli flags with shorthands ([#117](https://github.com/git-chglog/git-chglog/issues/117))
|
||||
- **short flags:** correctly define cli flags with shorthands ([#117](https://github.com/git-chglog/git-chglog/issues/117))
|
||||
|
||||
### Chores
|
||||
- update readme and changelog for v0.11.1
|
||||
- bumps version to v0.11.1
|
||||
|
||||
|
||||
<a name="v0.11.0"></a>
|
||||
## [v0.11.0] - 2021-03-12
|
||||
### Bug Fixes
|
||||
- **deps:** update all non-major dependencies ([#115](https://github.com/git-chglog/git-chglog/issues/115))
|
||||
- **deps:** update module gopkg.in/kyokomi/emoji.v1 to github.com/kyokomi/emoji/v2 ([#109](https://github.com/git-chglog/git-chglog/issues/109))
|
||||
- **deps:** update module github.com/urfave/cli to v2 ([#107](https://github.com/git-chglog/git-chglog/issues/107))
|
||||
- **deps:** update module github.com/stretchr/testify to v1.7.0 ([#103](https://github.com/git-chglog/git-chglog/issues/103))
|
||||
- **deps:** update module gopkg.in/alecaivazis/survey.v1 to github.com/AlecAivazis/survey/v2 ([#108](https://github.com/git-chglog/git-chglog/issues/108))
|
||||
- **init:** support OptionAnswer form in survey/v2 ([#113](https://github.com/git-chglog/git-chglog/issues/113))
|
||||
|
||||
### Chores
|
||||
- update changelog for v0.11.0
|
||||
- bumps version to v0.11.0
|
||||
- **deps:** add initial renovatebot configuration ([#102](https://github.com/git-chglog/git-chglog/issues/102))
|
||||
|
||||
### Features
|
||||
- add Jira integration ([#52](https://github.com/git-chglog/git-chglog/issues/52))
|
||||
- **flag:** --path filtering - refs ([#62](https://github.com/git-chglog/git-chglog/issues/62)). Closes [#35](https://github.com/git-chglog/git-chglog/issues/35)
|
||||
|
||||
|
||||
<a name="v0.10.0"></a>
|
||||
## [v0.10.0] - 2021-01-16
|
||||
|
||||
### BREAKING CHANGE
|
||||
We adapted the naming schema of the uploaded binaries by adding a `v` prefix for tags/versions starting from `v0.10.0`:
|
||||
```
|
||||
# up to 0.9.1
|
||||
https://github.com/git-chglog/git-chglog/releases/download/<VERSION>/git-chglog_<OS>_<ARCH>
|
||||
|
||||
# from v0.10.0
|
||||
https://github.com/git-chglog/git-chglog/releases/download/v<VERSION>/git-chglog_<OS>_<ARCH>
|
||||
|
||||
```
|
||||
|
||||
### Bug Fixes
|
||||
- ignore only git-chglog binary in root and not subfolder
|
||||
|
||||
### Chores
|
||||
- update changelog for v0.10.0
|
||||
- bumps version to v0.10.0
|
||||
- sorts changelog desc and excludes Merge commits
|
||||
- fix Makefile typo ([#82](https://github.com/git-chglog/git-chglog/issues/82))
|
||||
- **asdf:** add asdf install support to README ([#79](https://github.com/git-chglog/git-chglog/issues/79))
|
||||
|
||||
### Features
|
||||
- Adds 'Custom' sort_type to CommitGroup ([#69](https://github.com/git-chglog/git-chglog/issues/69))
|
||||
- enable tag_filter_pattern in config options ([#72](https://github.com/git-chglog/git-chglog/issues/72))
|
||||
|
|
@ -41,6 +206,16 @@ https://github.com/git-chglog/git-chglog/releases/download/v<VERSION>/git-chglog
|
|||
- add upperFirst template function
|
||||
- Add emoji format and some formatters in variables
|
||||
|
||||
### Reverts
|
||||
- Revert "ci: switches to personal GH Token for brew cross repo releases"
|
||||
- ci: switches to personal GH Token for brew cross repo releases
|
||||
|
||||
### Pull Requests
|
||||
- Merge pull request [#65](https://github.com/git-chglog/git-chglog/issues/65) from barryib/case-sensitive-option
|
||||
- Merge pull request [#59](https://github.com/git-chglog/git-chglog/issues/59) from momotaro98/feature/add-emoji-template-in-init
|
||||
- Merge pull request [#66](https://github.com/git-chglog/git-chglog/issues/66) from barryib/add-upper-first-func
|
||||
- Merge pull request [#68](https://github.com/git-chglog/git-chglog/issues/68) from unixorn/tweak-readme
|
||||
|
||||
|
||||
<a name="0.9.1"></a>
|
||||
## [0.9.1] - 2019-09-23
|
||||
|
|
@ -53,49 +228,84 @@ https://github.com/git-chglog/git-chglog/releases/download/v<VERSION>/git-chglog
|
|||
### Features
|
||||
- Add --tag-filter-pattern flag.
|
||||
|
||||
### Pull Requests
|
||||
- Merge pull request [#44](https://github.com/git-chglog/git-chglog/issues/44) from evanchaoli/tag-filter
|
||||
- Merge pull request [#41](https://github.com/git-chglog/git-chglog/issues/41) from StanleyGoldman/fixing-tests-windows
|
||||
- Merge pull request [#37](https://github.com/git-chglog/git-chglog/issues/37) from ForkingSyndrome/master
|
||||
|
||||
|
||||
<a name="0.8.0"></a>
|
||||
## [0.8.0] - 2019-02-23
|
||||
### Features
|
||||
- add the contains, hasPrefix, hasSuffix, replace, lower and upper functions to the template functions map
|
||||
|
||||
### Pull Requests
|
||||
- Merge pull request [#34](https://github.com/git-chglog/git-chglog/issues/34) from atosatto/template-functions
|
||||
|
||||
|
||||
<a name="0.7.1"></a>
|
||||
## [0.7.1] - 2018-11-10
|
||||
### Bug Fixes
|
||||
- Panic occured when exec --next-tag with HEAD with tag
|
||||
|
||||
### Pull Requests
|
||||
- Merge pull request [#31](https://github.com/git-chglog/git-chglog/issues/31) from drubin/patch-1
|
||||
- Merge pull request [#30](https://github.com/git-chglog/git-chglog/issues/30) from vvakame/fix-panic
|
||||
|
||||
|
||||
<a name="0.7.0"></a>
|
||||
## [0.7.0] - 2018-05-06
|
||||
### Bug Fixes
|
||||
- Remove accidentally added `Unreleased.Tag`
|
||||
|
||||
### Chores
|
||||
- Update `changelog` task in Makefile
|
||||
|
||||
### Features
|
||||
- Add URL of output example for template style
|
||||
- Add `--next-tag` flag (experimental)
|
||||
|
||||
### Pull Requests
|
||||
- Merge pull request [#22](https://github.com/git-chglog/git-chglog/issues/22) from git-chglog/feat/add-preview-style-link
|
||||
- Merge pull request [#21](https://github.com/git-chglog/git-chglog/issues/21) from git-chglog/feat/next-tag
|
||||
|
||||
|
||||
<a name="0.6.0"></a>
|
||||
## [0.6.0] - 2018-05-04
|
||||
### Chores
|
||||
- Update CHANGELOG template format
|
||||
|
||||
### Features
|
||||
- Add tag name header id for keep-a-changelog template
|
||||
|
||||
### Pull Requests
|
||||
- Merge pull request [#20](https://github.com/git-chglog/git-chglog/issues/20) from git-chglog/feat/kac-template-title-id
|
||||
|
||||
|
||||
<a name="0.5.0"></a>
|
||||
## [0.5.0] - 2018-05-04
|
||||
### Bug Fixes
|
||||
- Add unreleased commits section to keep-a-changelog template [#15](https://github.com/git-chglog/git-chglog/issues/15)
|
||||
|
||||
### Chores
|
||||
- Update CHANGELOG template format
|
||||
|
||||
### Features
|
||||
- Update template format to human readable
|
||||
- Add `Unreleased` field to `RenderData`
|
||||
|
||||
### Pull Requests
|
||||
- Merge pull request [#19](https://github.com/git-chglog/git-chglog/issues/19) from git-chglog/fix/unreleased-commits
|
||||
- Merge pull request [#18](https://github.com/git-chglog/git-chglog/issues/18) from ringohub/master
|
||||
|
||||
|
||||
<a name="0.4.0"></a>
|
||||
## [0.4.0] - 2018-04-14
|
||||
### Features
|
||||
- Add support for Bitbucket :tada:
|
||||
- Add support for Bitbucket
|
||||
|
||||
### Pull Requests
|
||||
- Merge pull request [#17](https://github.com/git-chglog/git-chglog/issues/17) from git-chglog/feat/bitbucket
|
||||
|
||||
|
||||
<a name="0.3.3"></a>
|
||||
|
|
@ -103,42 +313,69 @@ https://github.com/git-chglog/git-chglog/releases/download/v<VERSION>/git-chglog
|
|||
### Features
|
||||
- Change to kindly error message when git-tag does not exist
|
||||
|
||||
### Pull Requests
|
||||
- Merge pull request [#16](https://github.com/git-chglog/git-chglog/issues/16) from git-chglog/fix/empty-tag-handling
|
||||
|
||||
|
||||
<a name="0.3.2"></a>
|
||||
## [0.3.2] - 2018-04-02
|
||||
### Bug Fixes
|
||||
- Fix color output bug in windows help command
|
||||
|
||||
### Pull Requests
|
||||
- Merge pull request [#14](https://github.com/git-chglog/git-chglog/issues/14) from git-chglog/fix/windows-help-color
|
||||
|
||||
|
||||
<a name="0.3.1"></a>
|
||||
## [0.3.1] - 2018-03-15
|
||||
### Bug Fixes
|
||||
- Fix preview string of commit subject ([@kt3k](https://github.com/kt3k))
|
||||
- fix preview string of commit subject
|
||||
|
||||
### Pull Requests
|
||||
- Merge pull request [#13](https://github.com/git-chglog/git-chglog/issues/13) from kt3k/feature/fix-preview
|
||||
|
||||
|
||||
<a name="0.3.0"></a>
|
||||
## [0.3.0] - 2018-03-12
|
||||
### Chores
|
||||
- Add helper task for generate CHANGELOG
|
||||
|
||||
### Features
|
||||
- Add support for GitLab :tada:
|
||||
- Add support for GitLab
|
||||
|
||||
### Pull Requests
|
||||
- Merge pull request [#12](https://github.com/git-chglog/git-chglog/issues/12) from git-chglog/feat/gitlab
|
||||
|
||||
|
||||
<a name="0.2.0"></a>
|
||||
## [0.2.0] - 2018-03-02
|
||||
### Chores
|
||||
- Fix release flow (retry)
|
||||
- Add AppVeyor config
|
||||
|
||||
### Features
|
||||
- Add template for `Keep a changelog` to the `--init` option
|
||||
- Supports vim like `j/k` keybind with item selection of `--init`
|
||||
|
||||
### Bug Fixes
|
||||
- Support Windows colors :tada: ([@mattn](https://github.com/mattn))
|
||||
- Fixed several bugs in Windows
|
||||
### Pull Requests
|
||||
- Merge pull request [#11](https://github.com/git-chglog/git-chglog/issues/11) from git-chglog/develop
|
||||
- Merge pull request [#10](https://github.com/git-chglog/git-chglog/issues/10) from mattn/fix-test
|
||||
- Merge pull request [#9](https://github.com/git-chglog/git-chglog/issues/9) from mattn/windows-color
|
||||
|
||||
|
||||
<a name="0.1.0"></a>
|
||||
## [0.1.0] - 2018-02-25
|
||||
### Bug Fixes
|
||||
- Fix a bug that `Commit.Revert.Header` is not converted by `GitHubProcessor`
|
||||
- Fix error message when `Tag` can not be acquired
|
||||
- Fix `Revert` of template created by Initializer
|
||||
|
||||
### Chores
|
||||
- Fix release scripts
|
||||
- Remove unnecessary task
|
||||
- Add coverage measurement task for local confirmation
|
||||
- Change release method of git tag on TravisCI
|
||||
|
||||
### Code Refactoring
|
||||
- Refactor `Initializer` to testable
|
||||
|
||||
|
|
@ -148,14 +385,19 @@ https://github.com/git-chglog/git-chglog/releases/download/v<VERSION>/git-chglog
|
|||
- Add Git Basic to commit message format
|
||||
- Add preview to the commit message format of `--init` option
|
||||
|
||||
### Pull Requests
|
||||
- Merge pull request [#8](https://github.com/git-chglog/git-chglog/issues/8) from git-chglog/feat/0.0.3
|
||||
- Merge pull request [#6](https://github.com/git-chglog/git-chglog/issues/6) from git-chglog/chore/coverage
|
||||
- Merge pull request [#4](https://github.com/git-chglog/git-chglog/issues/4) from paralax/patch-1
|
||||
- Merge pull request [#5](https://github.com/git-chglog/git-chglog/issues/5) from git-chglog/develop
|
||||
- Merge pull request [#1](https://github.com/git-chglog/git-chglog/issues/1) from git-chglog/develop
|
||||
|
||||
|
||||
<a name="0.0.2"></a>
|
||||
## [0.0.2] - 2018-02-18
|
||||
### Bug Fixes
|
||||
- Fix a bug that `Commit.Revert.Header` is not converted by `GitHubProcessor`
|
||||
|
||||
### Features
|
||||
- Add preview to the commit message format of `--init` option
|
||||
### Chores
|
||||
- Fix release script
|
||||
- Add release process
|
||||
|
||||
|
||||
<a name="0.0.1"></a>
|
||||
|
|
@ -163,6 +405,17 @@ https://github.com/git-chglog/git-chglog/releases/download/v<VERSION>/git-chglog
|
|||
### Bug Fixes
|
||||
- Fix parsing of revert and body
|
||||
|
||||
### Chores
|
||||
- Fix timezone in TravisCI
|
||||
- Add travis configuration
|
||||
- Add Makefile for task management
|
||||
- Fix testcase depending on datetime
|
||||
- Update vendor packages
|
||||
- Add e2e tests
|
||||
- Setup gitignore
|
||||
- Initial commit
|
||||
- **editor:** Add Editorconfig
|
||||
|
||||
### Code Refactoring
|
||||
- Fix typo
|
||||
- Change to return an error if corresponding commit is empty
|
||||
|
|
@ -177,7 +430,17 @@ https://github.com/git-chglog/git-chglog/releases/download/v<VERSION>/git-chglog
|
|||
- First implement
|
||||
|
||||
|
||||
[Unreleased]: https://github.com/git-chglog/git-chglog/compare/v0.11.1...HEAD
|
||||
[Unreleased]: https://github.com/git-chglog/git-chglog/compare/v0.15.4...HEAD
|
||||
[v0.15.4]: https://github.com/git-chglog/git-chglog/compare/v0.15.2...v0.15.4
|
||||
[v0.15.2]: https://github.com/git-chglog/git-chglog/compare/v0.15.1...v0.15.2
|
||||
[v0.15.1]: https://github.com/git-chglog/git-chglog/compare/v0.15.0...v0.15.1
|
||||
[v0.15.0]: https://github.com/git-chglog/git-chglog/compare/v0.14.2...v0.15.0
|
||||
[v0.14.2]: https://github.com/git-chglog/git-chglog/compare/v0.14.1...v0.14.2
|
||||
[v0.14.1]: https://github.com/git-chglog/git-chglog/compare/v0.14.0...v0.14.1
|
||||
[v0.14.0]: https://github.com/git-chglog/git-chglog/compare/v0.13.0...v0.14.0
|
||||
[v0.13.0]: https://github.com/git-chglog/git-chglog/compare/v0.12.0...v0.13.0
|
||||
[v0.12.0]: https://github.com/git-chglog/git-chglog/compare/v0.11.2...v0.12.0
|
||||
[v0.11.2]: https://github.com/git-chglog/git-chglog/compare/v0.11.1...v0.11.2
|
||||
[v0.11.1]: https://github.com/git-chglog/git-chglog/compare/v0.11.0...v0.11.1
|
||||
[v0.11.0]: https://github.com/git-chglog/git-chglog/compare/v0.10.0...v0.11.0
|
||||
[v0.10.0]: https://github.com/git-chglog/git-chglog/compare/0.9.1...v0.10.0
|
||||
|
|
|
|||
|
|
@ -2,22 +2,21 @@
|
|||
|
||||
Thank you for contributing `git-chglog` :tada:
|
||||
|
||||
|
||||
## Templates
|
||||
|
||||
Please use issue/PR templates which are inserted automatically.
|
||||
|
||||
|
||||
## Found a Bug?
|
||||
|
||||
If you find a bug in the source code, you can help us by [submitting an issue](https://github.com/git-chglog/git-chglog/issues) to our [GitHub Repository](https://github.com/git-chglog/git-chglog). Even better, you can submit a Pull Request with a fix.
|
||||
|
||||
If you find a bug in the source code, you can help us by [submitting an issue]
|
||||
to our [GitHub Repository]. Even better, you can submit a Pull Request with a
|
||||
fix.
|
||||
|
||||
## Commit Message Format
|
||||
|
||||
A format influenced by [Angular commit message](https://github.com/angular/angular/blob/master/CONTRIBUTING.md#commit-message-format).
|
||||
A format influenced by [Angular commit message].
|
||||
|
||||
```
|
||||
```text
|
||||
<type>: <subject>
|
||||
<BLANK LINE>
|
||||
<body>
|
||||
|
|
@ -25,26 +24,31 @@ A format influenced by [Angular commit message](https://github.com/angular/angul
|
|||
<footer>
|
||||
```
|
||||
|
||||
|
||||
### Type
|
||||
|
||||
Must be one of the following:
|
||||
|
||||
* **docs:** Documention only changes
|
||||
* **ci:** Changes to our CI configuration files and scripts
|
||||
* **chore:** Updating Makefile etc, no production code changes
|
||||
* **feat:** A new feature
|
||||
* **fix:** A bug fix
|
||||
* **perf:** A code change that improves performance
|
||||
* **refactor:** A code change that neither fixes a bug nor adds a feature
|
||||
* **style:** Changes that do not affect the meaning of the code
|
||||
* **test:** Adding missing tests or correcting existing tests
|
||||
|
||||
- **docs:** Documention only changes
|
||||
- **ci:** Changes to our CI configuration files and scripts
|
||||
- **chore:** Updating Makefile etc, no production code changes
|
||||
- **feat:** A new feature
|
||||
- **fix:** A bug fix
|
||||
- **perf:** A code change that improves performance
|
||||
- **refactor:** A code change that neither fixes a bug nor adds a feature
|
||||
- **style:** Changes that do not affect the meaning of the code
|
||||
- **test:** Adding missing tests or correcting existing tests
|
||||
|
||||
### Footer
|
||||
|
||||
The footer should contain a [closing reference to an issue](https://help.github.com/articles/closing-issues-via-commit-messages/) if any.
|
||||
The footer should contain a [closing reference to an issue] if any.
|
||||
|
||||
The **footer** should contain any information about **Breaking Changes** and is also the place to reference GitHub issues that this commit **Closes**.
|
||||
The **footer** should contain any information about **Breaking Changes** and is
|
||||
also the place to reference GitHub issues that this commit **Closes**.
|
||||
|
||||
**Breaking Changes** should start with the word `BREAKING CHANGE:` with a space or two newlines. The rest of the commit message is then used for this.
|
||||
**Breaking Changes** should start with the word `BREAKING CHANGE:` with a space
|
||||
or two newlines. The rest of the commit message is then used for this.
|
||||
|
||||
[submitting an issue]: https://github.com/git-chglog/git-chglog/issues
|
||||
[GitHub Repository]: https://github.com/git-chglog/git-chglog
|
||||
[Angular commit message]: https://github.com/angular/angular/blob/master/CONTRIBUTING.md#commit-message-format
|
||||
[closing reference to an issue]: https://help.github.com/articles/closing-issues-via-commit-messages/
|
||||
12
Dockerfile
Normal file
12
Dockerfile
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
FROM alpine
|
||||
|
||||
RUN apk add --no-cache git && \
|
||||
mkdir /workdir && \
|
||||
git config --global --add safe.directory /workdir
|
||||
|
||||
COPY git-chglog /usr/local/bin/git-chglog
|
||||
|
||||
WORKDIR /workdir
|
||||
RUN chmod +x /usr/local/bin/git-chglog
|
||||
|
||||
ENTRYPOINT [ "/usr/local/bin/git-chglog" ]
|
||||
108
Makefile
108
Makefile
|
|
@ -1,22 +1,108 @@
|
|||
# Build variables
|
||||
VERSION ?= $(shell git describe --tags --always)
|
||||
|
||||
# Go variables
|
||||
GO ?= go
|
||||
GOOS ?= $(shell $(GO) env GOOS)
|
||||
GOARCH ?= $(shell $(GO) env GOARCH)
|
||||
GOHOST ?= GOOS=$(GOOS) GOARCH=$(GOARCH) $(GO)
|
||||
|
||||
LDFLAGS ?= "-X main.version=$(VERSION)"
|
||||
|
||||
# Docker variables
|
||||
DEFAULT_TAG ?= $(shell echo "$(VERSION)" | tr -d 'v')
|
||||
DOCKER_IMAGE := quay.io/git-chglog/git-chglog
|
||||
DOCKER_TAG ?= $(DEFAULT_TAG)
|
||||
|
||||
.PHONY: all
|
||||
all: help
|
||||
|
||||
###############
|
||||
##@ Development
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
clean: ## Clean workspace
|
||||
@ $(MAKE) --no-print-directory log-$@
|
||||
rm -rf ./dist/
|
||||
rm -rf ./git-chglog
|
||||
rm -rf $(GOPATH)/bin/git-chglog
|
||||
rm -rf cover.out
|
||||
|
||||
.PHONY: build
|
||||
build:
|
||||
go build -o git-chglog ./cmd/git-chglog
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
go test -covermode atomic -coverprofile cover.out -v ./...
|
||||
test: ## Run tests
|
||||
@ $(MAKE) --no-print-directory log-$@
|
||||
$(GOHOST) test -covermode atomic -coverprofile cover.out -v ./...
|
||||
|
||||
.PHONY: lint
|
||||
lint: ## Run linters
|
||||
@ $(MAKE) --no-print-directory log-$@
|
||||
golangci-lint run
|
||||
|
||||
#########
|
||||
##@ Build
|
||||
|
||||
.PHONY: build
|
||||
build: ## Build git-chglog
|
||||
@ $(MAKE) --no-print-directory log-$@
|
||||
CGO_ENABLED=0 $(GOHOST) build -ldflags=$(LDFLAGS) -o git-chglog ./cmd/git-chglog
|
||||
|
||||
.PHONY: install
|
||||
install:
|
||||
go install ./cmd/git-chglog
|
||||
install: ## Install git-chglog
|
||||
@ $(MAKE) --no-print-directory log-$@
|
||||
$(GOHOST) install ./cmd/git-chglog
|
||||
|
||||
.PHONY: docker
|
||||
docker: build ## Build Docker image
|
||||
@ $(MAKE) --no-print-directory log-$@
|
||||
docker build --pull --tag $(DOCKER_IMAGE):$(DOCKER_TAG) .
|
||||
|
||||
.PHONY: push
|
||||
push: ## Push Docker image
|
||||
@ $(MAKE) --no-print-directory log-$@
|
||||
docker push $(DOCKER_IMAGE):$(DOCKER_TAG)
|
||||
|
||||
###########
|
||||
##@ Release
|
||||
|
||||
.PHONY: changelog
|
||||
changelog:
|
||||
@git-chglog --next-tag $(tag) $(tag)
|
||||
changelog: build ## Generate changelog
|
||||
@ $(MAKE) --no-print-directory log-$@
|
||||
./git-chglog --next-tag $(VERSION) -o CHANGELOG.md
|
||||
|
||||
.PHONY: release
|
||||
release: changelog ## Release a new tag
|
||||
@ $(MAKE) --no-print-directory log-$@
|
||||
git add CHANGELOG.md
|
||||
git commit -m "chore: update changelog for $(VERSION)"
|
||||
git tag $(VERSION)
|
||||
git push origin master $(VERSION)
|
||||
|
||||
########
|
||||
##@ Help
|
||||
|
||||
.PHONY: help
|
||||
help: ## Display this help
|
||||
@awk \
|
||||
-v "col=\033[36m" -v "nocol=\033[0m" \
|
||||
' \
|
||||
BEGIN { \
|
||||
FS = ":.*##" ; \
|
||||
printf "Usage:\n make %s<target>%s\n", col, nocol \
|
||||
} \
|
||||
/^[a-zA-Z_-]+:.*?##/ { \
|
||||
printf " %s%-12s%s %s\n", col, $$1, nocol, $$2 \
|
||||
} \
|
||||
/^##@/ { \
|
||||
printf "\n%s%s%s\n", nocol, substr($$0, 5), nocol \
|
||||
} \
|
||||
' $(MAKEFILE_LIST)
|
||||
|
||||
log-%:
|
||||
@grep -h -E '^$*:.*?## .*$$' $(MAKEFILE_LIST) | \
|
||||
awk \
|
||||
'BEGIN { \
|
||||
FS = ":.*?## " \
|
||||
}; \
|
||||
{ \
|
||||
printf "\033[36m==> %s\033[0m\n", $$2 \
|
||||
}'
|
||||
|
|
|
|||
270
README.md
270
README.md
|
|
@ -4,14 +4,12 @@
|
|||
|
||||
[](https://godoc.org/github.com/git-chglog/git-chglog)
|
||||
[](https://github.com/git-chglog/git-chglog/actions)
|
||||
[](https://ci.appveyor.com/project/tsuyoshiwada/git-chglog/branch/master)
|
||||
[](https://coveralls.io/github/git-chglog/git-chglog?branch=master)
|
||||
[](https://github.com/git-chglog/git-chglog/blob/master/LICENSE)
|
||||
|
||||
> CHANGELOG generator implemented in Go (Golang).
|
||||
> CHANGELOG generator implemented in Go (Golang).
|
||||
> _Anytime, anywhere, Write your CHANGELOG._
|
||||
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [git-chglog](#git-chglog)
|
||||
|
|
@ -24,6 +22,7 @@
|
|||
- [Scoop (for Windows users)](#scoop-for-windows-users)
|
||||
- [asdf](#asdf)
|
||||
- [Go users](#go-users)
|
||||
- [Docker](#docker)
|
||||
- [Test Installation](#test-installation)
|
||||
- [Quick Start](#quick-start)
|
||||
- [CLI Usage](#cli-usage)
|
||||
|
|
@ -34,6 +33,7 @@
|
|||
- [`template`](#template)
|
||||
- [`info`](#info)
|
||||
- [`options`](#options)
|
||||
- [`options.sort`](#optionssort)
|
||||
- [`options.commits`](#optionscommits)
|
||||
- [`options.commit_groups`](#optionscommit_groups)
|
||||
- [`options.header`](#optionsheader)
|
||||
|
|
@ -45,35 +45,36 @@
|
|||
- [Templates](#templates)
|
||||
- [Supported Styles](#supported-styles)
|
||||
- [Jira Integration](#jira-integration)
|
||||
- [1. Change the header parse pattern to recognize Jira issue id in the configure file](#1-change-the-header-parse-pattern-to-recognize-jira-issue-id-in-the-configure-file)
|
||||
- [2. Add Jira configuration to the configure file](#2-add-jira-configuration-to-the-configure-file)
|
||||
- [3. Update the template to show Jira data](#3-update-the-template-to-show-jira-data)
|
||||
- [FAQ](#faq)
|
||||
- [TODO](#todo)
|
||||
- [Thanks](#thanks)
|
||||
- [Contributing](#contributing)
|
||||
- [Development](#development)
|
||||
- [Feedback](#feedback)
|
||||
- [Development](#development)
|
||||
- [Release Process](#release-process)
|
||||
- [Feedback](#feedback)
|
||||
- [CHANGELOG](#changelog)
|
||||
- [Related Projects](#related-projects)
|
||||
- [License](#license)
|
||||
|
||||
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
* :recycle: High portability
|
||||
- It works with single binary. Therefore, any project (environment) can be used.
|
||||
* :beginner: Simple usability
|
||||
- The CLI usage is very simple and has low learning costs.
|
||||
- For example, the simplest command is `$ git-chglog`.
|
||||
* :rocket: High flexibility
|
||||
- Commit message format and ...
|
||||
- CHANGELOG's style (Template) and ...
|
||||
- etc ...
|
||||
- :recycle: High portability
|
||||
- It works with single binary. Therefore, any project (environment) can be used.
|
||||
- :beginner: Simple usability
|
||||
- The CLI usage is very simple and has low learning costs.
|
||||
- For example, the simplest command is `$ git-chglog`.
|
||||
- :rocket: High flexibility
|
||||
- Commit message format and ...
|
||||
- CHANGELOG's style (Template) and ...
|
||||
- etc ...
|
||||
|
||||
## How it works
|
||||
|
||||
`git-chglog` internally uses the `git` command to get data to include in the CHANGELOG.
|
||||
The basic steps are as follows.
|
||||
`git-chglog` internally uses the `git` command to get data to include in the
|
||||
CHANGELOG. The basic steps are as follows.
|
||||
|
||||
1. Get all the tags.
|
||||
1. Get the commits contained between `tagA` and `tagB`.
|
||||
|
|
@ -81,7 +82,8 @@ The basic steps are as follows.
|
|||
|
||||
## Getting Started
|
||||
|
||||
We will start with installation and introduce the steps up to the automatic generation of the configuration file and template.
|
||||
We will start with installation and introduce the steps up to the automatic generation
|
||||
of the configuration file and template.
|
||||
|
||||
### Installation
|
||||
|
||||
|
|
@ -90,54 +92,64 @@ Please install `git-chglog` in a way that matches your environment.
|
|||
#### [Homebrew](https://brew.sh) (for macOS users)
|
||||
|
||||
```bash
|
||||
$ brew tap git-chglog/git-chglog
|
||||
$ brew install git-chglog
|
||||
brew tap git-chglog/git-chglog
|
||||
brew install git-chglog
|
||||
```
|
||||
|
||||
#### [Scoop](https://scoop.sh) (for Windows users)
|
||||
|
||||
```
|
||||
$ scoop install git-chglog
|
||||
```bash
|
||||
scoop install git-chglog
|
||||
```
|
||||
|
||||
#### [asdf](https://asdf-vm.com/)
|
||||
|
||||
```bash
|
||||
$ asdf plugin-add git-chglog https://github.com/GoodwayGroup/asdf-git-chglog.git
|
||||
$ asdf install git-chglog latest
|
||||
asdf plugin-add git-chglog https://github.com/GoodwayGroup/asdf-git-chglog.git
|
||||
asdf install git-chglog latest
|
||||
```
|
||||
|
||||
#### Go users
|
||||
|
||||
```bash
|
||||
$ go get -u github.com/git-chglog/git-chglog/cmd/git-chglog
|
||||
go install github.com/git-chglog/git-chglog/cmd/git-chglog@latest
|
||||
```
|
||||
|
||||
### [Docker](https://www.docker.com/)
|
||||
The compiled docker images are maintained on [quay.io](https://quay.io/repository/git-chglog/git-chglog).
|
||||
We maintain the following tags:
|
||||
- `edge`: Image that is build from the current `HEAD` of the main line branch.
|
||||
- `latest`: Image that is built from the [latest released version](https://github.com/git-chglog/git-chglog/releases)
|
||||
- `x.y.y` (versions): Images that are build from the tagged versions within Github.
|
||||
```bash
|
||||
docker pull quay.io/git-chglog/git-chglog:latest
|
||||
docker run -v "$PWD":/workdir quay.io/git-chglog/git-chglog --version
|
||||
```
|
||||
---
|
||||
|
||||
If you are using another platform, you can download a binary from the [releases page](https://github.com/git-chglog/git-chglog/releases) and place it in a directory in your `$PATH`.
|
||||
|
||||
If you are using another platform, you can download a binary from the [releases page]
|
||||
and place it in a directory in your `$PATH`.
|
||||
|
||||
### Test Installation
|
||||
|
||||
You can check with the following command whether the `git-chglog` command was included in a directory that is in your `$PATH`.
|
||||
You can check with the following command whether the `git-chglog` command was
|
||||
included in a directory that is in your `$PATH`.
|
||||
|
||||
```bash
|
||||
$ git-chglog --version
|
||||
# outputs the git-chglog version
|
||||
```
|
||||
|
||||
|
||||
### Quick Start
|
||||
|
||||
`git-chglog` requires configuration files and templates to generate a CHANGELOG.
|
||||
`git-chglog` requires configuration files and templates to generate a CHANGELOG.
|
||||
|
||||
However, it is a waste of time to create configuration files and templates from scratch.
|
||||
|
||||
Therefore we recommend using the `--init` option which will create them interactively :+1:
|
||||
|
||||
```bash
|
||||
$ git-chglog --init
|
||||
git-chglog --init
|
||||
```
|
||||
|
||||

|
||||
|
|
@ -146,24 +158,26 @@ $ git-chglog --init
|
|||
|
||||
You are now ready for configuration files and templates!
|
||||
|
||||
Let's immediately generate a CHANGELOG of your project.
|
||||
By doing the following simple command, Markdown for your CHANGELOG is displayed on stdout.
|
||||
Let's immediately generate a CHANGELOG of your project.
|
||||
By doing the following simple command, Markdown for your CHANGELOG is displayed
|
||||
on stdout.
|
||||
|
||||
```bash
|
||||
$ git-chglog
|
||||
git-chglog
|
||||
```
|
||||
|
||||
Use `-o` (`--output`) option if you want to output to a file instead of stdout.
|
||||
|
||||
```bash
|
||||
$ git-chglog -o CHANGELOG.md
|
||||
git-chglog -o CHANGELOG.md
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
You now know basic usage of `git-chglog`!
|
||||
|
||||
In order to make a better CHANGELOG, please refer to the following document and customize it.
|
||||
In order to make a better CHANGELOG, please refer to the following document and
|
||||
customize it.
|
||||
|
||||
## CLI Usage
|
||||
|
||||
|
|
@ -196,6 +210,7 @@ OPTIONS:
|
|||
--jira-url value Jira URL [$JIRA_URL]
|
||||
--jira-username value Jira username [$JIRA_USERNAME]
|
||||
--jira-token value Jira token [$JIRA_TOKEN]
|
||||
--sort value Specify how to sort tags; currently supports "date" or by "semver" (default: date)
|
||||
--help, -h show help (default: false)
|
||||
--version, -v print the version (default: false)
|
||||
|
||||
|
|
@ -246,7 +261,8 @@ The table below shows Query patterns and summaries, and Query examples.
|
|||
|
||||
## Configuration
|
||||
|
||||
The `git-chglog` configuration is a yaml file. The default location is `.chglog/config.yml`.
|
||||
The `git-chglog` configuration is a yaml file. The default location is
|
||||
`.chglog/config.yml`.
|
||||
|
||||
Below is a complete list that you can use with `git-chglog`.
|
||||
|
||||
|
|
@ -260,6 +276,7 @@ info:
|
|||
|
||||
options:
|
||||
tag_filter_pattern: '^v'
|
||||
sort: "date"
|
||||
|
||||
commits:
|
||||
filters:
|
||||
|
|
@ -314,7 +331,8 @@ Git execution command.
|
|||
|
||||
### `style`
|
||||
|
||||
CHANGELOG style. Automatic linking of issues and notices, initial value setting such as merges etc. are done automatically.
|
||||
CHANGELOG style. Automatic linking of issues and notices, initial value setting
|
||||
such as merges etc. are done automatically.
|
||||
|
||||
| Required | Type | Default | Description |
|
||||
|:---------|:-------|:---------|:-------------------------------------------------------|
|
||||
|
|
@ -322,7 +340,8 @@ CHANGELOG style. Automatic linking of issues and notices, initial value setting
|
|||
|
||||
### `template`
|
||||
|
||||
Path for the template file. It is specified by a relative path from the setting file. Absolute paths are also ok.
|
||||
Path for the template file. It is specified by a relative path from the setting
|
||||
file. Absolute paths are also ok.
|
||||
|
||||
| Required | Type | Default | Description |
|
||||
|:---------|:-------|:---------------------|:------------|
|
||||
|
|
@ -330,7 +349,8 @@ Path for the template file. It is specified by a relative path from the setting
|
|||
|
||||
### `info`
|
||||
|
||||
Metadata for CHANGELOG. Depending on Style, it is sometimes used in processing, so it is recommended to specify it.
|
||||
Metadata for CHANGELOG. Depending on Style, it is sometimes used in processing,
|
||||
so it is recommended to specify it.
|
||||
|
||||
| Key | Required | Type | Default | Description |
|
||||
|:-----------------|:---------|:-------|:--------------|:-----------------------|
|
||||
|
|
@ -341,14 +361,22 @@ Metadata for CHANGELOG. Depending on Style, it is sometimes used in processing,
|
|||
|
||||
Options used to process commits.
|
||||
|
||||
#### `options.sort`
|
||||
|
||||
Options concerning the acquisition and sort of commits.
|
||||
|
||||
| Required | Type | Default | Description |
|
||||
|:---------|:------------|:----------|:--------------------------------------------------------------------------------------------------------------------|
|
||||
| N | String | `"date"` | Defines how tags are sorted in the generated change log. Values: "date", "semver". |
|
||||
|
||||
#### `options.commits`
|
||||
|
||||
Options concerning the acquisition and sort of commits.
|
||||
|
||||
| Key | Required | Type | Default | Description |
|
||||
|:----------|:---------|:------------|:----------|:--------------------------------------------------------------------------------------------------------------------|
|
||||
| `filters` | N | Map in List | none | Filter by using `Commit` properties and values. Filtering is not done by specifying an empty value. |
|
||||
| `sort_by` | N | String | `"Scope"` | Property name to use for sorting `Commit`. See [Commit](https://godoc.org/github.com/git-chglog/git-chglog#Commit). |
|
||||
| Key | Required | Type | Default | Description |
|
||||
|:----------|:---------|:------------|:----------|:----------------------------------------------------------------------------------------------------|
|
||||
| `filters` | N | Map in List | none | Filter by using `Commit` properties and values. Filtering is not done by specifying an empty value. |
|
||||
| `sort_by` | N | String | `"Scope"` | Property name to use for sorting `Commit`. See [Commit]. |
|
||||
|
||||
#### `options.commit_groups`
|
||||
|
||||
|
|
@ -414,9 +442,22 @@ Options to detect notes contained in commit bodies.
|
|||
|
||||
## Templates
|
||||
|
||||
The `git-chglog` template uses the `text/template` package. For basic usage please refer to the following.
|
||||
The `git-chglog` template uses the `text/template` package and enhanced templating functions provided by [Sprig]. For basic usage please refer to the following.
|
||||
|
||||
> [text/template](https://golang.org/pkg/text/template/)
|
||||
- [text/template](https://golang.org/pkg/text/template/)
|
||||
- [Sprig]
|
||||
|
||||
We have implemented the following custom template functions. These override functions provided by [Sprig].
|
||||
|
||||
| Name | Signature | Description |
|
||||
| :----------- | :-------------------------------------------- | :---------------------------------------------------------------------------- |
|
||||
| `contains` | `func(s, substr string) bool` | Reports whether `substr` is within `s` using `strings.Contains` |
|
||||
| `datetime` | `func(layout string, input time.Time) string` | Generate a formatted Date string based on layout |
|
||||
| `hasPrefix` | `func(s, prefix string) bool` | Tests whether the string `s` begins with `prefix` using `strings.HasPrefix` |
|
||||
| `hasSuffix` | `func(s, suffix string) bool` | Tests whether the string `s` ends with `suffix`. using `strings.HasPrefix` |
|
||||
| `indent` | `func(s string, n int) string` | Indent all lines of `s` by `n` spaces |
|
||||
| `replace` | `func(s, old, new string, n int) string` | Replace `old` with `new` within string `s`, `n` times using `strings.Replace` |
|
||||
| `upperFirst` | `func(s string) string` | Upper case the first character of a string |
|
||||
|
||||
If you are not satisfied with the prepared template please try customizing one.
|
||||
|
||||
|
|
@ -495,20 +536,20 @@ See the godoc [RenderData][doc-render-data] documentation for available variable
|
|||
| [GitLab](https://about.gitlab.com/) | :white_check_mark: | Mentions automatic link. Automatic link to references. |
|
||||
| [Bitbucket](https://bitbucket.org/product) | :white_check_mark: | Mentions automatic link. Automatic link to references. |
|
||||
|
||||
> :memo: Even with styles that are not yet supported, it is possible to make ordinary CHANGELOG.
|
||||
|
||||
> :memo: Even with styles that are not yet supported, it is possible to make
|
||||
ordinary CHANGELOG.
|
||||
|
||||
## Jira Integration
|
||||
|
||||
|
||||
Jira is a popular project management tool. When a project uses Jira to track feature development and bug fixes,
|
||||
it may also want to generate change log based information stored in Jira. With embedding a Jira story id in git
|
||||
commit header, the git-chglog tool may automatically fetch data of the story from Jira, those data then can be
|
||||
used to render the template.
|
||||
Jira is a popular project management tool. When a project uses Jira to track
|
||||
feature development and bug fixes, it may also want to generate change log based
|
||||
information stored in Jira. With embedding a Jira story id in git commit header,
|
||||
the git-chglog tool may automatically fetch data of the story from Jira, those
|
||||
data then can be used to render the template.
|
||||
|
||||
Take the following steps to add Jira integration:
|
||||
|
||||
#### 1. Change the header parse pattern to recognize Jira issue id in the configure file.
|
||||
### 1. Change the header parse pattern to recognize Jira issue id in the configure file
|
||||
|
||||
__Where Jira issue is identical Jira story.__
|
||||
|
||||
|
|
@ -519,16 +560,16 @@ The following is a sample pattern:
|
|||
pattern: "^(?:(\\w*)|(?:\\[(.*)\\])?)\\:\\s(.*)$"
|
||||
pattern_maps:
|
||||
- Type
|
||||
- JiraIssueId
|
||||
- JiraIssueID
|
||||
- Subject
|
||||
```
|
||||
|
||||
This sample pattern can match both forms of commit headers:
|
||||
|
||||
* `feat: new feature of something`
|
||||
* `[JIRA-ID]: something`
|
||||
- `feat: new feature of something`
|
||||
- `[JIRA-ID]: something`
|
||||
|
||||
#### 2. Add Jira configuration to the configure file.
|
||||
### 2. Add Jira configuration to the configure file
|
||||
|
||||
The following is a sample:
|
||||
|
||||
|
|
@ -545,20 +586,22 @@ The following is a sample:
|
|||
description_pattern: "<changelog>(.*)</changelog>"
|
||||
```
|
||||
|
||||
Here you need to define Jira URL, access username and token (password). If you don't want to
|
||||
write your Jira access credential in configure file, you may define them with environment variables:
|
||||
`JIRA_URL`, `JIRA_USERNAME` and `JIRA_TOKEN`.
|
||||
Here you need to define Jira URL, access username and token (password). If you
|
||||
don't want to write your Jira access credential in configure file, you may define
|
||||
them with environment variables: `JIRA_URL`, `JIRA_USERNAME` and `JIRA_TOKEN`.
|
||||
|
||||
You also needs to define a issue type map. In above sample, Jira issue type `Task` will be
|
||||
mapped to `fix` and `Story` will be mapped to `feat`.
|
||||
You also needs to define a issue type map. In above sample, Jira issue type `Task`
|
||||
will be mapped to `fix` and `Story` will be mapped to `feat`.
|
||||
|
||||
As a Jira story's description could be very long, you might not want to include the entire
|
||||
description into change log. In that case, you may define `description_pattern` like above,
|
||||
so that only content embraced with `<changelog> ... </changelog>` will be included.
|
||||
As a Jira story's description could be very long, you might not want to include
|
||||
the entire description into change log. In that case, you may define `description_pattern`
|
||||
like above, so that only content embraced with `<changelog> ... </changelog>`
|
||||
will be included.
|
||||
|
||||
#### 3. Update the template to show Jira data.
|
||||
### 3. Update the template to show Jira data
|
||||
|
||||
In the template, if a commit contains a Jira issue id, then you may show Jira data. For example:
|
||||
In the template, if a commit contains a Jira issue id, then you may show Jira
|
||||
data. For example:
|
||||
|
||||
```markdown
|
||||
{{ range .CommitGroups -}}
|
||||
|
|
@ -573,21 +616,22 @@ In the template, if a commit contains a Jira issue id, then you may show Jira da
|
|||
|
||||
Within a `Commit`, the following Jira data can be used in template:
|
||||
|
||||
* `.JiraIssue.Summary` - Summary of the Jira story
|
||||
* `.JiraIssue.Description` - Description of the Jira story
|
||||
* `.JiraIssue.Type` - Original type of the Jira story, and `.Type` will be mapped type.
|
||||
* `.JiraIssue.Labels` - A list of strings, each is a Jira label.
|
||||
|
||||
- `.JiraIssue.Summary` - Summary of the Jira story
|
||||
- `.JiraIssue.Description` - Description of the Jira story
|
||||
- `.JiraIssue.Type` - Original type of the Jira story, and `.Type` will be mapped type.
|
||||
- `.JiraIssue.Labels` - A list of strings, each is a Jira label.
|
||||
|
||||
## FAQ
|
||||
|
||||
<details>
|
||||
<summary>Why do not you output files by default?</summary>
|
||||
This is not for the purpose of completely automating the generation of CHANGELOG files, it is only for assisting generation.
|
||||
This is not for the purpose of completely automating the generation of CHANGELOG
|
||||
files, it is only for assisting generation.
|
||||
|
||||
It is ideal to describe everything included in CHANGELOG in your commits. But actually it is very difficult to do it perfectly.
|
||||
It is ideal to describe everything included in CHANGELOG in your commits. But
|
||||
actually it is very difficult to do it perfectly.
|
||||
|
||||
There are times when you need to edit the generated output to write a great CHANGELOG.
|
||||
There are times when you need to edit the generated output to write a great CHANGELOG.
|
||||
|
||||
By displaying it on the standard output, it makes it easy to change the contents.
|
||||
</details>
|
||||
|
|
@ -597,63 +641,86 @@ Within a `Commit`, the following Jira data can be used in template:
|
|||
|
||||
Yes, it can be solved by using the `--next-tag` flag.
|
||||
|
||||
For example, let's say you want to upgrade your project to `2.0.0`.
|
||||
For example, let's say you want to upgrade your project to `2.0.0`.
|
||||
You can create CHANGELOG containing `2.0.0` as follows.
|
||||
|
||||
```bash
|
||||
$ git-chglog --next-tag 2.0.0 -o CHANGELOG.md
|
||||
$ git commit -am "release 2.0.0"
|
||||
$ git tag 2.0.0
|
||||
git-chglog --next-tag 2.0.0 -o CHANGELOG.md
|
||||
git commit -am "release 2.0.0"
|
||||
git tag 2.0.0
|
||||
```
|
||||
|
||||
The point to notice is that before actually creating a tag with `git`, it is conveying the next version with `--next-tag` :+1:
|
||||
The point to notice is that before actually creating a tag with `git`, it is
|
||||
conveying the next version with `--next-tag` :+1:
|
||||
|
||||
This is a step that is necessary for project operation in many cases.
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Can I generate a CHANGELOG based on certain tags?</summary>
|
||||
|
||||
|
||||
Yes, it can be solved by use the `--tag-filter-pattern` flag.
|
||||
|
||||
|
||||
For example, the following command will only include tags starting with "v":
|
||||
|
||||
```bash
|
||||
$ git-chglog --tag-filter-pattern '^v'
|
||||
git-chglog --tag-filter-pattern '^v'
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## TODO
|
||||
|
||||
* [x] Windows Support
|
||||
* [x] More styles (GitHub, GitLab, Bitbucket :tada:)
|
||||
* [ ] Snippetization of configuration files (improvement of reusability)
|
||||
* [ ] More test test test ... (and example)
|
||||
- [x] Windows Support
|
||||
- [x] More styles (GitHub, GitLab, Bitbucket :tada:)
|
||||
- [ ] Snippetization of configuration files (improvement of reusability)
|
||||
- [ ] More test test test ... (and example)
|
||||
|
||||
## Thanks
|
||||
|
||||
`git-chglog` is inspired by [conventional-changelog](https://github.com/conventional-changelog/conventional-changelog). Thank you!
|
||||
`git-chglog` is inspired by [conventional-changelog]. Thank you!
|
||||
|
||||
## Contributing
|
||||
|
||||
We alway welcome your contributions :clap:
|
||||
We always welcome your contributions :clap:
|
||||
|
||||
### Development
|
||||
## Development
|
||||
|
||||
1. Use Golang version `>= 1.24`
|
||||
1. Fork (https://github.com/git-chglog/git-chglog) :tada:
|
||||
1. Create a feature branch :coffee:
|
||||
1. Run test suite with the `$ make test` command and confirm that it passes :zap:
|
||||
1. Run linters with the `$ make lint` command and confirm it passes :broom:
|
||||
- The project uses [golangci-lint]
|
||||
1. Commit your changes :memo:
|
||||
1. Rebase your local changes against the `master` branch :bulb:
|
||||
1. Create new Pull Request :love_letter:
|
||||
|
||||
Bugs, feature requests and comments are more than welcome in the [issues](https://github.com/git-chglog/git-chglog/issues).
|
||||
Bugs, feature requests and comments are more than welcome in the [issues].
|
||||
|
||||
### Feedback
|
||||
## Release Process
|
||||
|
||||
I would like to make `git-chglog` a better tool.
|
||||
There is a `release` target within the Makefile that wraps up the steps to
|
||||
release a new version.
|
||||
|
||||
> NOTE: Pass the `VERSION` variable when running the command to properly set
|
||||
> the tag version for the release.
|
||||
|
||||
```bash
|
||||
$ VERSION=vX.Y.Z make release
|
||||
# EXAMPLE:
|
||||
$ VERSION=v0.11.3 make release
|
||||
```
|
||||
|
||||
Once the `tag` has been pushed, the `goreleaser` github action will take care
|
||||
of the rest.
|
||||
|
||||
## Feedback
|
||||
|
||||
I would like to make `git-chglog` a better tool.
|
||||
The goal is to be able to use in various projects.
|
||||
|
||||
Therefore, your feedback is very useful.
|
||||
Therefore, your feedback is very useful.
|
||||
I am very happy to tell you your opinions on Issues and PR :heart:
|
||||
|
||||
## CHANGELOG
|
||||
|
|
@ -662,13 +729,20 @@ See [CHANGELOG.md](./CHANGELOG.md)
|
|||
|
||||
## Related Projects
|
||||
|
||||
* [git-chglog/artwork](https://github.com/git-chglog/artwork) - Assets for `git-chglog`.
|
||||
- [git-chglog/artwork] - Assets for `git-chglog`.
|
||||
|
||||
## License
|
||||
|
||||
[MIT © tsuyoshiwada](./LICENSE)
|
||||
|
||||
[releases page]: https://github.com/git-chglog/git-chglog/releases
|
||||
[Commit]: https://godoc.org/github.com/git-chglog/git-chglog#Commit
|
||||
[doc-commit]: https://godoc.org/github.com/git-chglog/git-chglog#Commit
|
||||
[doc-commit-group]: https://godoc.org/github.com/git-chglog/git-chglog#CommitGroup
|
||||
[doc-ref]: https://godoc.org/github.com/git-chglog/git-chglog#Ref
|
||||
[doc-render-data]: https://godoc.org/github.com/git-chglog/git-chglog#RenderData
|
||||
[conventional-changelog]: https://github.com/conventional-changelog/conventional-changelog
|
||||
[golangci-lint]: https://golangci-lint.run/usage/install/#local-installation
|
||||
[issues]: https://github.com/git-chglog/git-chglog/issues
|
||||
[git-chglog/artwork]: https://github.com/git-chglog/artwork
|
||||
[Sprig]: http://masterminds.github.io/sprig
|
||||
|
|
|
|||
67
chglog.go
67
chglog.go
|
|
@ -5,13 +5,15 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"text/template"
|
||||
"time"
|
||||
|
||||
gitcmd "github.com/tsuyoshiwada/go-gitcmd"
|
||||
"github.com/Masterminds/sprig/v3"
|
||||
"github.com/tsuyoshiwada/go-gitcmd"
|
||||
)
|
||||
|
||||
// Options is an option used to process commits
|
||||
|
|
@ -19,6 +21,7 @@ type Options struct {
|
|||
Processor Processor
|
||||
NextTag string // Treat unreleased commits as specified tags (EXPERIMENTAL)
|
||||
TagFilterPattern string // Filter tag by regexp
|
||||
Sort string // Specify how to sort tags; currently supports "date" (default) or by "semver".
|
||||
NoCaseSensitive bool // Filter commits in a case insensitive way
|
||||
CommitFilters map[string][]string // Filter by using `Commit` properties and values. Filtering is not done by specifying an empty value
|
||||
CommitSortBy string // Property name to use for sorting `Commit` (e.g. `Scope`)
|
||||
|
|
@ -37,7 +40,7 @@ type Options struct {
|
|||
NoteKeywords []string // Keyword list to find `Note`. A semicolon is a separator, like `<keyword>:` (e.g. `BREAKING CHANGE`)
|
||||
JiraUsername string
|
||||
JiraToken string
|
||||
JiraUrl string
|
||||
JiraURL string
|
||||
JiraTypeMaps map[string]string
|
||||
JiraIssueDescriptionPattern string
|
||||
Paths []string // Path filter
|
||||
|
|
@ -119,7 +122,7 @@ func NewGenerator(logger *Logger, config *Config) *Generator {
|
|||
return &Generator{
|
||||
client: client,
|
||||
config: config,
|
||||
tagReader: newTagReader(client, config.Options.TagFilterPattern),
|
||||
tagReader: newTagReader(client, config.Options.TagFilterPattern, config.Options.Sort),
|
||||
tagSelector: newTagSelector(),
|
||||
commitParser: newCommitParser(logger, client, jiraClient, config),
|
||||
commitExtractor: newCommitExtractor(config.Options),
|
||||
|
|
@ -129,16 +132,21 @@ func NewGenerator(logger *Logger, config *Config) *Generator {
|
|||
// Generate gets the commit based on the specified tag `query` and writes the result to `io.Writer`
|
||||
//
|
||||
// tag `query` can be specified with the following rule
|
||||
// <old>..<new> - Commit contained in `<new>` tags from `<old>` (e.g. `1.0.0..2.0.0`)
|
||||
// <tagname>.. - Commit from the `<tagname>` to the latest tag (e.g. `1.0.0..`)
|
||||
// ..<tagname> - Commit from the oldest tag to `<tagname>` (e.g. `..1.0.0`)
|
||||
// <tagname> - Commit contained in `<tagname>` (e.g. `1.0.0`)
|
||||
//
|
||||
// <old>..<new> - Commit contained in `<new>` tags from `<old>` (e.g. `1.0.0..2.0.0`)
|
||||
// <tagname>.. - Commit from the `<tagname>` to the latest tag (e.g. `1.0.0..`)
|
||||
// ..<tagname> - Commit from the oldest tag to `<tagname>` (e.g. `..1.0.0`)
|
||||
// <tagname> - Commit contained in `<tagname>` (e.g. `1.0.0`)
|
||||
func (gen *Generator) Generate(w io.Writer, query string) error {
|
||||
back, err := gen.workdir()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer back()
|
||||
defer func() {
|
||||
if err = back(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}()
|
||||
|
||||
tags, first, err := gen.getTags(query)
|
||||
if err != nil {
|
||||
|
|
@ -269,7 +277,7 @@ func (gen *Generator) getTags(query string) ([]*Tag, string, error) {
|
|||
|
||||
// Assign the date with `readVersions()`
|
||||
tags = append([]*Tag{
|
||||
&Tag{
|
||||
{
|
||||
Name: next,
|
||||
Subject: next,
|
||||
Previous: previous,
|
||||
|
|
@ -318,30 +326,6 @@ func (gen *Generator) render(w io.Writer, unreleased *Unreleased, versions []*Ve
|
|||
"datetime": func(layout string, input time.Time) string {
|
||||
return input.Format(layout)
|
||||
},
|
||||
// check whether substs is withing s
|
||||
"contains": func(s, substr string) bool {
|
||||
return strings.Contains(s, substr)
|
||||
},
|
||||
// check whether s begins with prefix
|
||||
"hasPrefix": func(s, prefix string) bool {
|
||||
return strings.HasPrefix(s, prefix)
|
||||
},
|
||||
// check whether s ends with suffix
|
||||
"hasSuffix": func(s, suffix string) bool {
|
||||
return strings.HasSuffix(s, suffix)
|
||||
},
|
||||
// replace the first n instances of old with new
|
||||
"replace": func(s, old, new string, n int) string {
|
||||
return strings.Replace(s, old, new, n)
|
||||
},
|
||||
// lower case a string
|
||||
"lower": func(s string) string {
|
||||
return strings.ToLower(s)
|
||||
},
|
||||
// upper case a string
|
||||
"upper": func(s string) string {
|
||||
return strings.ToUpper(s)
|
||||
},
|
||||
// upper case the first character of a string
|
||||
"upperFirst": func(s string) string {
|
||||
if len(s) > 0 {
|
||||
|
|
@ -349,11 +333,26 @@ func (gen *Generator) render(w io.Writer, unreleased *Unreleased, versions []*Ve
|
|||
}
|
||||
return ""
|
||||
},
|
||||
// indent all lines of s n spaces
|
||||
"indent": func(s string, n int) string {
|
||||
if len(s) == 0 {
|
||||
return ""
|
||||
}
|
||||
pad := strings.Repeat(" ", n)
|
||||
return pad + strings.ReplaceAll(s, "\n", "\n"+pad)
|
||||
},
|
||||
// While Sprig provides these functions, they change the standard input
|
||||
// order which leads to a regression. For an example see:
|
||||
// https://github.com/Masterminds/sprig/blob/master/functions.go#L149
|
||||
"contains": strings.Contains,
|
||||
"hasPrefix": strings.HasPrefix,
|
||||
"hasSuffix": strings.HasSuffix,
|
||||
"replace": strings.Replace,
|
||||
}
|
||||
|
||||
fname := filepath.Base(gen.config.Template)
|
||||
|
||||
t := template.Must(template.New(fname).Funcs(fmap).ParseFiles(gen.config.Template))
|
||||
t := template.Must(template.New(fname).Funcs(sprig.TxtFuncMap()).Funcs(fmap).ParseFiles(gen.config.Template))
|
||||
|
||||
return t.Execute(w, &RenderData{
|
||||
Info: gen.config.Info,
|
||||
|
|
|
|||
220
chglog_test.go
220
chglog_test.go
|
|
@ -32,17 +32,17 @@ func TestMain(m *testing.M) {
|
|||
func setup(dir string, setupRepo func(commitFunc, tagFunc, gitcmd.Client)) {
|
||||
testDir := filepath.Join(cwd, testRepoRoot, dir)
|
||||
|
||||
os.RemoveAll(testDir)
|
||||
os.MkdirAll(testDir, os.ModePerm)
|
||||
os.Chdir(testDir)
|
||||
_ = os.RemoveAll(testDir)
|
||||
_ = os.MkdirAll(testDir, os.ModePerm)
|
||||
_ = os.Chdir(testDir)
|
||||
|
||||
loc, _ := time.LoadLocation("UTC")
|
||||
time.Local = loc
|
||||
|
||||
git := gitcmd.New(nil)
|
||||
git.Exec("init")
|
||||
git.Exec("config", "user.name", "test_user")
|
||||
git.Exec("config", "user.email", "test@example.com")
|
||||
_, _ = git.Exec("init")
|
||||
_, _ = git.Exec("config", "user.name", "test_user")
|
||||
_, _ = git.Exec("config", "user.email", "test@example.com")
|
||||
|
||||
var commit = func(date, subject, body string) {
|
||||
msg := subject
|
||||
|
|
@ -51,21 +51,21 @@ func setup(dir string, setupRepo func(commitFunc, tagFunc, gitcmd.Client)) {
|
|||
}
|
||||
t, _ := time.Parse(internalTimeFormat, date)
|
||||
d := t.Format("Mon Jan 2 15:04:05 2006 +0000")
|
||||
git.Exec("commit", "--allow-empty", "--date", d, "-m", msg)
|
||||
_, _ = git.Exec("commit", "--allow-empty", "--date", d, "-m", msg)
|
||||
}
|
||||
|
||||
var tag = func(name string) {
|
||||
git.Exec("tag", name)
|
||||
_, _ = git.Exec("tag", name)
|
||||
}
|
||||
|
||||
setupRepo(commit, tag, git)
|
||||
|
||||
os.Chdir(cwd)
|
||||
_ = os.Chdir(cwd)
|
||||
}
|
||||
|
||||
func cleanup() {
|
||||
os.Chdir(cwd)
|
||||
os.RemoveAll(filepath.Join(cwd, testRepoRoot))
|
||||
_ = os.Chdir(cwd)
|
||||
_ = os.RemoveAll(filepath.Join(cwd, testRepoRoot))
|
||||
}
|
||||
|
||||
func TestGeneratorNotFoundTags(t *testing.T) {
|
||||
|
|
@ -89,9 +89,11 @@ func TestGeneratorNotFoundTags(t *testing.T) {
|
|||
|
||||
buf := &bytes.Buffer{}
|
||||
err := gen.Generate(buf, "")
|
||||
expected := strings.TrimSpace(buf.String())
|
||||
|
||||
assert.Error(err)
|
||||
assert.Contains(err.Error(), "git-tag does not exist")
|
||||
assert.Equal("", buf.String())
|
||||
assert.Equal("", expected)
|
||||
}
|
||||
|
||||
func TestGeneratorNotFoundCommits(t *testing.T) {
|
||||
|
|
@ -116,8 +118,10 @@ func TestGeneratorNotFoundCommits(t *testing.T) {
|
|||
|
||||
buf := &bytes.Buffer{}
|
||||
err := gen.Generate(buf, "foo")
|
||||
expected := strings.TrimSpace(buf.String())
|
||||
|
||||
assert.Error(err)
|
||||
assert.Equal("", buf.String())
|
||||
assert.Equal("", expected)
|
||||
}
|
||||
|
||||
func TestGeneratorNotFoundCommitsOne(t *testing.T) {
|
||||
|
|
@ -171,9 +175,11 @@ func TestGeneratorNotFoundCommitsOne(t *testing.T) {
|
|||
|
||||
buf := &bytes.Buffer{}
|
||||
err := gen.Generate(buf, "foo")
|
||||
expected := strings.TrimSpace(buf.String())
|
||||
|
||||
assert.Error(err)
|
||||
assert.Contains(err.Error(), "\"foo\" was not found")
|
||||
assert.Equal("", buf.String())
|
||||
assert.Equal("", expected)
|
||||
}
|
||||
|
||||
func TestGeneratorWithTypeScopeSubject(t *testing.T) {
|
||||
|
|
@ -193,7 +199,7 @@ func TestGeneratorWithTypeScopeSubject(t *testing.T) {
|
|||
tag("1.1.0")
|
||||
|
||||
commit("2018-01-03 00:00:00", "feat(context): Online breaking change", "BREAKING CHANGE: Online breaking change message.")
|
||||
commit("2018-01-03 00:01:00", "feat(router): Muliple breaking change", `This is body,
|
||||
commit("2018-01-03 00:01:00", "feat(router): Multiple breaking change", `This is body,
|
||||
|
||||
BREAKING CHANGE:
|
||||
Multiple
|
||||
|
|
@ -215,8 +221,9 @@ change message.`)
|
|||
RepositoryURL: "https://github.com/git-chglog/git-chglog",
|
||||
},
|
||||
Options: &Options{
|
||||
Sort: "date",
|
||||
CommitFilters: map[string][]string{
|
||||
"Type": []string{
|
||||
"Type": {
|
||||
"feat",
|
||||
"fix",
|
||||
},
|
||||
|
|
@ -256,7 +263,7 @@ change message.`)
|
|||
|
||||
buf := &bytes.Buffer{}
|
||||
err := gen.Generate(buf, "")
|
||||
output := strings.Replace(strings.TrimSpace(buf.String()), "\r\n", "\n", -1)
|
||||
expected := strings.TrimSpace(buf.String())
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(`<a name="unreleased"></a>
|
||||
|
|
@ -270,7 +277,7 @@ change message.`)
|
|||
## [2.0.0-beta.0] - 2018-01-03
|
||||
### Features
|
||||
- **context:** Online breaking change
|
||||
- **router:** Muliple breaking change
|
||||
- **router:** Multiple breaking change
|
||||
|
||||
### BREAKING CHANGE
|
||||
|
||||
|
|
@ -302,7 +309,7 @@ Online breaking change message.
|
|||
|
||||
[Unreleased]: https://github.com/git-chglog/git-chglog/compare/2.0.0-beta.0...HEAD
|
||||
[2.0.0-beta.0]: https://github.com/git-chglog/git-chglog/compare/1.1.0...2.0.0-beta.0
|
||||
[1.1.0]: https://github.com/git-chglog/git-chglog/compare/1.0.0...1.1.0`, output)
|
||||
[1.1.0]: https://github.com/git-chglog/git-chglog/compare/1.0.0...1.1.0`, expected)
|
||||
}
|
||||
|
||||
func TestGeneratorWithNextTag(t *testing.T) {
|
||||
|
|
@ -329,9 +336,10 @@ func TestGeneratorWithNextTag(t *testing.T) {
|
|||
RepositoryURL: "https://github.com/git-chglog/git-chglog",
|
||||
},
|
||||
Options: &Options{
|
||||
Sort: "date",
|
||||
NextTag: "3.0.0",
|
||||
CommitFilters: map[string][]string{
|
||||
"Type": []string{
|
||||
"Type": {
|
||||
"feat",
|
||||
},
|
||||
},
|
||||
|
|
@ -352,7 +360,7 @@ func TestGeneratorWithNextTag(t *testing.T) {
|
|||
|
||||
buf := &bytes.Buffer{}
|
||||
err := gen.Generate(buf, "")
|
||||
output := strings.Replace(strings.TrimSpace(buf.String()), "\r\n", "\n", -1)
|
||||
expected := strings.TrimSpace(buf.String())
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(`<a name="unreleased"></a>
|
||||
|
|
@ -379,11 +387,11 @@ func TestGeneratorWithNextTag(t *testing.T) {
|
|||
|
||||
[Unreleased]: https://github.com/git-chglog/git-chglog/compare/3.0.0...HEAD
|
||||
[3.0.0]: https://github.com/git-chglog/git-chglog/compare/2.0.0...3.0.0
|
||||
[2.0.0]: https://github.com/git-chglog/git-chglog/compare/1.0.0...2.0.0`, output)
|
||||
[2.0.0]: https://github.com/git-chglog/git-chglog/compare/1.0.0...2.0.0`, expected)
|
||||
|
||||
buf = &bytes.Buffer{}
|
||||
err = gen.Generate(buf, "3.0.0")
|
||||
output = strings.Replace(strings.TrimSpace(buf.String()), "\r\n", "\n", -1)
|
||||
expected = strings.TrimSpace(buf.String())
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(`<a name="unreleased"></a>
|
||||
|
|
@ -397,7 +405,7 @@ func TestGeneratorWithNextTag(t *testing.T) {
|
|||
|
||||
|
||||
[Unreleased]: https://github.com/git-chglog/git-chglog/compare/3.0.0...HEAD
|
||||
[3.0.0]: https://github.com/git-chglog/git-chglog/compare/2.0.0...3.0.0`, output)
|
||||
[3.0.0]: https://github.com/git-chglog/git-chglog/compare/2.0.0...3.0.0`, expected)
|
||||
}
|
||||
|
||||
func TestGeneratorWithTagFiler(t *testing.T) {
|
||||
|
|
@ -424,7 +432,7 @@ func TestGeneratorWithTagFiler(t *testing.T) {
|
|||
Options: &Options{
|
||||
TagFilterPattern: "^v",
|
||||
CommitFilters: map[string][]string{
|
||||
"Type": []string{
|
||||
"Type": {
|
||||
"feat",
|
||||
},
|
||||
},
|
||||
|
|
@ -445,6 +453,7 @@ func TestGeneratorWithTagFiler(t *testing.T) {
|
|||
|
||||
buf := &bytes.Buffer{}
|
||||
err := gen.Generate(buf, "")
|
||||
expected := strings.TrimSpace(buf.String())
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(`<a name="unreleased"></a>
|
||||
|
|
@ -458,6 +467,165 @@ func TestGeneratorWithTagFiler(t *testing.T) {
|
|||
- **core:** version dev-1.0.0
|
||||
|
||||
|
||||
[Unreleased]: https://github.com/git-chglog/git-chglog/compare/v1.0.0...HEAD`, strings.TrimSpace(buf.String()))
|
||||
[Unreleased]: https://github.com/git-chglog/git-chglog/compare/v1.0.0...HEAD`, expected)
|
||||
|
||||
}
|
||||
|
||||
func TestGeneratorWithTrimmedBody(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
testName := "trimmed_body"
|
||||
|
||||
setup(testName, func(commit commitFunc, tag tagFunc, _ gitcmd.Client) {
|
||||
commit("2018-01-01 00:00:00", "feat: single line commit", "")
|
||||
commit("2018-01-01 00:01:00", "feat: multi-line commit", `
|
||||
More details about the change and why it went in.
|
||||
|
||||
BREAKING CHANGE:
|
||||
|
||||
When using .TrimmedBody Notes are not included and can only appear in the Notes section.
|
||||
|
||||
Signed-off-by: First Last <first.last@mail.com>
|
||||
|
||||
Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>`)
|
||||
|
||||
commit("2018-01-01 00:00:00", "feat: another single line commit", "")
|
||||
tag("1.0.0")
|
||||
})
|
||||
|
||||
gen := NewGenerator(NewLogger(os.Stdout, os.Stderr, false, true),
|
||||
&Config{
|
||||
Bin: "git",
|
||||
WorkingDir: filepath.Join(testRepoRoot, testName),
|
||||
Template: filepath.Join(cwd, "testdata", testName+".md"),
|
||||
Info: &Info{
|
||||
Title: "CHANGELOG Example",
|
||||
RepositoryURL: "https://github.com/git-chglog/git-chglog",
|
||||
},
|
||||
Options: &Options{
|
||||
CommitFilters: map[string][]string{
|
||||
"Type": {
|
||||
"feat",
|
||||
},
|
||||
},
|
||||
CommitSortBy: "Scope",
|
||||
CommitGroupBy: "Type",
|
||||
CommitGroupSortBy: "Title",
|
||||
CommitGroupTitleMaps: map[string]string{
|
||||
"feat": "Features",
|
||||
},
|
||||
HeaderPattern: "^(\\w*)(?:\\(([\\w\\$\\.\\-\\*\\s]*)\\))?\\:\\s(.*)$",
|
||||
HeaderPatternMaps: []string{
|
||||
"Type",
|
||||
"Scope",
|
||||
"Subject",
|
||||
},
|
||||
NoteKeywords: []string{
|
||||
"BREAKING CHANGE",
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
err := gen.Generate(buf, "")
|
||||
expected := strings.TrimSpace(buf.String())
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(`<a name="unreleased"></a>
|
||||
## [Unreleased]
|
||||
|
||||
|
||||
<a name="1.0.0"></a>
|
||||
## 1.0.0 - 2018-01-01
|
||||
### Features
|
||||
- another single line commit
|
||||
- multi-line commit
|
||||
More details about the change and why it went in.
|
||||
- single line commit
|
||||
|
||||
### BREAKING CHANGE
|
||||
|
||||
When using .TrimmedBody Notes are not included and can only appear in the Notes section.
|
||||
|
||||
|
||||
[Unreleased]: https://github.com/git-chglog/git-chglog/compare/1.0.0...HEAD`, expected)
|
||||
}
|
||||
|
||||
func TestGeneratorWithSprig(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
testName := "with_sprig"
|
||||
|
||||
setup(testName, func(commit commitFunc, tag tagFunc, _ gitcmd.Client) {
|
||||
commit("2018-01-01 00:00:00", "feat(core): version 1.0.0", "")
|
||||
tag("1.0.0")
|
||||
|
||||
commit("2018-02-01 00:00:00", "feat(core): version 2.0.0", "")
|
||||
tag("2.0.0")
|
||||
|
||||
commit("2018-03-01 00:00:00", "feat(core): version 3.0.0", "")
|
||||
})
|
||||
|
||||
gen := NewGenerator(NewLogger(os.Stdout, os.Stderr, false, true),
|
||||
&Config{
|
||||
Bin: "git",
|
||||
WorkingDir: filepath.Join(testRepoRoot, testName),
|
||||
Template: filepath.Join(cwd, "testdata", testName+".md"),
|
||||
Info: &Info{
|
||||
Title: "CHANGELOG Example",
|
||||
RepositoryURL: "https://github.com/git-chglog/git-chglog",
|
||||
},
|
||||
Options: &Options{
|
||||
Sort: "date",
|
||||
NextTag: "3.0.0",
|
||||
CommitFilters: map[string][]string{
|
||||
"Type": {
|
||||
"feat",
|
||||
},
|
||||
},
|
||||
CommitSortBy: "Scope",
|
||||
CommitGroupBy: "Type",
|
||||
CommitGroupSortBy: "Title",
|
||||
CommitGroupTitleMaps: map[string]string{
|
||||
"feat": "Features",
|
||||
},
|
||||
HeaderPattern: "^(\\w*)(?:\\(([\\w\\$\\.\\-\\*\\s]*)\\))?\\:\\s(.*)$",
|
||||
HeaderPatternMaps: []string{
|
||||
"Type",
|
||||
"Scope",
|
||||
"Subject",
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
err := gen.Generate(buf, "")
|
||||
expected := strings.TrimSpace(buf.String())
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(`My Changelog
|
||||
<a name="unreleased"></a>
|
||||
## [Unreleased]
|
||||
|
||||
|
||||
<a name="3.0.0"></a>
|
||||
## [3.0.0] - 2018-03-01
|
||||
### Features
|
||||
- **CORE:** version 3.0.0
|
||||
|
||||
|
||||
<a name="2.0.0"></a>
|
||||
## [2.0.0] - 2018-02-01
|
||||
### Features
|
||||
- **CORE:** version 2.0.0
|
||||
|
||||
|
||||
<a name="1.0.0"></a>
|
||||
## 1.0.0 - 2018-01-01
|
||||
### Features
|
||||
- **CORE:** version 1.0.0
|
||||
|
||||
|
||||
[Unreleased]: https://github.com/git-chglog/git-chglog/compare/3.0.0...HEAD
|
||||
[3.0.0]: https://github.com/git-chglog/git-chglog/compare/2.0.0...3.0.0
|
||||
[2.0.0]: https://github.com/git-chglog/git-chglog/compare/1.0.0...2.0.0`, expected)
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/fatih/color"
|
||||
|
||||
chglog "github.com/git-chglog/git-chglog"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -8,8 +8,9 @@ import (
|
|||
"regexp"
|
||||
"testing"
|
||||
|
||||
chglog "github.com/git-chglog/git-chglog"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
chglog "github.com/git-chglog/git-chglog"
|
||||
)
|
||||
|
||||
func TestCLIForStdout(t *testing.T) {
|
||||
|
|
@ -36,7 +37,7 @@ func TestCLIForStdout(t *testing.T) {
|
|||
if config.Bin != "/custom/bin/git" {
|
||||
return errors.New("")
|
||||
}
|
||||
w.Write([]byte("success!!"))
|
||||
_, _ = w.Write([]byte("success!!"))
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
|
@ -104,7 +105,7 @@ func TestCLIForFile(t *testing.T) {
|
|||
if filepath.ToSlash(config.Bin) != "/custom/bin/git" {
|
||||
return errors.New("")
|
||||
}
|
||||
w.Write([]byte("success!!"))
|
||||
_, _ = w.Write([]byte("success!!"))
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,8 +4,9 @@ import (
|
|||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
chglog "github.com/git-chglog/git-chglog"
|
||||
"github.com/imdario/mergo"
|
||||
|
||||
chglog "github.com/git-chglog/git-chglog"
|
||||
)
|
||||
|
||||
// Info ...
|
||||
|
|
@ -49,6 +50,7 @@ type NoteOptions struct {
|
|||
Keywords []string `yaml:"keywords"`
|
||||
}
|
||||
|
||||
// JiraClientInfoOptions ...
|
||||
type JiraClientInfoOptions struct {
|
||||
Username string `yaml:"username"`
|
||||
Token string `yaml:"token"`
|
||||
|
|
@ -70,6 +72,7 @@ type JiraOptions struct {
|
|||
// Options ...
|
||||
type Options struct {
|
||||
TagFilterPattern string `yaml:"tag_filter_pattern"`
|
||||
Sort string `yaml:"sort"`
|
||||
Commits CommitOptions `yaml:"commits"`
|
||||
CommitGroups CommitGroupOptions `yaml:"commit_groups"`
|
||||
Header PatternOptions `yaml:"header"`
|
||||
|
|
@ -120,6 +123,7 @@ func (config *Config) Normalize(ctx *CLIContext) error {
|
|||
}
|
||||
|
||||
config.normalizeStyle()
|
||||
config.normalizeTagSortBy()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
@ -136,6 +140,19 @@ func (config *Config) normalizeStyle() {
|
|||
}
|
||||
}
|
||||
|
||||
func (config *Config) normalizeTagSortBy() {
|
||||
switch {
|
||||
case config.Options.Sort == "":
|
||||
config.Options.Sort = "date"
|
||||
case strings.EqualFold(config.Options.Sort, "date"):
|
||||
config.Options.Sort = "date"
|
||||
case strings.EqualFold(config.Options.Sort, "semver"):
|
||||
config.Options.Sort = "semver"
|
||||
default:
|
||||
config.Options.Sort = "date"
|
||||
}
|
||||
}
|
||||
|
||||
// For GitHub
|
||||
func (config *Config) normalizeStyleOfGitHub() {
|
||||
opts := config.Options
|
||||
|
|
@ -286,11 +303,12 @@ func (config *Config) Convert(ctx *CLIContext) *chglog.Config {
|
|||
Template: orValue(ctx.Template, config.Template),
|
||||
Info: &chglog.Info{
|
||||
Title: info.Title,
|
||||
RepositoryURL: orValue(ctx.RepositoryUrl, info.RepositoryURL),
|
||||
RepositoryURL: orValue(ctx.RepositoryURL, info.RepositoryURL),
|
||||
},
|
||||
Options: &chglog.Options{
|
||||
NextTag: ctx.NextTag,
|
||||
TagFilterPattern: ctx.TagFilterPattern,
|
||||
Sort: orValue(ctx.Sort, opts.Sort),
|
||||
NoCaseSensitive: ctx.NoCaseSensitive,
|
||||
Paths: ctx.Paths,
|
||||
CommitFilters: opts.Commits.Filters,
|
||||
|
|
@ -298,6 +316,7 @@ func (config *Config) Convert(ctx *CLIContext) *chglog.Config {
|
|||
CommitGroupBy: opts.CommitGroups.GroupBy,
|
||||
CommitGroupSortBy: opts.CommitGroups.SortBy,
|
||||
CommitGroupTitleMaps: opts.CommitGroups.TitleMaps,
|
||||
CommitGroupTitleOrder: opts.CommitGroups.TitleOrder,
|
||||
HeaderPattern: opts.Header.Pattern,
|
||||
HeaderPatternMaps: opts.Header.PatternMaps,
|
||||
IssuePrefix: opts.Issues.Prefix,
|
||||
|
|
@ -309,7 +328,7 @@ func (config *Config) Convert(ctx *CLIContext) *chglog.Config {
|
|||
NoteKeywords: opts.Notes.Keywords,
|
||||
JiraUsername: orValue(ctx.JiraUsername, opts.Jira.ClintInfo.Username),
|
||||
JiraToken: orValue(ctx.JiraToken, opts.Jira.ClintInfo.Token),
|
||||
JiraUrl: orValue(ctx.JiraUrl, opts.Jira.ClintInfo.URL),
|
||||
JiraURL: orValue(ctx.JiraURL, opts.Jira.ClintInfo.URL),
|
||||
JiraTypeMaps: opts.Jira.Issue.TypeMaps,
|
||||
JiraIssueDescriptionPattern: opts.Jira.Issue.DescriptionPattern,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
// ConfigLoader ...
|
||||
|
|
@ -20,7 +21,8 @@ func NewConfigLoader() ConfigLoader {
|
|||
}
|
||||
|
||||
func (loader *configLoaderImpl) Load(path string) (*Config, error) {
|
||||
bytes, err := ioutil.ReadFile(path)
|
||||
fp := filepath.Clean(path)
|
||||
bytes, err := os.ReadFile(fp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ type CLIContext struct {
|
|||
Stderr io.Writer
|
||||
ConfigPath string
|
||||
Template string
|
||||
RepositoryUrl string
|
||||
RepositoryURL string
|
||||
OutputPath string
|
||||
Silent bool
|
||||
NoColor bool
|
||||
|
|
@ -22,8 +22,9 @@ type CLIContext struct {
|
|||
TagFilterPattern string
|
||||
JiraUsername string
|
||||
JiraToken string
|
||||
JiraUrl string
|
||||
JiraURL string
|
||||
Paths []string
|
||||
Sort string
|
||||
}
|
||||
|
||||
// InitContext ...
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ func (t *customTemplateBuilderImpl) Build(ans *Answer) (string, error) {
|
|||
tpl += t.versionHeader(ans.Style, ans.Template)
|
||||
|
||||
// commits
|
||||
tpl += t.commits(ans.Template, ans.CommitMessageFormat)
|
||||
tpl += t.commits(ans.CommitMessageFormat)
|
||||
|
||||
// revert
|
||||
if ans.IncludeReverts {
|
||||
|
|
@ -75,7 +75,7 @@ func (*customTemplateBuilderImpl) versionHeader(style, template string) string {
|
|||
return tpl
|
||||
}
|
||||
|
||||
func (*customTemplateBuilderImpl) commits(template, format string) string {
|
||||
func (*customTemplateBuilderImpl) commits(format string) string {
|
||||
var (
|
||||
header string
|
||||
body string
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ package main
|
|||
|
||||
import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
)
|
||||
|
||||
|
|
@ -35,15 +34,18 @@ func (*osFileSystem) Exists(path string) bool {
|
|||
|
||||
func (*osFileSystem) MkdirP(path string) error {
|
||||
if _, err := os.Stat(path); os.IsNotExist(err) {
|
||||
//nolint:gosec
|
||||
return os.MkdirAll(path, os.ModePerm)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*osFileSystem) Create(name string) (File, error) {
|
||||
//nolint: gosec
|
||||
return os.Create(name)
|
||||
}
|
||||
|
||||
func (*osFileSystem) WriteFile(path string, content []byte) error {
|
||||
return ioutil.WriteFile(path, content, os.ModePerm)
|
||||
//nolint:gosec
|
||||
return os.WriteFile(path, content, os.ModePerm)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,17 +2,16 @@ package main
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/git-chglog/git-chglog"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/fatih/color"
|
||||
gitcmd "github.com/tsuyoshiwada/go-gitcmd"
|
||||
|
||||
chglog "github.com/git-chglog/git-chglog"
|
||||
)
|
||||
|
||||
// Initializer ...
|
||||
type Initializer struct {
|
||||
ctx *InitContext
|
||||
client gitcmd.Client
|
||||
fs FileSystem
|
||||
logger *chglog.Logger
|
||||
questioner Questioner
|
||||
|
|
|
|||
|
|
@ -3,14 +3,20 @@ package main
|
|||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/mattn/go-colorable"
|
||||
gitcmd "github.com/tsuyoshiwada/go-gitcmd"
|
||||
"github.com/tsuyoshiwada/go-gitcmd"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
// version is passed in via LDFLAGS main.version
|
||||
var version string
|
||||
|
||||
// CreateApp creates and initializes CLI application
|
||||
// with description, flags, version, etc.
|
||||
func CreateApp(actionFunc cli.ActionFunc) *cli.App {
|
||||
ttl := color.New(color.FgYellow).SprintFunc()
|
||||
|
||||
|
|
@ -71,7 +77,7 @@ func CreateApp(actionFunc cli.ActionFunc) *cli.App {
|
|||
app := cli.NewApp()
|
||||
app.Name = "git-chglog"
|
||||
app.Usage = "todo usage for git-chglog"
|
||||
app.Version = Version
|
||||
app.Version = version
|
||||
|
||||
app.Flags = []cli.Flag{
|
||||
// init
|
||||
|
|
@ -88,17 +94,17 @@ func CreateApp(actionFunc cli.ActionFunc) *cli.App {
|
|||
|
||||
// config
|
||||
&cli.StringFlag{
|
||||
Name: "config, c",
|
||||
Name: "config, c",
|
||||
Aliases: []string{"c"},
|
||||
Usage: "specifies a different configuration file to pick up",
|
||||
Value: ".chglog/config.yml",
|
||||
Usage: "specifies a different configuration file to pick up",
|
||||
Value: ".chglog/config.yml",
|
||||
},
|
||||
|
||||
// template
|
||||
&cli.StringFlag{
|
||||
Name: "template",
|
||||
Name: "template",
|
||||
Aliases: []string{"t"},
|
||||
Usage: "specifies a template file to pick up. If not specified, use the one in config",
|
||||
Usage: "specifies a template file to pick up. If not specified, use the one in config",
|
||||
},
|
||||
|
||||
// repository url
|
||||
|
|
@ -109,9 +115,9 @@ func CreateApp(actionFunc cli.ActionFunc) *cli.App {
|
|||
|
||||
// output
|
||||
&cli.StringFlag{
|
||||
Name: "output",
|
||||
Name: "output",
|
||||
Aliases: []string{"o"},
|
||||
Usage: "output path and filename for the changelogs. If not specified, output to stdout",
|
||||
Usage: "output path and filename for the changelogs. If not specified, output to stdout",
|
||||
},
|
||||
|
||||
&cli.StringFlag{
|
||||
|
|
@ -172,6 +178,13 @@ func CreateApp(actionFunc cli.ActionFunc) *cli.App {
|
|||
EnvVars: []string{"JIRA_TOKEN"},
|
||||
},
|
||||
|
||||
// sort
|
||||
&cli.StringFlag{
|
||||
Name: "sort",
|
||||
Usage: "Specify how to sort tags; currently supports \"date\" or by \"semver\"",
|
||||
DefaultText: "date",
|
||||
},
|
||||
|
||||
// help & version
|
||||
cli.HelpFlag,
|
||||
cli.VersionFlag,
|
||||
|
|
@ -182,6 +195,8 @@ func CreateApp(actionFunc cli.ActionFunc) *cli.App {
|
|||
return app
|
||||
}
|
||||
|
||||
// AppAction is a callback function to create initializer
|
||||
// and CLIContext and ultimately run the application.
|
||||
func AppAction(c *cli.Context) error {
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
|
|
@ -218,6 +233,8 @@ func AppAction(c *cli.Context) error {
|
|||
Stdout: colorable.NewColorableStdout(),
|
||||
Stderr: colorable.NewColorableStderr(),
|
||||
ConfigPath: c.String("config"),
|
||||
Template: c.String("template"),
|
||||
RepositoryURL: c.String("repository-url"),
|
||||
OutputPath: c.String("output"),
|
||||
Silent: c.Bool("silent"),
|
||||
NoColor: c.Bool("no-color"),
|
||||
|
|
@ -228,8 +245,9 @@ func AppAction(c *cli.Context) error {
|
|||
TagFilterPattern: c.String("tag-filter-pattern"),
|
||||
JiraUsername: c.String("jira-username"),
|
||||
JiraToken: c.String("jira-token"),
|
||||
JiraUrl: c.String("jira-url"),
|
||||
JiraURL: c.String("jira-url"),
|
||||
Paths: c.StringSlice("path"),
|
||||
Sort: c.String("sort"),
|
||||
},
|
||||
fs,
|
||||
NewConfigLoader(),
|
||||
|
|
@ -243,5 +261,8 @@ func AppAction(c *cli.Context) error {
|
|||
|
||||
func main() {
|
||||
app := CreateApp(AppAction)
|
||||
app.Run(os.Args)
|
||||
err := app.Run(os.Args)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,16 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/urfave/cli/v2"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var gAssert *assert.Assertions
|
||||
|
||||
func mock_app_action(c *cli.Context) error {
|
||||
func mockAppAction(c *cli.Context) error {
|
||||
assert := gAssert
|
||||
assert.Equal("c.yml", c.String("config"))
|
||||
assert.Equal("^v", c.String("tag-filter-pattern"))
|
||||
|
|
@ -25,7 +27,7 @@ func TestCreateApp(t *testing.T) {
|
|||
assert.True(true)
|
||||
gAssert = assert
|
||||
|
||||
app := CreateApp(mock_app_action)
|
||||
app := CreateApp(mockAppAction)
|
||||
args := []string{
|
||||
"git-chglog",
|
||||
"--silent",
|
||||
|
|
@ -36,5 +38,8 @@ func TestCreateApp(t *testing.T) {
|
|||
"--next-tag", "v5",
|
||||
"--tag-filter-pattern", "^v",
|
||||
}
|
||||
app.Run(args)
|
||||
err := app.Run(args)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ package main
|
|||
import (
|
||||
"testing"
|
||||
|
||||
chglog "github.com/git-chglog/git-chglog"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
chglog "github.com/git-chglog/git-chglog"
|
||||
)
|
||||
|
||||
func TestProcessorFactory(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ import (
|
|||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
gitcmd "github.com/tsuyoshiwada/go-gitcmd"
|
||||
survey "github.com/AlecAivazis/survey/v2"
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/tsuyoshiwada/go-gitcmd"
|
||||
)
|
||||
|
||||
// Answer ...
|
||||
|
|
@ -52,11 +52,12 @@ func (q *questionerImpl) Ask() (*Answer, error) {
|
|||
t := q.fs.Exists(tpl)
|
||||
msg := ""
|
||||
|
||||
if c && t {
|
||||
switch {
|
||||
case c && t:
|
||||
msg = fmt.Sprintf("\"%s\" and \"%s\" already exists. Do you want to overwrite?", config, tpl)
|
||||
} else if c {
|
||||
case c:
|
||||
msg = fmt.Sprintf("\"%s\" already exists. Do you want to overwrite?", config)
|
||||
} else if t {
|
||||
case t:
|
||||
msg = fmt.Sprintf("\"%s\" already exists. Do you want to overwrite?", tpl)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
var reSSH = regexp.MustCompile("^\\w+@([\\w\\.\\-]+):([\\w\\.\\-]+)\\/([\\w\\.\\-]+)$")
|
||||
var reSSH = regexp.MustCompile(`^\w+@([\w\.\-]+):([\w\.\-]+)\/([\w\.\-]+)$`)
|
||||
|
||||
func remoteOriginURLToHTTP(rawurl string) string {
|
||||
if rawurl == "" {
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ func (f *CommitMessageFormat) PatternMapString() string {
|
|||
return fmt.Sprintf("\n%s", strings.Join(arr, "\n"))
|
||||
}
|
||||
|
||||
// FilterTypeString ...
|
||||
// FilterTypesString ...
|
||||
func (f *CommitMessageFormat) FilterTypesString() string {
|
||||
if len(f.typeSamples) == 0 {
|
||||
return " []"
|
||||
|
|
|
|||
|
|
@ -1,4 +0,0 @@
|
|||
package main
|
||||
|
||||
// Version of git-chglog cli client
|
||||
const Version = "v0.11.1"
|
||||
|
|
@ -119,6 +119,7 @@ func (e *commitExtractor) commitGroupTitle(commit *Commit) (string, string) {
|
|||
if t, ok := e.opts.CommitGroupTitleMaps[v]; ok {
|
||||
ttl = t
|
||||
} else {
|
||||
//nolint:staticcheck
|
||||
ttl = strings.Title(raw)
|
||||
}
|
||||
}
|
||||
|
|
@ -127,7 +128,11 @@ func (e *commitExtractor) commitGroupTitle(commit *Commit) (string, string) {
|
|||
return raw, ttl
|
||||
}
|
||||
|
||||
func (e *commitExtractor) sortCommitGroups(groups []*CommitGroup) {
|
||||
func (e *commitExtractor) sortCommitGroups(groups []*CommitGroup) { //nolint:gocyclo
|
||||
// NOTE(khos2ow): this function is over our cyclomatic complexity goal.
|
||||
// Be wary when adding branches, and look for functionality that could
|
||||
// be reasonably moved into an injected dependency.
|
||||
|
||||
order := make(map[string]int)
|
||||
if e.opts.CommitGroupSortBy == "Custom" {
|
||||
for i, t := range e.opts.CommitGroupTitleOrder {
|
||||
|
|
@ -136,6 +141,9 @@ func (e *commitExtractor) sortCommitGroups(groups []*CommitGroup) {
|
|||
}
|
||||
|
||||
// groups
|
||||
// TODO(khos2ow): move the inline sort function to
|
||||
// conceret implementation of sort.Interface in order
|
||||
// to reduce cyclomatic complaxity.
|
||||
sort.Slice(groups, func(i, j int) bool {
|
||||
if e.opts.CommitGroupSortBy == "Custom" {
|
||||
return order[groups[i].RawTitle] < order[groups[j].RawTitle]
|
||||
|
|
@ -165,6 +173,11 @@ func (e *commitExtractor) sortCommitGroups(groups []*CommitGroup) {
|
|||
|
||||
// commits
|
||||
for _, group := range groups {
|
||||
group := group // pin group to avoid potential bugs with passing group to lower functions
|
||||
|
||||
// TODO(khos2ow): move the inline sort function to
|
||||
// conceret implementation of sort.Interface in order
|
||||
// to reduce cyclomatic complaxity.
|
||||
sort.Slice(group.Commits, func(i, j int) bool {
|
||||
var (
|
||||
a, b interface{}
|
||||
|
|
@ -198,6 +211,7 @@ func (e *commitExtractor) sortNoteGroups(groups []*NoteGroup) {
|
|||
|
||||
// notes
|
||||
for _, group := range groups {
|
||||
group := group // pin group to avoid potential bugs with passing group to lower functions
|
||||
sort.Slice(group.Notes, func(i, j int) bool {
|
||||
return strings.ToLower(group.Notes[i].Title) < strings.ToLower(group.Notes[j].Title)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -20,14 +20,14 @@ func TestCommitExtractor(t *testing.T) {
|
|||
|
||||
fixtures := []*Commit{
|
||||
// [0]
|
||||
&Commit{
|
||||
{
|
||||
Type: "foo",
|
||||
Scope: "c",
|
||||
Header: "1",
|
||||
Notes: []*Note{},
|
||||
},
|
||||
// [1]
|
||||
&Commit{
|
||||
{
|
||||
Type: "foo",
|
||||
Scope: "b",
|
||||
Header: "2",
|
||||
|
|
@ -37,7 +37,7 @@ func TestCommitExtractor(t *testing.T) {
|
|||
},
|
||||
},
|
||||
// [2]
|
||||
&Commit{
|
||||
{
|
||||
Type: "bar",
|
||||
Scope: "d",
|
||||
Header: "3",
|
||||
|
|
@ -47,7 +47,7 @@ func TestCommitExtractor(t *testing.T) {
|
|||
},
|
||||
},
|
||||
// [3]
|
||||
&Commit{
|
||||
{
|
||||
Type: "foo",
|
||||
Scope: "a",
|
||||
Header: "4",
|
||||
|
|
@ -56,7 +56,7 @@ func TestCommitExtractor(t *testing.T) {
|
|||
},
|
||||
},
|
||||
// [4]
|
||||
&Commit{
|
||||
{
|
||||
Type: "",
|
||||
Scope: "",
|
||||
Header: "Merge1",
|
||||
|
|
@ -67,7 +67,7 @@ func TestCommitExtractor(t *testing.T) {
|
|||
},
|
||||
},
|
||||
// [5]
|
||||
&Commit{
|
||||
{
|
||||
Type: "",
|
||||
Scope: "",
|
||||
Header: "Revert1",
|
||||
|
|
@ -81,14 +81,14 @@ func TestCommitExtractor(t *testing.T) {
|
|||
commitGroups, mergeCommits, revertCommits, noteGroups := extractor.Extract(fixtures)
|
||||
|
||||
assert.Equal([]*CommitGroup{
|
||||
&CommitGroup{
|
||||
{
|
||||
RawTitle: "bar",
|
||||
Title: "BAR",
|
||||
Commits: []*Commit{
|
||||
fixtures[2],
|
||||
},
|
||||
},
|
||||
&CommitGroup{
|
||||
{
|
||||
RawTitle: "foo",
|
||||
Title: "Foo",
|
||||
Commits: []*Commit{
|
||||
|
|
@ -108,26 +108,26 @@ func TestCommitExtractor(t *testing.T) {
|
|||
}, revertCommits)
|
||||
|
||||
assert.Equal([]*NoteGroup{
|
||||
&NoteGroup{
|
||||
{
|
||||
Title: "note1-title",
|
||||
Notes: []*Note{
|
||||
fixtures[1].Notes[0],
|
||||
fixtures[2].Notes[0],
|
||||
},
|
||||
},
|
||||
&NoteGroup{
|
||||
{
|
||||
Title: "note2-title",
|
||||
Notes: []*Note{
|
||||
fixtures[1].Notes[1],
|
||||
},
|
||||
},
|
||||
&NoteGroup{
|
||||
{
|
||||
Title: "note3-title",
|
||||
Notes: []*Note{
|
||||
fixtures[2].Notes[1],
|
||||
},
|
||||
},
|
||||
&NoteGroup{
|
||||
{
|
||||
Title: "note4-title",
|
||||
Notes: []*Note{
|
||||
fixtures[3].Notes[0],
|
||||
|
|
|
|||
|
|
@ -4,7 +4,11 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
func commitFilter(commits []*Commit, filters map[string][]string, noCaseSensitive bool) []*Commit {
|
||||
func commitFilter(commits []*Commit, filters map[string][]string, noCaseSensitive bool) []*Commit { //nolint:gocyclo
|
||||
// NOTE(khos2ow): this function is over our cyclomatic complexity goal.
|
||||
// Be wary when adding branches, and look for functionality that could
|
||||
// be reasonably moved into an injected dependency.
|
||||
|
||||
res := []*Commit{}
|
||||
|
||||
for _, commit := range commits {
|
||||
|
|
|
|||
|
|
@ -18,27 +18,27 @@ func TestCommitFilter(t *testing.T) {
|
|||
}
|
||||
|
||||
fixtures := []*Commit{
|
||||
&Commit{
|
||||
{
|
||||
Type: "foo",
|
||||
Scope: "hoge",
|
||||
Subject: "1",
|
||||
},
|
||||
&Commit{
|
||||
{
|
||||
Type: "foo",
|
||||
Scope: "fuga",
|
||||
Subject: "2",
|
||||
},
|
||||
&Commit{
|
||||
{
|
||||
Type: "bar",
|
||||
Scope: "hoge",
|
||||
Subject: "3",
|
||||
},
|
||||
&Commit{
|
||||
{
|
||||
Type: "bar",
|
||||
Scope: "fuga",
|
||||
Subject: "4",
|
||||
},
|
||||
&Commit{
|
||||
{
|
||||
Type: "Bar",
|
||||
Scope: "hogera",
|
||||
Subject: "5",
|
||||
|
|
|
|||
100
commit_parser.go
100
commit_parser.go
|
|
@ -59,6 +59,8 @@ type commitParser struct {
|
|||
reIssue *regexp.Regexp
|
||||
reNotes *regexp.Regexp
|
||||
reMention *regexp.Regexp
|
||||
reSignOff *regexp.Regexp
|
||||
reCoAuthor *regexp.Regexp
|
||||
reJiraIssueDescription *regexp.Regexp
|
||||
}
|
||||
|
||||
|
|
@ -80,7 +82,9 @@ func newCommitParser(logger *Logger, client gitcmd.Client, jiraClient JiraClient
|
|||
reRef: regexp.MustCompile("(?i)(" + joinedRefActions + ")\\s?([\\w/\\.\\-]+)?(?:" + joinedIssuePrefix + ")(\\d+)"),
|
||||
reIssue: regexp.MustCompile("(?:" + joinedIssuePrefix + ")(\\d+)"),
|
||||
reNotes: regexp.MustCompile("^(?i)\\s*(" + joinedNoteKeywords + ")[:\\s]+(.*)"),
|
||||
reMention: regexp.MustCompile("@([\\w-]+)"),
|
||||
reMention: regexp.MustCompile(`@([\w-]+)`),
|
||||
reSignOff: regexp.MustCompile(`Signed-off-by:\s+([\p{L}\s\-\[\]]+)\s+<([\w+\-\[\].@]+)>`),
|
||||
reCoAuthor: regexp.MustCompile(`Co-authored-by:\s+([\p{L}\s\-\[\]]+)\s+<([\w+\-\[\].@]+)>`),
|
||||
reJiraIssueDescription: regexp.MustCompile(opts.JiraIssueDescriptionPattern),
|
||||
}
|
||||
}
|
||||
|
|
@ -223,11 +227,41 @@ func (p *commitParser) processHeader(commit *Commit, input string) {
|
|||
commit.Mentions = p.parseMentions(input)
|
||||
|
||||
// Jira
|
||||
if commit.JiraIssueId != "" {
|
||||
p.processJiraIssue(commit, commit.JiraIssueId)
|
||||
if commit.JiraIssueID != "" {
|
||||
p.processJiraIssue(commit, commit.JiraIssueID)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *commitParser) extractLineMetadata(commit *Commit, line string) bool {
|
||||
meta := false
|
||||
|
||||
refs := p.parseRefs(line)
|
||||
if len(refs) > 0 {
|
||||
meta = true
|
||||
commit.Refs = append(commit.Refs, refs...)
|
||||
}
|
||||
|
||||
mentions := p.parseMentions(line)
|
||||
if len(mentions) > 0 {
|
||||
meta = true
|
||||
commit.Mentions = append(commit.Mentions, mentions...)
|
||||
}
|
||||
|
||||
coAuthors := p.parseCoAuthors(line)
|
||||
if len(coAuthors) > 0 {
|
||||
meta = true
|
||||
commit.CoAuthors = append(commit.CoAuthors, coAuthors...)
|
||||
}
|
||||
|
||||
signers := p.parseSigners(line)
|
||||
if len(signers) > 0 {
|
||||
meta = true
|
||||
commit.Signers = append(commit.Signers, signers...)
|
||||
}
|
||||
|
||||
return meta
|
||||
}
|
||||
|
||||
func (p *commitParser) processBody(commit *Commit, input string) {
|
||||
input = convNewline(input, "\n")
|
||||
|
||||
|
|
@ -237,30 +271,29 @@ func (p *commitParser) processBody(commit *Commit, input string) {
|
|||
// notes & refs & mentions
|
||||
commit.Notes = []*Note{}
|
||||
inNote := false
|
||||
trim := false
|
||||
fenceDetector := newMdFenceDetector()
|
||||
lines := strings.Split(input, "\n")
|
||||
|
||||
// body without notes & refs & mentions
|
||||
trimmedBody := make([]string, 0, len(lines))
|
||||
|
||||
for _, line := range lines {
|
||||
if !inNote {
|
||||
trim = false
|
||||
}
|
||||
fenceDetector.Update(line)
|
||||
|
||||
if !fenceDetector.InCodeblock() {
|
||||
refs := p.parseRefs(line)
|
||||
if len(refs) > 0 {
|
||||
inNote = false
|
||||
commit.Refs = append(commit.Refs, refs...)
|
||||
}
|
||||
|
||||
mentions := p.parseMentions(line)
|
||||
if len(mentions) > 0 {
|
||||
inNote = false
|
||||
commit.Mentions = append(commit.Mentions, mentions...)
|
||||
}
|
||||
if !fenceDetector.InCodeblock() && p.extractLineMetadata(commit, line) {
|
||||
trim = true
|
||||
inNote = false
|
||||
}
|
||||
|
||||
// Q: should this check also only be outside of code blocks?
|
||||
res := p.reNotes.FindAllStringSubmatch(line, -1)
|
||||
|
||||
if len(res) > 0 {
|
||||
inNote = true
|
||||
trim = true
|
||||
for _, r := range res {
|
||||
commit.Notes = append(commit.Notes, &Note{
|
||||
Title: r[1],
|
||||
|
|
@ -271,8 +304,13 @@ func (p *commitParser) processBody(commit *Commit, input string) {
|
|||
last := commit.Notes[len(commit.Notes)-1]
|
||||
last.Body = last.Body + "\n" + line
|
||||
}
|
||||
|
||||
if !trim {
|
||||
trimmedBody = append(trimmedBody, line)
|
||||
}
|
||||
}
|
||||
|
||||
commit.TrimmedBody = strings.TrimSpace(strings.Join(trimmedBody, "\n"))
|
||||
p.trimSpaceInNotes(commit)
|
||||
}
|
||||
|
||||
|
|
@ -317,6 +355,30 @@ func (p *commitParser) parseRefs(input string) []*Ref {
|
|||
return refs
|
||||
}
|
||||
|
||||
func (p *commitParser) parseSigners(input string) []Contact {
|
||||
res := p.reSignOff.FindAllStringSubmatch(input, -1)
|
||||
contacts := make([]Contact, len(res))
|
||||
|
||||
for i, r := range res {
|
||||
contacts[i].Name = r[1]
|
||||
contacts[i].Email = r[2]
|
||||
}
|
||||
|
||||
return contacts
|
||||
}
|
||||
|
||||
func (p *commitParser) parseCoAuthors(input string) []Contact {
|
||||
res := p.reCoAuthor.FindAllStringSubmatch(input, -1)
|
||||
contacts := make([]Contact, len(res))
|
||||
|
||||
for i, r := range res {
|
||||
contacts[i].Name = r[1]
|
||||
contacts[i].Email = r[2]
|
||||
}
|
||||
|
||||
return contacts
|
||||
}
|
||||
|
||||
func (p *commitParser) parseMentions(input string) []string {
|
||||
res := p.reMention.FindAllStringSubmatch(input, -1)
|
||||
mentions := make([]string, len(res))
|
||||
|
|
@ -364,10 +426,10 @@ func (p *commitParser) uniqMentions(mentions []string) []string {
|
|||
return arr
|
||||
}
|
||||
|
||||
func (p *commitParser) processJiraIssue(commit *Commit, issueId string) {
|
||||
issue, err := p.jiraClient.GetJiraIssue(commit.JiraIssueId)
|
||||
func (p *commitParser) processJiraIssue(commit *Commit, issueID string) {
|
||||
issue, err := p.jiraClient.GetJiraIssue(commit.JiraIssueID)
|
||||
if err != nil {
|
||||
p.logger.Error(fmt.Sprintf("Failed to parse Jira story %s: %s\n", issueId, err))
|
||||
p.logger.Error(fmt.Sprintf("Failed to parse Jira story %s: %s\n", issueID, err))
|
||||
return
|
||||
}
|
||||
commit.Type = p.config.Options.JiraTypeMaps[issue.Fields.Type.Name]
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ package chglog
|
|||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
|
@ -23,7 +22,7 @@ func TestCommitParserParse(t *testing.T) {
|
|||
return "", errors.New("")
|
||||
}
|
||||
|
||||
bytes, _ := ioutil.ReadFile(filepath.Join("testdata", "gitlog.txt"))
|
||||
bytes, _ := os.ReadFile(filepath.Join("testdata", "gitlog.txt"))
|
||||
|
||||
return string(bytes), nil
|
||||
},
|
||||
|
|
@ -33,7 +32,7 @@ func TestCommitParserParse(t *testing.T) {
|
|||
mock, nil, &Config{
|
||||
Options: &Options{
|
||||
CommitFilters: map[string][]string{
|
||||
"Type": []string{
|
||||
"Type": {
|
||||
"feat",
|
||||
"fix",
|
||||
"perf",
|
||||
|
|
@ -79,7 +78,7 @@ func TestCommitParserParse(t *testing.T) {
|
|||
commits, err := parser.Parse("HEAD")
|
||||
assert.Nil(err)
|
||||
assert.Equal([]*Commit{
|
||||
&Commit{
|
||||
{
|
||||
Hash: &Hash{
|
||||
Long: "65cf1add9735dcc4810dda3312b0792236c97c4e",
|
||||
Short: "65cf1add",
|
||||
|
|
@ -97,21 +96,22 @@ func TestCommitParserParse(t *testing.T) {
|
|||
Merge: nil,
|
||||
Revert: nil,
|
||||
Refs: []*Ref{
|
||||
&Ref{
|
||||
{
|
||||
Action: "",
|
||||
Ref: "123",
|
||||
Source: "",
|
||||
},
|
||||
},
|
||||
Notes: []*Note{},
|
||||
Mentions: []string{},
|
||||
Header: "feat(*): Add new feature #123",
|
||||
Type: "feat",
|
||||
Scope: "*",
|
||||
Subject: "Add new feature #123",
|
||||
Body: "",
|
||||
Notes: []*Note{},
|
||||
Mentions: []string{},
|
||||
Header: "feat(*): Add new feature #123",
|
||||
Type: "feat",
|
||||
Scope: "*",
|
||||
Subject: "Add new feature #123",
|
||||
Body: "",
|
||||
TrimmedBody: "",
|
||||
},
|
||||
&Commit{
|
||||
{
|
||||
Hash: &Hash{
|
||||
Long: "14ef0b6d386c5432af9292eab3c8314fa3001bc7",
|
||||
Short: "14ef0b6d",
|
||||
|
|
@ -132,24 +132,24 @@ func TestCommitParserParse(t *testing.T) {
|
|||
},
|
||||
Revert: nil,
|
||||
Refs: []*Ref{
|
||||
&Ref{
|
||||
{
|
||||
Action: "",
|
||||
Ref: "3",
|
||||
Source: "",
|
||||
},
|
||||
&Ref{
|
||||
{
|
||||
Action: "Fixes",
|
||||
Ref: "3",
|
||||
Source: "",
|
||||
},
|
||||
&Ref{
|
||||
{
|
||||
Action: "Closes",
|
||||
Ref: "1",
|
||||
Source: "",
|
||||
},
|
||||
},
|
||||
Notes: []*Note{
|
||||
&Note{
|
||||
{
|
||||
Title: "BREAKING CHANGE",
|
||||
Body: "This is breaking point message.",
|
||||
},
|
||||
|
|
@ -166,8 +166,9 @@ Fixes #3
|
|||
Closes #1
|
||||
|
||||
BREAKING CHANGE: This is breaking point message.`,
|
||||
TrimmedBody: `This is body message.`,
|
||||
},
|
||||
&Commit{
|
||||
{
|
||||
Hash: &Hash{
|
||||
Long: "809a8280ffd0dadb0f4e7ba9fc835e63c37d6af6",
|
||||
Short: "809a8280",
|
||||
|
|
@ -200,8 +201,9 @@ BREAKING CHANGE: This is breaking point message.`,
|
|||
@tsuyoshiwada
|
||||
@hogefuga
|
||||
@FooBarBaz`,
|
||||
TrimmedBody: `Has mention body`,
|
||||
},
|
||||
&Commit{
|
||||
{
|
||||
Hash: &Hash{
|
||||
Long: "74824d6bd1470b901ec7123d13a76a1b8938d8d0",
|
||||
Short: "74824d6b",
|
||||
|
|
@ -219,19 +221,19 @@ BREAKING CHANGE: This is breaking point message.`,
|
|||
Merge: nil,
|
||||
Revert: nil,
|
||||
Refs: []*Ref{
|
||||
&Ref{
|
||||
{
|
||||
Action: "Fixes",
|
||||
Ref: "123",
|
||||
Source: "",
|
||||
},
|
||||
&Ref{
|
||||
{
|
||||
Action: "Closes",
|
||||
Ref: "456",
|
||||
Source: "username/repository",
|
||||
},
|
||||
},
|
||||
Notes: []*Note{
|
||||
&Note{
|
||||
{
|
||||
Title: "BREAKING CHANGE",
|
||||
Body: fmt.Sprintf(`This is multiline breaking change note.
|
||||
It is treated as the body of the Note until a mention or reference appears.
|
||||
|
|
@ -280,8 +282,9 @@ class MyController extends Controller {
|
|||
|
||||
Fixes #123
|
||||
Closes username/repository#456`, "```", "```"),
|
||||
TrimmedBody: `This mixed body message.`,
|
||||
},
|
||||
&Commit{
|
||||
{
|
||||
Hash: &Hash{
|
||||
Long: "123456789735dcc4810dda3312b0792236c97c4e",
|
||||
Short: "12345678",
|
||||
|
|
@ -300,14 +303,15 @@ Closes username/repository#456`, "```", "```"),
|
|||
Revert: &Revert{
|
||||
Header: "fix(core): commit message",
|
||||
},
|
||||
Refs: []*Ref{},
|
||||
Notes: []*Note{},
|
||||
Mentions: []string{},
|
||||
Header: "Revert \"fix(core): commit message\"",
|
||||
Type: "",
|
||||
Scope: "",
|
||||
Subject: "",
|
||||
Body: "This reverts commit f755db78dcdf461dc42e709b3ab728ceba353d1d.",
|
||||
Refs: []*Ref{},
|
||||
Notes: []*Note{},
|
||||
Mentions: []string{},
|
||||
Header: "Revert \"fix(core): commit message\"",
|
||||
Type: "",
|
||||
Scope: "",
|
||||
Subject: "",
|
||||
Body: "This reverts commit f755db78dcdf461dc42e709b3ab728ceba353d1d.",
|
||||
TrimmedBody: "This reverts commit f755db78dcdf461dc42e709b3ab728ceba353d1d.",
|
||||
},
|
||||
}, commits)
|
||||
}
|
||||
|
|
@ -371,7 +375,7 @@ func TestCommitParserParseWithJira(t *testing.T) {
|
|||
return "", errors.New("")
|
||||
}
|
||||
|
||||
bytes, _ := ioutil.ReadFile(filepath.Join("testdata", "gitlog_jira.txt"))
|
||||
bytes, _ := os.ReadFile(filepath.Join("testdata", "gitlog_jira.txt"))
|
||||
|
||||
return string(bytes), nil
|
||||
},
|
||||
|
|
@ -381,7 +385,7 @@ func TestCommitParserParseWithJira(t *testing.T) {
|
|||
mock, mockJiraClient{}, &Config{
|
||||
Options: &Options{
|
||||
CommitFilters: map[string][]string{
|
||||
"Type": []string{
|
||||
"Type": {
|
||||
"feat",
|
||||
"fix",
|
||||
"perf",
|
||||
|
|
@ -391,7 +395,7 @@ func TestCommitParserParseWithJira(t *testing.T) {
|
|||
HeaderPattern: "^(?:(\\w*)|(?:\\[(.*)\\])?)\\:\\s(.*)$",
|
||||
HeaderPatternMaps: []string{
|
||||
"Type",
|
||||
"JiraIssueId",
|
||||
"JiraIssueID",
|
||||
"Subject",
|
||||
},
|
||||
JiraTypeMaps: map[string]string{
|
||||
|
|
@ -403,7 +407,7 @@ func TestCommitParserParseWithJira(t *testing.T) {
|
|||
commits, err := parser.Parse("HEAD")
|
||||
assert.Nil(err)
|
||||
commit := commits[0]
|
||||
assert.Equal(commit.JiraIssueId, "JIRA-1111")
|
||||
assert.Equal(commit.JiraIssueID, "JIRA-1111")
|
||||
assert.Equal(commit.JiraIssue.Type, "Story")
|
||||
assert.Equal(commit.JiraIssue.Summary, "summary of JIRA-1111")
|
||||
assert.Equal(commit.JiraIssue.Description, "description of JIRA-1111")
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ func Example() {
|
|||
},
|
||||
Options: &Options{
|
||||
CommitFilters: map[string][]string{
|
||||
"Type": []string{
|
||||
"Type": {
|
||||
"feat",
|
||||
"fix",
|
||||
},
|
||||
|
|
|
|||
23
fields.go
23
fields.go
|
|
@ -8,6 +8,12 @@ type Hash struct {
|
|||
Short string
|
||||
}
|
||||
|
||||
// Contact of co-authors and signers
|
||||
type Contact struct {
|
||||
Name string
|
||||
Email string
|
||||
}
|
||||
|
||||
// Author of commit
|
||||
type Author struct {
|
||||
Name string
|
||||
|
|
@ -52,7 +58,7 @@ type NoteGroup struct {
|
|||
Notes []*Note
|
||||
}
|
||||
|
||||
// JiraIssue
|
||||
// JiraIssue is information about a jira ticket (type, summary, description, and labels)
|
||||
type JiraIssue struct {
|
||||
Type string
|
||||
Summary string
|
||||
|
|
@ -69,14 +75,17 @@ type Commit struct {
|
|||
Revert *Revert // If it is not a revert commit, `nil` is assigned
|
||||
Refs []*Ref
|
||||
Notes []*Note
|
||||
Mentions []string // Name of the user included in the commit header or body
|
||||
Mentions []string // Name of the user included in the commit header or body
|
||||
CoAuthors []Contact // (e.g. `Co-authored-by: user <user@email>`)
|
||||
Signers []Contact // (e.g. `Signed-off-by: user <user@email>`)
|
||||
JiraIssue *JiraIssue // If no issue id found in header, `nil` is assigned
|
||||
Header string // (e.g. `feat(core)[RNWY-310]: Add new feature`)
|
||||
Type string // (e.g. `feat`)
|
||||
Scope string // (e.g. `core`)
|
||||
Subject string // (e.g. `Add new feature`)
|
||||
JiraIssueId string // (e.g. `RNWY-310`)
|
||||
Header string // (e.g. `feat(core)[RNWY-310]: Add new feature`)
|
||||
Type string // (e.g. `feat`)
|
||||
Scope string // (e.g. `core`)
|
||||
Subject string // (e.g. `Add new feature`)
|
||||
JiraIssueID string // (e.g. `RNWY-310`)
|
||||
Body string
|
||||
TrimmedBody string // Body without any Notes/Refs/Mentions/CoAuthors/Signers
|
||||
}
|
||||
|
||||
// CommitGroup is a collection of commits grouped according to the `CommitGroupBy` option
|
||||
|
|
|
|||
52
go.mod
52
go.mod
|
|
@ -1,16 +1,48 @@
|
|||
module github.com/git-chglog/git-chglog
|
||||
|
||||
go 1.15
|
||||
go 1.24.1
|
||||
|
||||
require (
|
||||
github.com/AlecAivazis/survey/v2 v2.2.9
|
||||
github.com/andygrunwald/go-jira v1.13.0
|
||||
github.com/fatih/color v1.10.0
|
||||
github.com/imdario/mergo v0.3.12
|
||||
github.com/kyokomi/emoji/v2 v2.2.8
|
||||
github.com/mattn/go-colorable v0.1.8
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/AlecAivazis/survey/v2 v2.3.7
|
||||
github.com/Masterminds/sprig/v3 v3.3.0
|
||||
github.com/andygrunwald/go-jira v1.16.0
|
||||
github.com/coreos/go-semver v0.3.1
|
||||
github.com/fatih/color v1.18.0
|
||||
github.com/imdario/mergo v0.3.16
|
||||
github.com/kyokomi/emoji/v2 v2.2.13
|
||||
github.com/mattn/go-colorable v0.1.14
|
||||
github.com/stretchr/testify v1.10.0
|
||||
github.com/tsuyoshiwada/go-gitcmd v0.0.0-20180205145712-5f1f5f9475df
|
||||
github.com/urfave/cli/v2 v2.3.0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
github.com/urfave/cli/v2 v2.27.6
|
||||
gopkg.in/yaml.v2 v2.3.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
||||
require (
|
||||
dario.cat/mergo v1.0.1 // indirect
|
||||
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||
github.com/Masterminds/semver/v3 v3.3.0 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/fatih/structs v1.1.0 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.4.2 // indirect
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/huandu/xstrings v1.5.0 // indirect
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
|
||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/shopspring/decimal v1.4.0 // indirect
|
||||
github.com/spf13/cast v1.7.0 // indirect
|
||||
github.com/trivago/tgo v1.0.7 // indirect
|
||||
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
|
||||
golang.org/x/crypto v0.26.0 // indirect
|
||||
golang.org/x/sys v0.29.0 // indirect
|
||||
golang.org/x/term v0.23.0 // indirect
|
||||
golang.org/x/text v0.17.0 // indirect
|
||||
)
|
||||
|
|
|
|||
167
go.sum
167
go.sum
|
|
@ -1,80 +1,135 @@
|
|||
github.com/AlecAivazis/survey/v2 v2.2.9 h1:LWvJtUswz/W9/zVVXELrmlvdwWcKE60ZAw0FWV9vssk=
|
||||
github.com/AlecAivazis/survey/v2 v2.2.9/go.mod h1:9DYvHgXtiXm6nCn+jXnOXLKbH+Yo9u8fAS/SduGdoPk=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8 h1:xzYJEypr/85nBpB11F9br+3HUrpgb+fcm5iADzXXYEw=
|
||||
github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc=
|
||||
github.com/andygrunwald/go-jira v1.13.0 h1:vvIImGgX32bHfoiyUwkNo+/YrPnRczNarvhLOncP6dE=
|
||||
github.com/andygrunwald/go-jira v1.13.0/go.mod h1:jYi4kFDbRPZTJdJOVJO4mpMMIwdB+rcZwSO58DzPd2I=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
|
||||
dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
||||
github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ=
|
||||
github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo=
|
||||
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
|
||||
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
|
||||
github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0=
|
||||
github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
|
||||
github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs=
|
||||
github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0=
|
||||
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s=
|
||||
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w=
|
||||
github.com/andygrunwald/go-jira v1.16.0 h1:PU7C7Fkk5L96JvPc6vDVIrd99vdPnYudHu4ju2c2ikQ=
|
||||
github.com/andygrunwald/go-jira v1.16.0/go.mod h1:UQH4IBVxIYWbgagc0LF/k9FRs9xjIiQ8hIcC6HfLwFU=
|
||||
github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4=
|
||||
github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.17 h1:QeVUsEDNrLBW4tMgZHvxy18sKtr6VI492kBhUfhDJNI=
|
||||
github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg=
|
||||
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
|
||||
github.com/fatih/structs v1.0.0 h1:BrX964Rv5uQ3wwS+KRUAJCBBw5PQmgJfJ6v4yly5QwU=
|
||||
github.com/fatih/structs v1.0.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
||||
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135 h1:zLTLjkaOFEFIOxY5BWLFLwh+cL8vOBW4XJ2aqLE/Tf0=
|
||||
github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174 h1:WlZsjVhE8Af9IcZDGgJGQpNflI3+MJSBhsgT5PCtzBQ=
|
||||
github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A=
|
||||
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
|
||||
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
|
||||
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
|
||||
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
|
||||
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
||||
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||
github.com/golang-jwt/jwt/v4 v4.4.2 h1:rcc4lwaZgFMCZ5jxF9ABolDcIHdBytAFgqFPbSJQAYs=
|
||||
github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
||||
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog=
|
||||
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68=
|
||||
github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI=
|
||||
github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||
github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
|
||||
github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||
github.com/kr/pty v1.1.4 h1:5Myjjh3JY/NaAi4IsUbHADytDyl1VE1Y9PXDlL+P/VQ=
|
||||
github.com/kr/pty v1.1.4/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kyokomi/emoji/v2 v2.2.8 h1:jcofPxjHWEkJtkIbcLHvZhxKgCPl6C7MyjTrD4KDqUE=
|
||||
github.com/kyokomi/emoji/v2 v2.2.8/go.mod h1:JUcn42DTdsXJo1SWanHh4HKDEyPaR5CqkmoirZZP9qE=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kyokomi/emoji/v2 v2.2.13 h1:GhTfQa67venUUvmleTNFnb+bi7S3aocF7ZCXU9fSO7U=
|
||||
github.com/kyokomi/emoji/v2 v2.2.13/go.mod h1:JUcn42DTdsXJo1SWanHh4HKDEyPaR5CqkmoirZZP9qE=
|
||||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
|
||||
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
|
||||
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
||||
github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
|
||||
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
|
||||
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
|
||||
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
|
||||
github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
|
||||
github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w=
|
||||
github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/trivago/tgo v1.0.1 h1:bxatjJIXNIpV18bucU4Uk/LaoxvxuOlp/oowRHyncLQ=
|
||||
github.com/trivago/tgo v1.0.1/go.mod h1:w4dpD+3tzNIIiIfkWWa85w5/B77tlvdZckQ+6PkFnhc=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/trivago/tgo v1.0.7 h1:uaWH/XIy9aWYWpjm2CU3RpcqZXmX2ysQ9/Go+d9gyrM=
|
||||
github.com/trivago/tgo v1.0.7/go.mod h1:w4dpD+3tzNIIiIfkWWa85w5/B77tlvdZckQ+6PkFnhc=
|
||||
github.com/tsuyoshiwada/go-gitcmd v0.0.0-20180205145712-5f1f5f9475df h1:Y2l28Jr3vOEeYtxfVbMtVfOdAwuUqWaP9fvNKiBVeXY=
|
||||
github.com/tsuyoshiwada/go-gitcmd v0.0.0-20180205145712-5f1f5f9475df/go.mod h1:pnyouUty/nBr/zm3GYwTIt+qFTLWbdjeLjZmJdzJOu8=
|
||||
github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M=
|
||||
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
||||
github.com/urfave/cli/v2 v2.27.6 h1:VdRdS98FNhKZ8/Az8B7MTyGQmpIr36O1EHybx/LaZ4g=
|
||||
github.com/urfave/cli/v2 v2.27.6/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ=
|
||||
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
|
||||
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5 h1:8dUaAV7K4uHsF56JQWkprecIQKdPHtR9jCHF5nB8uzc=
|
||||
golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
|
||||
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190530182044-ad28b68e88f1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae h1:/WDfKMnPU+m5M4xB+6x4kaepxRw6jWvR5iDRdvjHgy8=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
|
||||
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU=
|
||||
golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
|
||||
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
|
|
|||
6
jira.go
6
jira.go
|
|
@ -4,6 +4,7 @@ import (
|
|||
agjira "github.com/andygrunwald/go-jira"
|
||||
)
|
||||
|
||||
// JiraClient is an HTTP client for Jira
|
||||
type JiraClient interface {
|
||||
GetJiraIssue(id string) (*agjira.Issue, error)
|
||||
}
|
||||
|
|
@ -14,11 +15,12 @@ type jiraClient struct {
|
|||
url string
|
||||
}
|
||||
|
||||
// NewJiraClient returns an instance of JiraClient
|
||||
func NewJiraClient(config *Config) JiraClient {
|
||||
return jiraClient{
|
||||
username: config.Options.JiraUsername,
|
||||
token: config.Options.JiraToken,
|
||||
url: config.Options.JiraUrl,
|
||||
token: config.Options.JiraToken,
|
||||
url: config.Options.JiraURL,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,15 @@
|
|||
package chglog
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestJira(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
config := &Config {
|
||||
config := &Config{
|
||||
Options: &Options{
|
||||
Processor: nil,
|
||||
NextTag: "",
|
||||
|
|
@ -29,7 +30,7 @@ func TestJira(t *testing.T) {
|
|||
NoteKeywords: nil,
|
||||
JiraUsername: "uuu",
|
||||
JiraToken: "ppp",
|
||||
JiraUrl: "http://jira.com",
|
||||
JiraURL: "http://jira.com",
|
||||
JiraTypeMaps: nil,
|
||||
JiraIssueDescriptionPattern: "",
|
||||
},
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import (
|
|||
"regexp"
|
||||
|
||||
"github.com/fatih/color"
|
||||
emoji "github.com/kyokomi/emoji/v2"
|
||||
"github.com/kyokomi/emoji/v2"
|
||||
)
|
||||
|
||||
// Logger ...
|
||||
|
|
@ -26,7 +26,7 @@ func NewLogger(stdout, stderr io.Writer, silent, noEmoji bool) *Logger {
|
|||
stderr: stderr,
|
||||
silent: silent,
|
||||
noEmoji: noEmoji,
|
||||
reEmoji: regexp.MustCompile(":[\\w\\+_\\-]+:\\s?"),
|
||||
reEmoji: regexp.MustCompile(`:[\w\+_\-]+:\s?`),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/stretchr/testify/assert"
|
||||
emoji "github.com/kyokomi/emoji/v2"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestLoggerLogSilent(t *testing.T) {
|
||||
|
|
@ -40,7 +40,7 @@ func TestLoggerLogNoEmoji(t *testing.T) {
|
|||
stderr := &bytes.Buffer{}
|
||||
logger := NewLogger(stdout, stderr, false, true)
|
||||
logger.Log(":+1:Hello, World! :)")
|
||||
assert.Equal(fmt.Sprint("Hello, World! :)\n"), stdout.String())
|
||||
assert.Equal(fmt.Sprint("Hello, World! :)\n"), stdout.String()) //nolint:gosimple
|
||||
}
|
||||
|
||||
func TestLoggerError(t *testing.T) {
|
||||
|
|
|
|||
38
processor.go
38
processor.go
|
|
@ -14,8 +14,8 @@ type Processor interface {
|
|||
// GitHubProcessor is optimized for CHANGELOG used in GitHub
|
||||
//
|
||||
// The following processing is performed
|
||||
// - Mentions automatic link (@tsuyoshiwada -> [@tsuyoshiwada](https://github.com/tsuyoshiwada))
|
||||
// - Automatic link to references (#123 -> [#123](https://github.com/owner/repo/issues/123))
|
||||
// - Mentions automatic link (@tsuyoshiwada -> [@tsuyoshiwada](https://github.com/tsuyoshiwada))
|
||||
// - Automatic link to references (#123 -> [#123](https://github.com/owner/repo/issues/123))
|
||||
type GitHubProcessor struct {
|
||||
Host string // Host name used for link destination. Note: You must include the protocol (e.g. "https://github.com")
|
||||
config *Config
|
||||
|
|
@ -33,8 +33,8 @@ func (p *GitHubProcessor) Bootstrap(config *Config) {
|
|||
p.Host = strings.TrimRight(p.Host, "/")
|
||||
}
|
||||
|
||||
p.reMention = regexp.MustCompile("@(\\w+)")
|
||||
p.reIssue = regexp.MustCompile("(?i)(#|gh-)(\\d+)")
|
||||
p.reMention = regexp.MustCompile(`@(\w+)`)
|
||||
p.reIssue = regexp.MustCompile(`(?i)(#|gh-)(\d+)`)
|
||||
}
|
||||
|
||||
// ProcessCommit ...
|
||||
|
|
@ -69,13 +69,15 @@ func (p *GitHubProcessor) addLinks(input string) string {
|
|||
// GitLabProcessor is optimized for CHANGELOG used in GitLab
|
||||
//
|
||||
// The following processing is performed
|
||||
// - Mentions automatic link (@tsuyoshiwada -> [@tsuyoshiwada](https://gitlab.com/tsuyoshiwada))
|
||||
// - Automatic link to references (#123 -> [#123](https://gitlab.com/owner/repo/issues/123))
|
||||
// - Mentions automatic link (@tsuyoshiwada -> [@tsuyoshiwada](https://gitlab.com/tsuyoshiwada))
|
||||
// - Automatic link to references issues (#123 -> [#123](https://gitlab.com/owner/repo/issues/123))
|
||||
// - Automatic link to references merge request (!123 -> [#123](https://gitlab.com/owner/repo/merge_requests/123))
|
||||
type GitLabProcessor struct {
|
||||
Host string // Host name used for link destination. Note: You must include the protocol (e.g. "https://gitlab.com")
|
||||
config *Config
|
||||
reMention *regexp.Regexp
|
||||
reIssue *regexp.Regexp
|
||||
Host string // Host name used for link destination. Note: You must include the protocol (e.g. "https://gitlab.com")
|
||||
config *Config
|
||||
reMention *regexp.Regexp
|
||||
reIssue *regexp.Regexp
|
||||
reMergeRequest *regexp.Regexp
|
||||
}
|
||||
|
||||
// Bootstrap ...
|
||||
|
|
@ -88,8 +90,9 @@ func (p *GitLabProcessor) Bootstrap(config *Config) {
|
|||
p.Host = strings.TrimRight(p.Host, "/")
|
||||
}
|
||||
|
||||
p.reMention = regexp.MustCompile("@(\\w+)")
|
||||
p.reIssue = regexp.MustCompile("(?i)#(\\d+)")
|
||||
p.reMention = regexp.MustCompile(`@(\w+)`)
|
||||
p.reIssue = regexp.MustCompile(`(?i)#(\d+)`)
|
||||
p.reMergeRequest = regexp.MustCompile(`(?i)!(\d+)`)
|
||||
}
|
||||
|
||||
// ProcessCommit ...
|
||||
|
|
@ -118,14 +121,17 @@ func (p *GitLabProcessor) addLinks(input string) string {
|
|||
// issues
|
||||
input = p.reIssue.ReplaceAllString(input, "[#$1]("+repoURL+"/issues/$1)")
|
||||
|
||||
// merge requests
|
||||
input = p.reMergeRequest.ReplaceAllString(input, "[!$1]("+repoURL+"/merge_requests/$1)")
|
||||
|
||||
return input
|
||||
}
|
||||
|
||||
// BitbucketProcessor is optimized for CHANGELOG used in Bitbucket
|
||||
//
|
||||
// The following processing is performed
|
||||
// - Mentions automatic link (@tsuyoshiwada -> [@tsuyoshiwada](https://bitbucket.org/tsuyoshiwada/))
|
||||
// - Automatic link to references (#123 -> [#123](https://bitbucket.org/owner/repo/issues/123/))
|
||||
// - Mentions automatic link (@tsuyoshiwada -> [@tsuyoshiwada](https://bitbucket.org/tsuyoshiwada/))
|
||||
// - Automatic link to references (#123 -> [#123](https://bitbucket.org/owner/repo/issues/123/))
|
||||
type BitbucketProcessor struct {
|
||||
Host string // Host name used for link destination. Note: You must include the protocol (e.g. "https://bitbucket.org")
|
||||
config *Config
|
||||
|
|
@ -143,8 +149,8 @@ func (p *BitbucketProcessor) Bootstrap(config *Config) {
|
|||
p.Host = strings.TrimRight(p.Host, "/")
|
||||
}
|
||||
|
||||
p.reMention = regexp.MustCompile("@(\\w+)")
|
||||
p.reIssue = regexp.MustCompile("(?i)#(\\d+)")
|
||||
p.reMention = regexp.MustCompile(`@(\w+)`)
|
||||
p.reIssue = regexp.MustCompile(`(?i)#(\d+)`)
|
||||
}
|
||||
|
||||
// ProcessCommit ...
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ func TestGitHubProcessor(t *testing.T) {
|
|||
multiline [#789](https://example.com/issues/789)
|
||||
[@foo](https://github.com/foo), [@bar](https://github.com/bar)`,
|
||||
Notes: []*Note{
|
||||
&Note{
|
||||
{
|
||||
Body: `issue1 [#11](https://example.com/issues/11)
|
||||
issue2 [#22](https://example.com/issues/22)
|
||||
[gh-56](https://example.com/issues/56) hoge fuga`,
|
||||
|
|
@ -42,7 +42,7 @@ issue2 [#22](https://example.com/issues/22)
|
|||
multiline #789
|
||||
@foo, @bar`,
|
||||
Notes: []*Note{
|
||||
&Note{
|
||||
{
|
||||
Body: `issue1 #11
|
||||
issue2 #22
|
||||
gh-56 hoge fuga`,
|
||||
|
|
@ -83,30 +83,34 @@ func TestGitLabProcessor(t *testing.T) {
|
|||
|
||||
assert.Equal(
|
||||
&Commit{
|
||||
Header: "message [@foo](https://gitlab.com/foo) [#123](https://example.com/issues/123)",
|
||||
Subject: "message [@foo](https://gitlab.com/foo) [#123](https://example.com/issues/123)",
|
||||
Header: "message [@foo](https://gitlab.com/foo) [#123](https://example.com/issues/123) [!345](https://example.com/merge_requests/345)",
|
||||
Subject: "message [@foo](https://gitlab.com/foo) [#123](https://example.com/issues/123) [!345](https://example.com/merge_requests/345)",
|
||||
Body: `issue [#456](https://example.com/issues/456)
|
||||
multiline [#789](https://example.com/issues/789)
|
||||
merge request [!345](https://example.com/merge_requests/345)
|
||||
[@foo](https://gitlab.com/foo), [@bar](https://gitlab.com/bar)`,
|
||||
Notes: []*Note{
|
||||
&Note{
|
||||
Body: `issue1 [#11](https://example.com/issues/11)
|
||||
{
|
||||
Body: `issue1 [#11](https://example.com/issues/11) [!33](https://example.com/merge_requests/33)
|
||||
issue2 [#22](https://example.com/issues/22)
|
||||
merge request [!33](https://example.com/merge_requests/33)
|
||||
gh-56 hoge fuga`,
|
||||
},
|
||||
},
|
||||
},
|
||||
processor.ProcessCommit(
|
||||
&Commit{
|
||||
Header: "message @foo #123",
|
||||
Subject: "message @foo #123",
|
||||
Header: "message @foo #123 !345",
|
||||
Subject: "message @foo #123 !345",
|
||||
Body: `issue #456
|
||||
multiline #789
|
||||
merge request !345
|
||||
@foo, @bar`,
|
||||
Notes: []*Note{
|
||||
&Note{
|
||||
Body: `issue1 #11
|
||||
{
|
||||
Body: `issue1 #11 !33
|
||||
issue2 #22
|
||||
merge request !33
|
||||
gh-56 hoge fuga`,
|
||||
},
|
||||
},
|
||||
|
|
@ -117,13 +121,13 @@ gh-56 hoge fuga`,
|
|||
assert.Equal(
|
||||
&Commit{
|
||||
Revert: &Revert{
|
||||
Header: "revert header [@mention](https://gitlab.com/mention) [#123](https://example.com/issues/123)",
|
||||
Header: "revert header [@mention](https://gitlab.com/mention) [#123](https://example.com/issues/123) [!345](https://example.com/merge_requests/345)",
|
||||
},
|
||||
},
|
||||
processor.ProcessCommit(
|
||||
&Commit{
|
||||
Revert: &Revert{
|
||||
Header: "revert header @mention #123",
|
||||
Header: "revert header @mention #123 !345",
|
||||
},
|
||||
},
|
||||
),
|
||||
|
|
@ -151,7 +155,7 @@ func TestBitbucketProcessor(t *testing.T) {
|
|||
multiline [#789](https://example.com/issues/789/)
|
||||
[@foo](https://bitbucket.org/foo/), [@bar](https://bitbucket.org/bar/)`,
|
||||
Notes: []*Note{
|
||||
&Note{
|
||||
{
|
||||
Body: `issue1 [#11](https://example.com/issues/11/)
|
||||
issue2 [#22](https://example.com/issues/22/)
|
||||
gh-56 hoge fuga`,
|
||||
|
|
@ -166,7 +170,7 @@ gh-56 hoge fuga`,
|
|||
multiline #789
|
||||
@foo, @bar`,
|
||||
Notes: []*Note{
|
||||
&Note{
|
||||
{
|
||||
Body: `issue1 #11
|
||||
issue2 #22
|
||||
gh-56 hoge fuga`,
|
||||
|
|
|
|||
|
|
@ -7,21 +7,23 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/coreos/go-semver/semver"
|
||||
gitcmd "github.com/tsuyoshiwada/go-gitcmd"
|
||||
)
|
||||
|
||||
type tagReader struct {
|
||||
client gitcmd.Client
|
||||
format string
|
||||
separator string
|
||||
reFilter *regexp.Regexp
|
||||
sortBy string
|
||||
}
|
||||
|
||||
func newTagReader(client gitcmd.Client, filterPattern string) *tagReader {
|
||||
func newTagReader(client gitcmd.Client, filterPattern string, sort string) *tagReader {
|
||||
return &tagReader{
|
||||
client: client,
|
||||
separator: "@@__CHGLOG__@@",
|
||||
reFilter: regexp.MustCompile(filterPattern),
|
||||
sortBy: sort,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -36,7 +38,7 @@ func (r *tagReader) ReadAll() ([]*Tag, error) {
|
|||
tags := []*Tag{}
|
||||
|
||||
if err != nil {
|
||||
return tags, fmt.Errorf("failed to get git-tag: %s", err.Error())
|
||||
return tags, fmt.Errorf("failed to get git-tag: %w", err)
|
||||
}
|
||||
|
||||
lines := strings.Split(out, "\n")
|
||||
|
|
@ -72,12 +74,33 @@ func (r *tagReader) ReadAll() ([]*Tag, error) {
|
|||
})
|
||||
}
|
||||
|
||||
r.sortTags(tags)
|
||||
switch r.sortBy {
|
||||
case "date":
|
||||
r.sortTags(tags)
|
||||
case "semver":
|
||||
r.filterSemVerTags(&tags)
|
||||
r.sortTagsBySemver(tags)
|
||||
}
|
||||
r.assignPreviousAndNextTag(tags)
|
||||
|
||||
return tags, nil
|
||||
}
|
||||
|
||||
func (*tagReader) filterSemVerTags(tags *[]*Tag) {
|
||||
// filter out any non-semver tags
|
||||
for i, t := range *tags {
|
||||
// remove leading v, since its so
|
||||
// common.
|
||||
name := strings.TrimPrefix(t.Name, "v")
|
||||
|
||||
// attempt semver parse, if not successful
|
||||
// remove it from tags slice.
|
||||
if _, err := semver.NewVersion(name); err != nil {
|
||||
*tags = append((*tags)[:i], (*tags)[i+1:]...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (*tagReader) parseRefname(input string) string {
|
||||
return strings.Replace(input, "refs/tags/", "", 1)
|
||||
}
|
||||
|
|
@ -125,3 +148,13 @@ func (*tagReader) sortTags(tags []*Tag) {
|
|||
return !tags[i].Date.Before(tags[j].Date)
|
||||
})
|
||||
}
|
||||
|
||||
func (*tagReader) sortTagsBySemver(tags []*Tag) {
|
||||
sort.Slice(tags, func(i, j int) bool {
|
||||
semver1 := strings.TrimPrefix(tags[i].Name, "v")
|
||||
semver2 := strings.TrimPrefix(tags[j].Name, "v")
|
||||
v1 := semver.New(semver1)
|
||||
v2 := semver.New(semver2)
|
||||
return v2.LessThan(*v1)
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ func TestTagReader(t *testing.T) {
|
|||
"refs/tags/v2.0.4-beta.1@@__CHGLOG__@@Release v2.0.4-beta.1@@__CHGLOG__@@Thu Feb 1 00:00:00 2018 +0000@@__CHGLOG__@@",
|
||||
"refs/tags/4.4.3@@__CHGLOG__@@This is tag subject@@__CHGLOG__@@@@__CHGLOG__@@Fri Feb 2 00:00:00 2018 +0000",
|
||||
"refs/tags/4.4.4@@__CHGLOG__@@Release 4.4.4@@__CHGLOG__@@Fri Feb 2 10:00:40 2018 +0000@@__CHGLOG__@@",
|
||||
"refs/tags/v2.0.4-beta.2@@__CHGLOG__@@Release v2.0.4-beta.2@@__CHGLOG__@@Sat Feb 3 12:15:00 2018 +0000@@__CHGLOG__@@",
|
||||
"refs/tags/5.0.0-rc.0@@__CHGLOG__@@Release 5.0.0-rc.0@@__CHGLOG__@@Sat Feb 3 12:30:10 2018 +0000@@__CHGLOG__@@",
|
||||
"refs/tags/hoge_fuga@@__CHGLOG__@@Invalid semver tag name@@__CHGLOG__@@Mon Mar 12 12:30:10 2018 +0000@@__CHGLOG__@@",
|
||||
"hoge@@__CHGLOG__@@",
|
||||
|
|
@ -28,12 +29,12 @@ func TestTagReader(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
actual, err := newTagReader(client, "").ReadAll()
|
||||
actual, err := newTagReader(client, "", "date").ReadAll()
|
||||
assert.Nil(err)
|
||||
|
||||
assert.Equal(
|
||||
[]*Tag{
|
||||
&Tag{
|
||||
{
|
||||
Name: "hoge_fuga",
|
||||
Subject: "Invalid semver tag name",
|
||||
Date: time.Date(2018, 3, 12, 12, 30, 10, 0, time.UTC),
|
||||
|
|
@ -44,7 +45,7 @@ func TestTagReader(t *testing.T) {
|
|||
Date: time.Date(2018, 2, 3, 12, 30, 10, 0, time.UTC),
|
||||
},
|
||||
},
|
||||
&Tag{
|
||||
{
|
||||
Name: "5.0.0-rc.0",
|
||||
Subject: "Release 5.0.0-rc.0",
|
||||
Date: time.Date(2018, 2, 3, 12, 30, 10, 0, time.UTC),
|
||||
|
|
@ -53,20 +54,35 @@ func TestTagReader(t *testing.T) {
|
|||
Subject: "Invalid semver tag name",
|
||||
Date: time.Date(2018, 3, 12, 12, 30, 10, 0, time.UTC),
|
||||
},
|
||||
Previous: &RelateTag{
|
||||
Name: "v2.0.4-beta.2",
|
||||
Subject: "Release v2.0.4-beta.2",
|
||||
Date: time.Date(2018, 2, 3, 12, 15, 0, 0, time.UTC),
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "v2.0.4-beta.2",
|
||||
Subject: "Release v2.0.4-beta.2",
|
||||
Date: time.Date(2018, 2, 3, 12, 15, 0, 0, time.UTC),
|
||||
Next: &RelateTag{
|
||||
Name: "5.0.0-rc.0",
|
||||
Subject: "Release 5.0.0-rc.0",
|
||||
Date: time.Date(2018, 2, 3, 12, 30, 10, 0, time.UTC),
|
||||
},
|
||||
Previous: &RelateTag{
|
||||
Name: "4.4.4",
|
||||
Subject: "Release 4.4.4",
|
||||
Date: time.Date(2018, 2, 2, 10, 0, 40, 0, time.UTC),
|
||||
},
|
||||
},
|
||||
&Tag{
|
||||
{
|
||||
Name: "4.4.4",
|
||||
Subject: "Release 4.4.4",
|
||||
Date: time.Date(2018, 2, 2, 10, 0, 40, 0, time.UTC),
|
||||
Next: &RelateTag{
|
||||
Name: "5.0.0-rc.0",
|
||||
Subject: "Release 5.0.0-rc.0",
|
||||
Date: time.Date(2018, 2, 3, 12, 30, 10, 0, time.UTC),
|
||||
Name: "v2.0.4-beta.2",
|
||||
Subject: "Release v2.0.4-beta.2",
|
||||
Date: time.Date(2018, 2, 3, 12, 15, 0, 0, time.UTC),
|
||||
},
|
||||
Previous: &RelateTag{
|
||||
Name: "4.4.3",
|
||||
|
|
@ -74,7 +90,7 @@ func TestTagReader(t *testing.T) {
|
|||
Date: time.Date(2018, 2, 2, 0, 0, 0, 0, time.UTC),
|
||||
},
|
||||
},
|
||||
&Tag{
|
||||
{
|
||||
Name: "4.4.3",
|
||||
Subject: "This is tag subject",
|
||||
Date: time.Date(2018, 2, 2, 0, 0, 0, 0, time.UTC),
|
||||
|
|
@ -89,7 +105,7 @@ func TestTagReader(t *testing.T) {
|
|||
Date: time.Date(2018, 2, 1, 0, 0, 0, 0, time.UTC),
|
||||
},
|
||||
},
|
||||
&Tag{
|
||||
{
|
||||
Name: "v2.0.4-beta.1",
|
||||
Subject: "Release v2.0.4-beta.1",
|
||||
Date: time.Date(2018, 2, 1, 0, 0, 0, 0, time.UTC),
|
||||
|
|
@ -104,18 +120,109 @@ func TestTagReader(t *testing.T) {
|
|||
actual,
|
||||
)
|
||||
|
||||
actual_filtered, err_filtered := newTagReader(client, "^v").ReadAll()
|
||||
assert.Nil(err_filtered)
|
||||
actual, err = newTagReader(client, "", "semver").ReadAll()
|
||||
assert.Nil(err)
|
||||
|
||||
assert.Equal(
|
||||
[]*Tag{
|
||||
&Tag{
|
||||
Name: "v2.0.4-beta.1",
|
||||
Subject: "Release v2.0.4-beta.1",
|
||||
Date: time.Date(2018, 2, 1, 0, 0, 0, 0, time.UTC),
|
||||
Next: nil,
|
||||
{
|
||||
Name: "5.0.0-rc.0",
|
||||
Subject: "Release 5.0.0-rc.0",
|
||||
Date: time.Date(2018, 2, 3, 12, 30, 10, 0, time.UTC),
|
||||
Next: nil,
|
||||
Previous: &RelateTag{
|
||||
Name: "4.4.4",
|
||||
Subject: "Release 4.4.4",
|
||||
Date: time.Date(2018, 2, 2, 10, 0, 40, 0, time.UTC),
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "4.4.4",
|
||||
Subject: "Release 4.4.4",
|
||||
Date: time.Date(2018, 2, 2, 10, 0, 40, 0, time.UTC),
|
||||
Next: &RelateTag{
|
||||
Name: "5.0.0-rc.0",
|
||||
Subject: "Release 5.0.0-rc.0",
|
||||
Date: time.Date(2018, 2, 3, 12, 30, 10, 0, time.UTC),
|
||||
},
|
||||
Previous: &RelateTag{
|
||||
Name: "4.4.3",
|
||||
Subject: "This is tag subject",
|
||||
Date: time.Date(2018, 2, 2, 0, 0, 0, 0, time.UTC),
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "4.4.3",
|
||||
Subject: "This is tag subject",
|
||||
Date: time.Date(2018, 2, 2, 0, 0, 0, 0, time.UTC),
|
||||
Next: &RelateTag{
|
||||
Name: "4.4.4",
|
||||
Subject: "Release 4.4.4",
|
||||
Date: time.Date(2018, 2, 2, 10, 0, 40, 0, time.UTC),
|
||||
},
|
||||
Previous: &RelateTag{
|
||||
Name: "v2.0.4-beta.2",
|
||||
Subject: "Release v2.0.4-beta.2",
|
||||
Date: time.Date(2018, 2, 3, 12, 15, 0, 0, time.UTC),
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "v2.0.4-beta.2",
|
||||
Subject: "Release v2.0.4-beta.2",
|
||||
Date: time.Date(2018, 2, 3, 12, 15, 0, 0, time.UTC),
|
||||
Next: &RelateTag{
|
||||
Name: "4.4.3",
|
||||
Subject: "This is tag subject",
|
||||
Date: time.Date(2018, 2, 2, 0, 0, 0, 0, time.UTC),
|
||||
},
|
||||
Previous: &RelateTag{
|
||||
Name: "v2.0.4-beta.1",
|
||||
Subject: "Release v2.0.4-beta.1",
|
||||
Date: time.Date(2018, 2, 1, 0, 0, 0, 0, time.UTC),
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "v2.0.4-beta.1",
|
||||
Subject: "Release v2.0.4-beta.1",
|
||||
Date: time.Date(2018, 2, 1, 0, 0, 0, 0, time.UTC),
|
||||
Next: &RelateTag{
|
||||
Name: "v2.0.4-beta.2",
|
||||
Subject: "Release v2.0.4-beta.2",
|
||||
Date: time.Date(2018, 2, 3, 12, 15, 0, 0, time.UTC),
|
||||
},
|
||||
Previous: nil,
|
||||
},
|
||||
},
|
||||
actual_filtered,
|
||||
actual,
|
||||
)
|
||||
|
||||
actualFiltered, errFiltered := newTagReader(client, "^v", "date").ReadAll()
|
||||
assert.Nil(errFiltered)
|
||||
assert.Equal(
|
||||
[]*Tag{
|
||||
{
|
||||
Name: "v2.0.4-beta.2",
|
||||
Subject: "Release v2.0.4-beta.2",
|
||||
Date: time.Date(2018, 2, 3, 12, 15, 0, 0, time.UTC),
|
||||
Next: nil,
|
||||
Previous: &RelateTag{
|
||||
Name: "v2.0.4-beta.1",
|
||||
Subject: "Release v2.0.4-beta.1",
|
||||
Date: time.Date(2018, 2, 1, 0, 0, 0, 0, time.UTC),
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "v2.0.4-beta.1",
|
||||
Subject: "Release v2.0.4-beta.1",
|
||||
Date: time.Date(2018, 2, 1, 0, 0, 0, 0, time.UTC),
|
||||
Next: &RelateTag{
|
||||
Name: "v2.0.4-beta.2",
|
||||
Subject: "Release v2.0.4-beta.2",
|
||||
Date: time.Date(2018, 2, 3, 12, 15, 0, 0, time.UTC),
|
||||
},
|
||||
Previous: nil,
|
||||
},
|
||||
},
|
||||
actualFiltered,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,14 +19,16 @@ func (s *tagSelector) Select(tags []*Tag, query string) ([]*Tag, string, error)
|
|||
case 2:
|
||||
old := tokens[0]
|
||||
new := tokens[1]
|
||||
if old == "" && new == "" {
|
||||
switch {
|
||||
case old == "" && new == "":
|
||||
return nil, "", nil
|
||||
} else if old == "" {
|
||||
case old == "":
|
||||
return s.selectBeforeTags(tags, new)
|
||||
} else if new == "" {
|
||||
case new == "":
|
||||
return s.selectAfterTags(tags, old)
|
||||
default:
|
||||
return s.selectRangeTags(tags, tokens[0], tokens[1])
|
||||
}
|
||||
return s.selectRangeTags(tags, tokens[0], tokens[1])
|
||||
}
|
||||
|
||||
return nil, "", errFailedQueryParse
|
||||
|
|
@ -76,7 +78,8 @@ func (*tagSelector) selectBeforeTags(tags []*Tag, token string) ([]*Tag, string,
|
|||
}
|
||||
|
||||
func (*tagSelector) selectAfterTags(tags []*Tag, token string) ([]*Tag, string, error) {
|
||||
var (
|
||||
// NOTE(clok): the res slice can range in size based on the token passed in.
|
||||
var ( //nolint:prealloc
|
||||
res []*Tag
|
||||
from string
|
||||
)
|
||||
|
|
|
|||
|
|
@ -12,51 +12,51 @@ func TestTagSelector(t *testing.T) {
|
|||
selector := newTagSelector()
|
||||
|
||||
fixtures := []*Tag{
|
||||
&Tag{Name: "2.2.12-rc.12"},
|
||||
&Tag{Name: "2.1.0"},
|
||||
&Tag{Name: "v2.0.0-beta.1"},
|
||||
&Tag{Name: "v1.2.9"},
|
||||
&Tag{Name: "v1.0.0"},
|
||||
{Name: "2.2.12-rc.12"},
|
||||
{Name: "2.1.0"},
|
||||
{Name: "v2.0.0-beta.1"},
|
||||
{Name: "v1.2.9"},
|
||||
{Name: "v1.0.0"},
|
||||
}
|
||||
|
||||
table := map[string][]string{
|
||||
// Single
|
||||
"2.2.12-rc.12": []string{
|
||||
"2.2.12-rc.12": {
|
||||
"2.2.12-rc.12",
|
||||
"2.1.0",
|
||||
},
|
||||
"v2.0.0-beta.1": []string{
|
||||
"v2.0.0-beta.1": {
|
||||
"v2.0.0-beta.1",
|
||||
"v1.2.9",
|
||||
},
|
||||
"v1.0.0": []string{
|
||||
"v1.0.0": {
|
||||
"v1.0.0",
|
||||
"",
|
||||
},
|
||||
// ~ <tag>
|
||||
"..2.1.0": []string{
|
||||
"..2.1.0": {
|
||||
"2.1.0",
|
||||
"v2.0.0-beta.1",
|
||||
"v1.2.9",
|
||||
"v1.0.0",
|
||||
"",
|
||||
},
|
||||
"..v1.0.0": []string{
|
||||
"..v1.0.0": {
|
||||
"v1.0.0",
|
||||
"",
|
||||
},
|
||||
// <tag> ~
|
||||
"v2.0.0-beta.1..": []string{
|
||||
"v2.0.0-beta.1..": {
|
||||
"2.2.12-rc.12",
|
||||
"2.1.0",
|
||||
"v2.0.0-beta.1",
|
||||
"v1.2.9",
|
||||
},
|
||||
"2.2.12-rc.12..": []string{
|
||||
"2.2.12-rc.12..": {
|
||||
"2.2.12-rc.12",
|
||||
"2.1.0",
|
||||
},
|
||||
"v1.0.0..": []string{
|
||||
"v1.0.0..": {
|
||||
"2.2.12-rc.12",
|
||||
"2.1.0",
|
||||
"v2.0.0-beta.1",
|
||||
|
|
@ -65,7 +65,7 @@ func TestTagSelector(t *testing.T) {
|
|||
"",
|
||||
},
|
||||
// <tag> ~ <tag>
|
||||
"v1.0.0..2.2.12-rc.12": []string{
|
||||
"v1.0.0..2.2.12-rc.12": {
|
||||
"2.2.12-rc.12",
|
||||
"2.1.0",
|
||||
"v2.0.0-beta.1",
|
||||
|
|
@ -73,13 +73,13 @@ func TestTagSelector(t *testing.T) {
|
|||
"v1.0.0",
|
||||
"",
|
||||
},
|
||||
"v1.0.0..v2.0.0-beta.1": []string{
|
||||
"v1.0.0..v2.0.0-beta.1": {
|
||||
"v2.0.0-beta.1",
|
||||
"v1.2.9",
|
||||
"v1.0.0",
|
||||
"",
|
||||
},
|
||||
"v1.2.9..2.1.0": []string{
|
||||
"v1.2.9..2.1.0": {
|
||||
"2.1.0",
|
||||
"v2.0.0-beta.1",
|
||||
"v1.2.9",
|
||||
|
|
|
|||
48
testdata/trimmed_body.md
vendored
Normal file
48
testdata/trimmed_body.md
vendored
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
{{ if .Versions -}}
|
||||
<a name="unreleased"></a>
|
||||
## [Unreleased]
|
||||
|
||||
{{ if .Unreleased.CommitGroups -}}
|
||||
{{ range .Unreleased.CommitGroups -}}
|
||||
### {{ .Title }}
|
||||
{{ range .Commits -}}
|
||||
- {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }}
|
||||
{{ if .TrimmedBody -}}
|
||||
{{ indent .TrimmedBody 2 }}
|
||||
{{ end -}}
|
||||
{{ end }}
|
||||
{{ end -}}
|
||||
{{ end -}}
|
||||
{{ end -}}
|
||||
|
||||
{{ range .Versions }}
|
||||
<a name="{{ .Tag.Name }}"></a>
|
||||
## {{ if .Tag.Previous }}[{{ .Tag.Name }}]{{ else }}{{ .Tag.Name }}{{ end }} - {{ datetime "2006-01-02" .Tag.Date }}
|
||||
{{ range .CommitGroups -}}
|
||||
### {{ .Title }}
|
||||
{{ range .Commits -}}
|
||||
- {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }}
|
||||
{{ if .TrimmedBody -}}
|
||||
{{ indent .TrimmedBody 2 }}
|
||||
{{ end -}}
|
||||
{{ end }}
|
||||
{{ end -}}
|
||||
|
||||
{{- if .NoteGroups -}}
|
||||
{{ range .NoteGroups -}}
|
||||
### {{ .Title }}
|
||||
{{ range .Notes }}
|
||||
{{ .Body }}
|
||||
{{ end }}
|
||||
{{ end -}}
|
||||
{{ end -}}
|
||||
{{ end -}}
|
||||
|
||||
{{- if .Versions }}
|
||||
[Unreleased]: {{ .Info.RepositoryURL }}/compare/{{ $latest := index .Versions 0 }}{{ $latest.Tag.Name }}...HEAD
|
||||
{{ range .Versions -}}
|
||||
{{ if .Tag.Previous -}}
|
||||
[{{ .Tag.Name }}]: {{ $.Info.RepositoryURL }}/compare/{{ .Tag.Previous.Name }}...{{ .Tag.Name }}
|
||||
{{ end -}}
|
||||
{{ end -}}
|
||||
{{ end -}}
|
||||
57
testdata/with_sprig.md
vendored
Normal file
57
testdata/with_sprig.md
vendored
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
{{ title "my changelog" }}
|
||||
{{ if .Versions -}}
|
||||
<a name="unreleased"></a>
|
||||
## [Unreleased]
|
||||
|
||||
{{ if .Unreleased.CommitGroups -}}
|
||||
{{ range .Unreleased.CommitGroups -}}
|
||||
### {{ .Title }}
|
||||
{{ range .Commits -}}
|
||||
- {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }}
|
||||
{{ end }}
|
||||
{{ end -}}
|
||||
{{ end -}}
|
||||
{{ end -}}
|
||||
|
||||
{{ range .Versions }}
|
||||
<a name="{{ .Tag.Name }}"></a>
|
||||
## {{ if .Tag.Previous }}[{{ .Tag.Name }}]{{ else }}{{ .Tag.Name }}{{ end }} - {{ datetime "2006-01-02" .Tag.Date }}
|
||||
{{ range .CommitGroups -}}
|
||||
### {{ .Title }}
|
||||
{{ range .Commits -}}
|
||||
- {{ if .Scope }}**{{ .Scope | upper }}:** {{ end }}{{ .Subject }}
|
||||
{{ end }}
|
||||
{{ end -}}
|
||||
|
||||
{{- if .RevertCommits -}}
|
||||
### Reverts
|
||||
{{ range .RevertCommits -}}
|
||||
- {{ .Revert.Header }}
|
||||
{{ end }}
|
||||
{{ end -}}
|
||||
|
||||
{{- if .MergeCommits -}}
|
||||
### Pull Requests
|
||||
{{ range .MergeCommits -}}
|
||||
- {{ .Header }}
|
||||
{{ end }}
|
||||
{{ end -}}
|
||||
|
||||
{{- if .NoteGroups -}}
|
||||
{{ range .NoteGroups -}}
|
||||
### {{ .Title }}
|
||||
{{ range .Notes }}
|
||||
{{ .Body }}
|
||||
{{ end }}
|
||||
{{ end -}}
|
||||
{{ end -}}
|
||||
{{ end -}}
|
||||
|
||||
{{- if .Versions }}
|
||||
[Unreleased]: {{ .Info.RepositoryURL }}/compare/{{ $latest := index .Versions 0 }}{{ $latest.Tag.Name }}...HEAD
|
||||
{{ range .Versions -}}
|
||||
{{ if .Tag.Previous -}}
|
||||
[{{ .Tag.Name }}]: {{ $.Info.RepositoryURL }}/compare/{{ .Tag.Previous.Name }}...{{ .Tag.Name }}
|
||||
{{ end -}}
|
||||
{{ end -}}
|
||||
{{ end -}}
|
||||
1
utils.go
1
utils.go
|
|
@ -23,6 +23,7 @@ func dotGet(target interface{}, prop string) (interface{}, bool) {
|
|||
value = reflect.ValueOf(target)
|
||||
}
|
||||
|
||||
//nolint:staticcheck
|
||||
field := value.FieldByName(strings.Title(key))
|
||||
if !field.IsValid() {
|
||||
return nil, false
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue