Compare commits

..

65 commits

Author SHA1 Message Date
renovate[bot]
83fc0386ad
fix(deps): update module gopkg.in/yaml.v2 to v3 (#246)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-28 08:35:43 +01:00
renovate[bot]
65fd9c7cb6
fix(deps): update all non-major dependencies (#269)
* fix(deps): update all non-major dependencies

* chore: bump go to v1.24

Signed-off-by: Manuel Vogel <8409778+mavogel@users.noreply.github.com>

* fix: build and lint

Signed-off-by: Manuel Vogel <8409778+mavogel@users.noreply.github.com>

* fix: goreleaser

Signed-off-by: Manuel Vogel <8409778+mavogel@users.noreply.github.com>

* fix: goveralls

Signed-off-by: Manuel Vogel <8409778+mavogel@users.noreply.github.com>

* fix: remove deprecatad linter

Signed-off-by: Manuel Vogel <8409778+mavogel@users.noreply.github.com>

* fix: goveralls latest version install

Signed-off-by: Manuel Vogel <8409778+mavogel@users.noreply.github.com>

* fix: linter

Signed-off-by: Manuel Vogel <8409778+mavogel@users.noreply.github.com>

* fix: bump ci linter to v1.64.7

Signed-off-by: Manuel Vogel <8409778+mavogel@users.noreply.github.com>

* fix: bump ci linter to v1.64.7 and fix issues

Signed-off-by: Manuel Vogel <8409778+mavogel@users.noreply.github.com>

* fix: remove version from linter yaml

Signed-off-by: Manuel Vogel <8409778+mavogel@users.noreply.github.com>

---------

Signed-off-by: Manuel Vogel <8409778+mavogel@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Manuel Vogel <8409778+mavogel@users.noreply.github.com>
2025-03-26 17:06:17 +01:00
renovate[bot]
6a6993d52d
chore(deps): update actions/setup-go action to v5 (#264)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-26 08:40:33 +01:00
renovate[bot]
09d3a61821
fix(deps): update all non-major dependencies (#240)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-18 08:42:59 +01:00
renovate[bot]
d93ef22384
fix(deps): update all non-major dependencies (#236)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-13 16:20:59 +01:00
renovate[bot]
ffadcdb2f8
fix(deps): update module github.com/kyokomi/emoji/v2 to v2.2.12 (#233)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-19 22:34:31 +01:00
renovate[bot]
09ccd2f09b
fix(deps): update module github.com/urfave/cli/v2 to v2.24.4 (#229)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-17 14:11:51 +01:00
Manuel Vogel
d7f33d0797 chore: update changelog for v0.15.4 2023-02-15 08:45:24 +01:00
Manuel Vogel
78063fb71f chore: new release due to shecksum mismatch. Closes #232
Signed-off-by: Manuel Vogel <mavogel@posteo.de>
2023-02-15 08:43:42 +01:00
Manuel Vogel
06336286cf chore: update changelog for v0.15.3 2023-02-11 11:55:00 +01:00
Manuel Vogel
6ad9b5c2db
fix: release process (#231)
* chore: use  --clean for goreleaser
* fix(ci): add gorleaser test
* fix(ci): prebuild binary in IT test
* fix(ci): use only ubuntu for docker image tests
2023-02-11 11:50:26 +01:00
Manuel Vogel
26c9a7c721 chore: update changelog for v0.15.3 2023-02-11 11:00:55 +01:00
Manuel Vogel
f3cf5b67a0
fix(ci): add integration test with docker image (#226)
* fix: add git safe directory for /workdir
* chore: use docker staged build
2023-02-11 10:54:32 +01:00
renovate[bot]
b0f4afeff4
fix(deps): update module github.com/urfave/cli/v2 to v2.24.3 (#227)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-08 15:01:44 +01:00
renovate[bot]
f608376b8d
fix(deps): update module github.com/fatih/color to v1.14.1 (#224)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-01-24 07:27:10 +01:00
renovate[bot]
6ff4d21a0e
fix(deps): update all non-major dependencies (#223)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-01-23 09:58:25 +01:00
Manuel Vogel
13cb5b3dc4 chore: bump docker/login-action to v2. Closes #206
Signed-off-by: Manuel Vogel <mavogel@posteo.de>
2023-01-23 09:55:36 +01:00
Manuel Vogel
1dbe8da4a3 chore: bump goreleaser/goreleaser-action to v4. Closes #208
Signed-off-by: Manuel Vogel <mavogel@posteo.de>
2023-01-23 09:53:30 +01:00
Manuel Vogel
7d4f3e8dff chore: update changelog for v0.15.2 2023-01-22 12:06:25 +01:00
Manuel Vogel
36320619c5 chore: update changelog for v0.15.2 2023-01-22 12:04:33 +01:00
renovate[bot]
4f3ff62db6
chore(deps): update all non-major dependencies (#220)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-01-22 12:01:00 +01:00
renovate[bot]
5896ad91ce
fix(deps): update module gopkg.in/yaml.v2 to v3 (#221)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-01-22 11:59:09 +01:00
Orpheus Lummis
cbab5b89dc
chore: update Go install instructions (#205) 2023-01-22 11:57:59 +01:00
Benjamin K
66a1d9ea5a
fix: typo in readme (#196) 2023-01-22 11:57:26 +01:00
Manuel Vogel
d1dc1da744
chore: bump golang to 1.19 (#218)
* chore: bump golang to 1.19

Signed-off-by: Manuel Vogel <mavogel@posteo.de>

* fix: [#212] Vulnerabilities. (#219)

Co-authored-by: Manuel Vogel <mavogel@posteo.de>

* chore: bump all dependencies

Signed-off-by: Manuel Vogel <mavogel@posteo.de>

* chore(deps): update actions/setup-go action to v3 (#202)

Co-authored-by: Renovate Bot <bot@renovateapp.com>

* chore(deps): update actions/checkout action to v3 (#201)

Co-authored-by: Renovate Bot <bot@renovateapp.com>

* chore(deps): update golangci/golangci-lint-action action to v3 (#203)

Co-authored-by: Renovate Bot <bot@renovateapp.com>

* chore(ci): add explicit go setup before linting

Signed-off-by: Manuel Vogel <mavogel@posteo.de>

* chore(ci): bump golangci to v1.50.1

Signed-off-by: Manuel Vogel <mavogel@posteo.de>

* chore: go fmt

Signed-off-by: Manuel Vogel <mavogel@posteo.de>

* chore: ignore staticcheck for strings.Title

Signed-off-by: Manuel Vogel <mavogel@posteo.de>

* chore: reaplce all ioutil with os funcs

Signed-off-by: Manuel Vogel <mavogel@posteo.de>

* chore ignore file read sec check

Signed-off-by: Manuel Vogel <mavogel@posteo.de>

* fix: remove unnecessary if before trimPrefix

Signed-off-by: Manuel Vogel <mavogel@posteo.de>

Signed-off-by: Manuel Vogel <mavogel@posteo.de>
Co-authored-by: Ben van B <030@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2023-01-22 11:56:18 +01:00
Manuel Vogel
03f0a44924
chore: update changelog for v0.15.1 2021-12-14 13:25:51 +01:00
Manuel Vogel
9558380243
chore: ignore .vscode 2021-12-14 13:23:54 +01:00
renovate[bot]
3d8006051f
fix(deps): update all non-major dependencies (#179)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-12-14 13:20:53 +01:00
Jameson Stone
2861505ecb
ci(workflows): 🔧 remove manual if contains skip in workflows (#164) 2021-12-14 13:20:18 +01:00
renovate[bot]
899c1ede45
chore(deps): update all non-major dependencies docker tags (#168)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-08-31 12:24:56 +02:00
renovate[bot]
93707ab667
fix(deps): update module github.com/andygrunwald/go-jira to v1.14.0 (#167)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-08-04 15:56:31 +02:00
renovate[bot]
7a3896821b
fix(deps): update module github.com/alecaivazis/survey/v2 to v2.2.16 (#165)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-08-04 11:34:53 +02:00
renovate[bot]
0022ecf864
fix(deps): update module github.com/alecaivazis/survey/v2 to v2.2.15 (#163)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-07-26 10:13:47 +02:00
Manuel Vogel
82ead28bee
chore: update changelog for v0.15.0 2021-07-09 09:31:50 +02:00
Thierno IB. BARRY
21b98bd56f
feat: Automatic link for gitlab merge requests (#160) 2021-07-09 09:26:33 +02:00
renovate[bot]
45e01f0f7f
fix(deps): update module github.com/alecaivazis/survey/v2 to v2.2.14 (#158)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-07-05 10:18:56 +02:00
renovate[bot]
6a18b6ef90
fix(deps): update module github.com/alecaivazis/survey/v2 to v2.2.13 (#156)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-06-29 08:24:33 +02:00
renovate[bot]
b38b5032cf
chore(deps): update alpine docker tag to v3.14.0 (#153) 2021-06-17 07:05:15 -05:00
renovate[bot]
9842899ea1
fix(deps): update module github.com/fatih/color to v1.12.0 (#150)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-05-25 09:05:09 +02:00
renovate[bot]
ac01b30c39
fix(deps): update module github.com/fatih/color to v1.11.0 (#149)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-05-14 09:19:18 +02:00
renovate[bot]
cefdc53e29
fix(deps): update module github.com/alecaivazis/survey/v2 to v2.2.12 (#147)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-04-30 14:03:34 +02:00
Derek Smith
c257740de9 chore: update changelog for v0.14.2 2021-04-16 07:17:02 -05:00
Khosrow Moossavi
bfac4702a7
fix: add CommitGroupTitleOrder back to Options (#143)
This was, accidentally, removed in part of one PR a while back and
caused the Custom sort to not work properly.

Signed-off-by: Khosrow Moossavi <khos2ow@gmail.com>
2021-04-14 17:01:05 -04:00
renovate[bot]
57aad771c8
chore(deps): update alpine docker tag to v3.13.5 (#144)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-04-14 15:46:29 -04:00
Derek Smith
bc0f363327 chore: update changelog for v0.14.1 2021-04-13 16:35:35 -05:00
Derek Smith
fdd421b057
fix(template): address regression in string functions for template engine (#142)
It appears that `Sprig` flips the inputs of the `contains`, `hasPrefix`, `replace`
and `hasSuffix` `strings` methods. This appears to be the cause of the regression.

See: https://github.com/Masterminds/sprig/blob/master/functions.go#L149-L152

This results in a regression against the previous implementations of the template
functions.

Signed-off-by: Derek Smith <derek@clokwork.net>
2021-04-13 16:27:42 -05:00
Khosrow Moossavi
7cc56b1256
chore: add docker target to Makefile (#138)
Signed-off-by: Khosrow Moossavi <khos2ow@gmail.com>
2021-04-02 12:19:50 -04:00
renovate[bot]
f76afed086
chore(deps): update alpine docker tag to v3.13.4 (#136)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-04-01 10:47:18 -05:00
Anthony MARQUES
2307bff72f
feat: add docker image on release and master (#135)
* feat: add docker image on release and master

* resolves return on the PR

* Add Installation docker doc

* Update .github/workflows/publish.yml

Co-authored-by: Derek Smith <derek@clokwork.net>

* Resovle PR conversations

* No v in RawVersion

Co-authored-by: Derek Smith <derek@clokwork.net>
2021-04-01 10:41:35 -05:00
Khosrow Moossavi
8d9e00b699
ci: overall enhancements and cosmetics improvements (#134)
* ci: cosmetic renaming CI jobs

Signed-off-by: Khosrow Moossavi <khos2ow@gmail.com>

* chore: overrall Makefile enhancements

Signed-off-by: Khosrow Moossavi <khos2ow@gmail.com>
2021-03-31 12:41:24 -04:00
Derek Smith
b02996e027
chore: add make release target (#130)
Signed-off-by: Derek Smith <derek@clokwork.net>
2021-03-30 12:53:27 -05:00
Derek Smith
2f5b47b0f7 chore: update changelog for v0.14.0 2021-03-28 22:21:56 -05:00
Trent Albright
4f3fdc4dae
feat: add sprig template functions support (#131)
* cherry-pick from delmendo

* add tests, docs, and lift hermetic restriction

* remove duplicate funcs that are now provided by sprig

* switch func load order to allow built-ins precedence

* Update chglog.go

Co-authored-by: Dirk Elmendorf <dirk@r26d.com>
2021-03-28 22:18:36 -05:00
Sander Blue
e523fd471a
feat: add --sort [TYPE] flag (#78)
* feat(chglog): add --sort flag

* chore(sort): update README with --sort usage
2021-03-28 22:17:21 -05:00
Khosrow Moossavi
34b9d5c997
ci: deprecate AppVoyer integration (#128)
With the migration to GitHub Action, there's no need to continue to use
AppVoyer to only test on Windows, as it's covered by corresponding new
jobs.

Signed-off-by: Khosrow Moossavi <khos2ow@gmail.com>
2021-03-25 22:48:53 -05:00
Derek Smith
b44eb4e011
chore(CHANGELOG): regenerate CHANGELOG with type-scope and KAC template (#129) 2021-03-24 16:59:08 -05:00
Derek Smith
4d8b2b6be7 chore: update changelog for v0.13.0 2021-03-23 14:14:31 -05:00
Derek Smith
3113e42524
chore: use ldflags to pass version to build process (#127) 2021-03-23 14:11:35 -05:00
Mason J. Katz
9a0d584745
feat: add support for rendering .Body after .Subject as part of list (#121)
When attempting to render a commit body below the summary line of the
commit there are two problems:

1) The text needs to be indented two spaces to appear as part of the
list.

2) Notes (e.g. BREAKING CHANGE) are included in the body and end up
being repeating in a Notes section (if this is part of your template).

To address #1 add an `indent` func to the template parsing.
To address #2 add a `TrimmedBody` to the `Commit` fields.

The `TrimmedBody` will include everything in `Body` but not any
`Ref`s, `Note`s, `Mention`s, `CoAuthors`, or `Signers`.

Both the CoAuthors and Signers are now first class in the Commit
struct.

With both of these a template block like:

```
{{ if .TrimmedBody -}}
{{ indent .TrimmedBody 2 }}
{{ end -}}
```

Will render the trimmed down body section as intended.

See TestGeneratorWithTimmedBody for example of desired output.
2021-03-22 16:04:57 -05:00
Derek Smith
2caa67cc76 chore: update changelog for v0.12.0 2021-03-20 22:20:14 -05:00
Derek Smith
9926e07971 chore: bumps version to v0.12.0 2021-03-20 21:57:06 -05:00
Louis DeLosSantos
ebff3d0beb
feat: allow tag sorting by semver (#124)
Relates to #123.

While this does not introduce "per-branch" tag parsing it does allow an
alternative tag sorting method which maybe a better solution.

With this commit the user can decide to sort the tags by semver instead
of dates.

This is useful where repositories are utilizing a  stable branch model
and back-ports are interleaved with new releases.

For example, if your mainline is on v3.0.0 with it's last release
1/1/2021 and a back-port release of v2.0.1 is released on 1/2/2021,
sorting by semver will correctly order the change log producing
v2.0.1 -> v2.0.1 -> v3.0.0

This functionality is completely opt-in and defaults to the original
"date" sorting

Signed-off-by: ldelossa <louis.delos@gmail.com>
2021-03-20 17:21:47 -05:00
Khosrow Moossavi
9a1a9a525c
chore(docs):cleanup Markdown lint issues and line breaks (#122)
* chore(docs): Fix markdown lint issues
* chore(docs): Adhere to semantic line breaks
2021-03-18 08:35:57 +01:00
Derek Smith
ae3382b7c8
chore(ci): add golangci-lint action and apply linting changes (#120)
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

Signed-off-by: Khosrow Moossavi <khos2ow@gmail.com>

* fix: file is not goimports-ed

Signed-off-by: Khosrow Moossavi <khos2ow@gmail.com>

* fix: golint and exported functions comments

Signed-off-by: Khosrow Moossavi <khos2ow@gmail.com>

* chore(lint): address gosec G304 warning

* chore(lint): address uparam warnings

* chore(lint): address scopelint lint failures

* fix: cyclomatic complexity

Signed-off-by: Khosrow Moossavi <khos2ow@gmail.com>

* chore(lint): address prealloc warning, noting that we are warning for now

* chore(lint): address govet and errorlint failures

* chore: clean up defer logic when checking errors

Co-authored-by: Khosrow Moossavi <khos2ow@gmail.com>
2021-03-16 21:24:36 -05:00
Manuel Vogel
2c3d3f400e
chore: bump golang to 1.16 (#118)
* chore: support goarch 386
* docs(readme): add golang version hint in development section
2021-03-14 21:21:30 +01:00
55 changed files with 1863 additions and 558 deletions

View file

@ -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

View file

@ -29,6 +29,13 @@
{{ end }}
{{ end -}}
{{- if .MergeCommits -}}
### Pull Requests
{{ range .MergeCommits -}}
- {{ .Header }}
{{ end }}
{{ end -}}
{{- if .NoteGroups -}}
{{ range .NoteGroups -}}
### {{ .Title }}

View file

@ -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
View 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
View 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

View file

@ -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 }}

View file

@ -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
View file

@ -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
View 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

View file

@ -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"

View file

@ -1,43 +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))
@ -46,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
@ -58,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>
@ -108,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
@ -153,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>
@ -168,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
@ -182,7 +430,16 @@ 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.2...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

View file

@ -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
View 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
View file

@ -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
View file

@ -4,14 +4,12 @@
[![godoc.org](https://img.shields.io/badge/godoc-reference-blue.svg?style=flat-square)](https://godoc.org/github.com/git-chglog/git-chglog)
[![Actions Status](https://github.com/git-chglog/git-chglog/workflows/tests/badge.svg)](https://github.com/git-chglog/git-chglog/actions)
[![AppVeyor](https://img.shields.io/appveyor/ci/tsuyoshiwada/git-chglog/master.svg?style=flat-square)](https://ci.appveyor.com/project/tsuyoshiwada/git-chglog/branch/master)
[![Coverage Status](https://img.shields.io/coveralls/github/git-chglog/git-chglog.svg?style=flat-square)](https://coveralls.io/github/git-chglog/git-chglog?branch=master)
[![MIT License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](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
```
![init option demo](./docs/assets/init.gif)
@ -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

View file

@ -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,

View file

@ -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)
}

View file

@ -7,6 +7,7 @@ import (
"time"
"github.com/fatih/color"
chglog "github.com/git-chglog/git-chglog"
)

View file

@ -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
},
}

View file

@ -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,
},

View file

@ -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
}

View file

@ -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 ...

View file

@ -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

View file

@ -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)
}

View file

@ -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

View file

@ -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
@ -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 {
@ -219,7 +234,7 @@ func AppAction(c *cli.Context) error {
Stderr: colorable.NewColorableStderr(),
ConfigPath: c.String("config"),
Template: c.String("template"),
RepositoryUrl: c.String("repository-url"),
RepositoryURL: c.String("repository-url"),
OutputPath: c.String("output"),
Silent: c.Bool("silent"),
NoColor: c.Bool("no-color"),
@ -230,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(),
@ -245,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)
}
}

View file

@ -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)
}
}

View file

@ -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) {

View file

@ -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)
}

View file

@ -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 == "" {

View file

@ -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 " []"

View file

@ -1,4 +0,0 @@
package main
// Version of git-chglog cli client
const Version = "v0.11.2"

View file

@ -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)
})

View file

@ -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],

View file

@ -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 {

View file

@ -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",

View file

@ -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]

View file

@ -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")

View file

@ -19,7 +19,7 @@ func Example() {
},
Options: &Options{
CommitFilters: map[string][]string{
"Type": []string{
"Type": {
"feat",
"fix",
},

View file

@ -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
View file

@ -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
View file

@ -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=

View file

@ -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,
}
}

View file

@ -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: "",
},

View file

@ -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?`),
}
}

View file

@ -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) {

View file

@ -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 ...

View file

@ -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`,

View file

@ -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)
})
}

View file

@ -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,
)
}

View file

@ -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
)

View file

@ -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
View 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
View 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 -}}

View file

@ -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