Skip to content

Commit e686f2b

Browse files
committed
feat: Add log command
1 parent f0a068a commit e686f2b

File tree

12 files changed

+580
-13
lines changed

12 files changed

+580
-13
lines changed

README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,28 @@ $ git-semver next --pre-release-tag=alpha --pre-release-counter
5555
1.2.3-alpha.1
5656
```
5757

58+
### log
59+
60+
The `log` command prints the commit log of all commits, which were contained in a specified version or all commits since the latest version if no version is specified.
61+
62+
#### Examples
63+
64+
Print the commits since the latest version.
65+
```bash
66+
$ git-semver log v1.0.0
67+
commit 688dd5f56c839f1d7871dd406b72e0f2f7ec5cf4
68+
Author: John Doe <[email protected]>
69+
Date: Sun May 24 16:41:51 2020 +0200
70+
71+
fix: Fix some Bug
72+
73+
commit a89b0cc7dc7838cd6c19e733efe6c95fc457cde9
74+
Author: John Doe <[email protected]>
75+
Date: Tue Dec 03 10:00:23 2019 +0100
76+
77+
feat: Add some feature
78+
```
79+
5880
### compare
5981

6082
The `compare` command is an utility command to compare two semantic versions.

cli/log/command.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package log
2+
3+
import (
4+
"fmt"
5+
"github.com/psanetra/git-semver/cli/common_opts"
6+
"github.com/psanetra/git-semver/logger"
7+
"github.com/psanetra/git-semver/semver"
8+
"github.com/psanetra/git-semver/version_log"
9+
"github.com/spf13/cobra"
10+
)
11+
12+
var excludePreReleases bool
13+
14+
var Command = cobra.Command{
15+
Use: "log [<version>]",
16+
Short: "prints the git log for the specified version",
17+
Long: "This command prints all commits, which were contained in a specified version or all commits since the latest version if no version is specified.",
18+
Args: cobra.MaximumNArgs(1),
19+
Run: func(cmd *cobra.Command, args []string) {
20+
21+
var version *semver.Version
22+
var err error
23+
24+
if len(args) > 0 {
25+
version, err = semver.ParseVersion(args[0])
26+
if err != nil {
27+
logger.Logger.Fatalln("Could not parse version:", err)
28+
}
29+
}
30+
31+
commits, err := version_log.VersionLog(version_log.VersionLogOptions{
32+
Workdir: common_opts.Workdir,
33+
Version: version,
34+
ExcludePreReleaseCommits: excludePreReleases,
35+
})
36+
37+
if err != nil {
38+
logger.Logger.Fatalln(err)
39+
}
40+
41+
for _, commit := range commits{
42+
fmt.Print(commit)
43+
}
44+
},
45+
}
46+
47+
func init() {
48+
Command.Flags().BoolVar(&excludePreReleases, "exclude-pre-releases", false, "Specifies if the log should exclude pre-release commits from the log.")
49+
}

cli/main.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"github.com/psanetra/git-semver/cli/common_opts"
55
"github.com/psanetra/git-semver/cli/compare"
66
"github.com/psanetra/git-semver/cli/latest"
7+
"github.com/psanetra/git-semver/cli/log"
78
"github.com/psanetra/git-semver/cli/next"
89
"github.com/psanetra/git-semver/logger"
910
"github.com/spf13/cobra"
@@ -28,6 +29,7 @@ func main() {
2829

2930
rootCmd.AddCommand(&latest.Command)
3031
rootCmd.AddCommand(&next.Command)
32+
rootCmd.AddCommand(&log.Command)
3133
rootCmd.AddCommand(&compare.Command)
3234
err := rootCmd.Execute()
3335

git_utils/get_versions.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package git_utils
2+
3+
import (
4+
"github.com/psanetra/git-semver/semver"
5+
"gopkg.in/src-d/go-git.v4"
6+
"io"
7+
)
8+
9+
func GetVersions(repo *git.Repository) ([]*semver.Version, error) {
10+
11+
tagIter, err := repo.Tags()
12+
13+
if err != nil {
14+
return nil, err
15+
}
16+
17+
defer tagIter.Close()
18+
19+
var ret []*semver.Version
20+
21+
for tag, err := tagIter.Next(); err != io.EOF; tag, err = tagIter.Next() {
22+
if err != nil {
23+
return nil, err
24+
}
25+
26+
tagName := tag.Name().Short()
27+
28+
version, err := semver.ParseVersion(tagName)
29+
30+
if err != nil {
31+
continue
32+
}
33+
34+
ret = append(ret, version)
35+
}
36+
37+
return ret, nil
38+
}

git_utils/ref_is_on_current_branch.go

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,8 @@ import (
77
"gopkg.in/src-d/go-git.v4/plumbing/revlist"
88
)
99

10-
func AssertRefIsOnHead(repo *git.Repository, ref *plumbing.Reference, message string) error {
11-
headRef, err := repo.Head()
12-
13-
if err != nil {
14-
return err
15-
}
16-
17-
headRefList, err := revlist.Objects(
10+
func AssertRefIsReachable(repo *git.Repository, precedingRef *plumbing.Reference, headRef *plumbing.Reference, message string) error {
11+
toRefList, err := revlist.Objects(
1812
repo.Storer,
1913
[]plumbing.Hash{
2014
headRef.Hash(),
@@ -26,10 +20,10 @@ func AssertRefIsOnHead(repo *git.Repository, ref *plumbing.Reference, message st
2620
return err
2721
}
2822

29-
refCommitHash := RefToCommitHash(repo.Storer, ref)
23+
refCommitHash := RefToCommitHash(repo.Storer, precedingRef)
3024

31-
if !HashListContains(headRefList, refCommitHash) {
32-
return errors.Errorf(message + " (tag: %s; commit: %s)", ref.Name().String(), refCommitHash.String())
25+
if !HashListContains(toRefList, refCommitHash) {
26+
return errors.Errorf(message + " (tag: %s; commit: %s)", precedingRef.Name().String(), refCommitHash.String())
3327
}
3428

3529
return nil

git_utils/sort_commits_desc.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package git_utils
2+
3+
import "gopkg.in/src-d/go-git.v4/plumbing/object"
4+
5+
type ByCommitTimeDesc []*object.Commit
6+
7+
func (a ByCommitTimeDesc) Len() int { return len(a) }
8+
func (a ByCommitTimeDesc) Less(i, j int) bool { return a[i].Committer.When.After(a[j].Committer.When) }
9+
func (a ByCommitTimeDesc) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
package de.psanetra.gitsemver;
2+
3+
import de.psanetra.gitsemver.containers.GitSemverContainer;
4+
import org.junit.jupiter.api.Test;
5+
6+
import java.io.IOException;
7+
8+
import static org.assertj.core.api.Assertions.assertThat;
9+
import static org.assertj.core.api.Assertions.assertThatCode;
10+
11+
public class LogCmdTests {
12+
13+
@Test
14+
public void shouldPrintLogWithNoTags() {
15+
16+
try (var container = new GitSemverContainer()) {
17+
container.start();
18+
19+
container.addNewFileToGit("file.txt");
20+
container.gitCommit("feat: Add feature");
21+
container.addNewFileToGit("file2.txt");
22+
container.gitCommit("fix: Add fix");
23+
24+
assertThat(container.exec("git", "semver", "log"))
25+
.contains("feat: Add feature")
26+
.contains("fix: Add fix");
27+
}
28+
29+
}
30+
31+
@Test
32+
public void shouldPrintNoLogIfLatestCommitIsTagged() {
33+
34+
try (var container = new GitSemverContainer()) {
35+
container.start();
36+
37+
container.addNewFileToGit("file.txt");
38+
container.gitCommit("feat: Add feature");
39+
container.addNewFileToGit("file2.txt");
40+
container.gitCommit("fix: Add fix");
41+
container.gitTag("v1.0.0");
42+
43+
assertThat(container.exec("git", "semver", "log"))
44+
.doesNotContain("feat: Add feature")
45+
.doesNotContain("fix: Add fix");
46+
}
47+
48+
}
49+
50+
@Test
51+
public void shouldPrintLogForSpecificVersion() {
52+
53+
try (var container = new GitSemverContainer()) {
54+
container.start();
55+
56+
container.addNewFileToGit("file.txt");
57+
container.gitCommit("feat: Add feature");
58+
container.gitTag("v0.1.0");
59+
container.addNewFileToGit("file2.txt");
60+
container.gitCommit("fix: Add fix");
61+
container.addNewFileToGit("file3.txt");
62+
container.gitCommit("fix: Add another fix");
63+
container.gitTag("v1.0.0");
64+
65+
assertThat(container.exec("git", "semver", "log", "v1.0.0"))
66+
.doesNotContain("feat: Add feature")
67+
.contains("fix: Add fix")
68+
.contains("fix: Add another fix");
69+
}
70+
71+
}
72+
73+
@Test
74+
public void shouldPrintLogWithExcludingSimplyTaggedCommitHistory() {
75+
76+
try (var container = new GitSemverContainer()) {
77+
container.start();
78+
79+
container.addNewFileToGit("file.txt");
80+
container.gitCommit("feat: Add feature");
81+
container.gitTag("v1.0.0");
82+
container.addNewFileToGit("file2.txt");
83+
container.gitCommit("fix: Add fix");
84+
85+
assertThat(container.exec("git", "semver", "log"))
86+
.doesNotContain("feat: Add feature")
87+
.contains("fix: Add fix");
88+
}
89+
90+
}
91+
92+
@Test
93+
public void shouldPrintLogWithExcludingAnnotatedTaggedCommitHistory() {
94+
95+
try (var container = new GitSemverContainer()) {
96+
container.start();
97+
98+
container.addNewFileToGit("file.txt");
99+
container.gitCommit("feat: Add feature");
100+
container.gitAnnotatedTag("v1.0.0", "Release 1");
101+
container.addNewFileToGit("file2.txt");
102+
container.gitCommit("fix: Add fix");
103+
104+
assertThat(container.exec("git", "semver", "log"))
105+
.doesNotContain("feat: Add feature")
106+
.contains("fix: Add fix");
107+
}
108+
109+
}
110+
111+
@Test
112+
public void shouldPrintLogUpToSimpleTag() {
113+
114+
try (var container = new GitSemverContainer()) {
115+
container.start();
116+
117+
container.addNewFileToGit("file.txt");
118+
container.gitCommit("feat: Add feature");
119+
container.gitTag("v1.0.0");
120+
container.addNewFileToGit("file2.txt");
121+
container.gitCommit("fix: Add fix");
122+
123+
assertThat(container.exec("git", "semver", "log", "v1.0.0"))
124+
.contains("feat: Add feature")
125+
.doesNotContain("fix: Add fix");
126+
}
127+
128+
}
129+
130+
@Test
131+
public void shouldPrintLogUpToAnnotatedTagged() {
132+
133+
try (var container = new GitSemverContainer()) {
134+
container.start();
135+
136+
container.addNewFileToGit("file.txt");
137+
container.gitCommit("feat: Add feature");
138+
container.gitAnnotatedTag("v1.0.0", "Release 1");
139+
container.addNewFileToGit("file2.txt");
140+
container.gitCommit("fix: Add fix");
141+
142+
assertThat(container.exec("git", "semver", "log", "v1.0.0"))
143+
.contains("feat: Add feature")
144+
.doesNotContain("fix: Add fix");
145+
}
146+
147+
}
148+
149+
@Test
150+
public void shouldPrintLogWithPreReleaseCommitsInclusive() {
151+
152+
try (var container = new GitSemverContainer()) {
153+
container.start();
154+
155+
container.addNewFileToGit("file.txt");
156+
container.gitCommit("feat: Add feature");
157+
container.gitTag("v1.0.0-alpha");
158+
container.addNewFileToGit("file2.txt");
159+
container.gitCommit("fix: Add fix");
160+
161+
assertThat(container.exec("git", "semver", "log"))
162+
.contains("feat: Add feature")
163+
.contains("fix: Add fix");
164+
}
165+
166+
}
167+
168+
@Test
169+
public void shouldPrintLogWithPreReleaseCommitsExclusive() {
170+
171+
try (var container = new GitSemverContainer()) {
172+
container.start();
173+
174+
container.addNewFileToGit("file.txt");
175+
container.gitCommit("feat: Add feature");
176+
container.gitTag("v1.0.0-alpha");
177+
container.addNewFileToGit("file2.txt");
178+
container.gitCommit("fix: Add fix");
179+
180+
assertThat(container.exec("git", "semver", "log", "--exclude-pre-releases"))
181+
.doesNotContain("feat: Add feature")
182+
.contains("fix: Add fix");
183+
}
184+
185+
}
186+
187+
@Test
188+
public void shouldPrintLogWithLatestPrecedingVersionNotReachableFromHEAD() {
189+
190+
try (var container = new GitSemverContainer()) {
191+
container.start();
192+
193+
container.addNewFileToGit("file.txt");
194+
container.gitCommit("feat: Initial feature, which is contained in v1.0.0");
195+
container.gitCheckoutNewBranch("v1");
196+
container.addNewFileToGit("file2.txt");
197+
container.gitCommit("feat: v1");
198+
container.gitTag("v1.0.0");
199+
container.gitCheckout("master");
200+
container.addNewFileToGit("file2.txt");
201+
container.gitCommit("fix: Commit which is only on v2.0.0");
202+
container.gitTag("v2.0.0");
203+
204+
assertThat(container.exec("git", "semver", "log", "v2.0.0"))
205+
.doesNotContain("feat: Initial feature, which is contained in v1.0.0")
206+
.doesNotContain("feat: v1")
207+
.contains("fix: Commit which is only on v2.0.0");
208+
}
209+
210+
}
211+
212+
}

0 commit comments

Comments
 (0)