Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add -pr for inspecting GitHub pull requests #11

Merged
merged 35 commits into from
Mar 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
c597c3e
Checkpoint.
bobg Mar 20, 2023
7a4782f
Reorganize main package. Add -pr and -token. Update main package doc …
bobg Mar 20, 2023
688a881
Adjust whitespace in comment template.
bobg Mar 20, 2023
4a0ea06
Upgrade go-git dependency.
bobg Mar 20, 2023
e7afb70
Improve (?) isModverComment.
bobg Mar 21, 2023
398d2a6
Oops.
bobg Mar 21, 2023
941500f
Take a stab at adding "modver -pr" to the GitHub Actions workflow.
bobg Mar 21, 2023
0956ca0
Wrong version of actions/checkout.
bobg Mar 21, 2023
8a27bbd
Disable TestGit for now.
bobg Mar 21, 2023
b4ca6b2
Some decoupling courtesy of github.com/bobg/decouple.
bobg Mar 28, 2023
b2cea92
Add a test with mocks.
bobg Mar 29, 2023
ddd4fee
More test coverage.
bobg Mar 29, 2023
67e3d6d
Unskip TestGit.
bobg Mar 29, 2023
69ece73
Fix (?) broken test.
bobg Mar 29, 2023
45ae075
If it ain't broke?
bobg Mar 29, 2023
79b6489
???
bobg Mar 29, 2023
f93272c
Grr
bobg Mar 29, 2023
9500114
revert revert revert
bobg Mar 29, 2023
d8a421c
Flail flail flail
bobg Mar 29, 2023
c3ac997
Update go-git.
bobg Mar 29, 2023
15a155b
Skip go-git in GitHub Actions.
bobg Mar 29, 2023
3c3f7f3
Oops.
bobg Mar 29, 2023
4ffc6e8
Oh come on.
bobg Mar 29, 2023
be3a831
Downgrade go-git.
bobg Mar 29, 2023
ef790eb
go mod tidy
bobg Mar 29, 2023
da4f3ea
Formatting.
bobg Mar 29, 2023
47e555a
Add a fetch-master step.
bobg Mar 29, 2023
ee10b28
checkout v3, no -v for go test
bobg Mar 29, 2023
62cf08c
Add a workaround.
bobg Mar 29, 2023
52dea4f
Add a different workaround.
bobg Mar 29, 2023
622672c
More test coverage.
bobg Mar 29, 2023
85708b4
Oops, pass os.Args[1:] to fs.Parse.
bobg Mar 29, 2023
efb79a0
More test coverage.
bobg Mar 29, 2023
3625bf0
More test coverage.
bobg Mar 29, 2023
13dd554
More test coverage.
bobg Mar 29, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
32 changes: 17 additions & 15 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,24 @@ jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0

- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: 1.18
- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: 1.18

- name: Unit tests
run: go test -v -coverprofile=cover.out ./...
- name: Unit tests
run: go test -coverprofile=cover.out ./...

- name: Send coverage
uses: shogo82148/actions-goveralls@v1
with:
path-to-profile: cover.out
- name: Modver
if: ${{ github.event_name == 'pull_request' }}
run: go run ./cmd/modver -pr https://github.com/${{ github.repository }}/pull/${{ github.event.number }} -token ${{ github.token }} -pretty

- name: Version string check
run: go run ./cmd/modver -git `pwd`/.git -versions HEAD~1 HEAD
- name: Send coverage
uses: shogo82148/actions-goveralls@v1
with:
path-to-profile: cover.out
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
*~
cover.out
modver
/cover.out
/modver
35 changes: 35 additions & 0 deletions cmd/modver/comment.md.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Modver result

This report was generated by [Modver](https://pkg.go.dev/github.com/bobg/modver/v2),
a Go package and command that helps you obey [semantic versioning rules](https://semver.org/) in your Go module.

{{ if eq .Code "Major" }}

This PR requires an increase in your module’s major version number.
If the new major version number is 2 or greater,
you must also add or update the version suffix
on the module path defined in your `go.mod` file.
See [the Go Modules Reference](https://go.dev/ref/mod#major-version-suffixes) for more info.

{{ else if eq .Code "Minor" }}

This PR requires (at least) an increase in your module's minor version number.

{{ else if eq .Code "Patchlevel" }}

This PR requires (at least) an increase in your module's patchlevel.

{{ else }}

This PR does not require a change in your module’s version number.
(You might still consider bumping the patchlevel anyway.)

{{ end }}

{{ if ne .Code "None" }}

```
{{ .Report -}}
```

{{ end }}
43 changes: 43 additions & 0 deletions cmd/modver/compare.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package main

import (
"context"
"fmt"
"os"

"github.com/google/go-github/v50/github"
"github.com/pkg/errors"

"github.com/bobg/modver/v2"
)

func doCompare(ctx context.Context, opts options) (modver.Result, error) {
if opts.pr != "" {
owner, reponame, prnum, err := parsePR(opts.pr)
if err != nil {
return modver.None, errors.Wrap(err, "parsing pull-request URL")
}
if opts.ghtoken == "" {
return modver.None, fmt.Errorf("usage: %s -pr URL -token TOKEN [-q | -pretty]", os.Args[0])
}
gh := github.NewTokenClient(ctx, opts.ghtoken)
return doPR(ctx, gh, owner, reponame, prnum)
}

if opts.gitRepo != "" {
if len(opts.args) != 2 {
return nil, fmt.Errorf("usage: %s -git REPO [-gitcmd GIT_COMMAND] [-q | -pretty] [-v1 OLDERVERSION -v2 NEWERVERSION | -versions] OLDERREV NEWERREV", os.Args[0])
}

callback := modver.CompareDirs
if opts.versions {
callback = getTags(&opts.v1, &opts.v2, opts.args[0], opts.args[1])
}

return modver.CompareGitWith(ctx, opts.gitRepo, opts.args[0], opts.args[1], callback)
}
if len(opts.args) != 2 {
return nil, fmt.Errorf("usage: %s [-q | -pretty] [-v1 OLDERVERSION -v2 NEWERVERSION] OLDERDIR NEWERDIR", os.Args[0])
}
return modver.CompareDirs(opts.args[0], opts.args[1])
}
140 changes: 140 additions & 0 deletions cmd/modver/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
// Command modver compares two versions of the same Go packages
// and tells whether a Major, Minor, or Patchlevel version bump
// (or None)
// is needed to go from one to the other.
//
// Usage:
//
// modver -git REPO [-gitcmd GIT_COMMAND] [-q | -pretty] [-v1 OLDERVERSION -v2 NEWERVERSION | -versions] OLDERREV NEWERREV
// modver [-q | -pretty] [-v1 OLDERVERSION -v2 NEWERVERSION] OLDERDIR NEWERDIR
// modver -pr URL [-q | -pretty]
//
// With `-git REPO`,
// where REPO is the path to a Git repository,
// OLDER and NEWER are two revisions in the repository
// (e.g. hexadecimal SHA strings or "HEAD", etc)
// containing the older and newer versions of a Go module.
// Without the -git flag,
// OLDER and NEWER are two directories containing the older and newer versions of a Go module.
//
// With `-gitcmd GIT_COMMAND`,
// modver uses the given command for Git operations.
// This is "git" by default.
// If the command does not exist or is not found in your PATH,
// modver falls back to using the go-git library.
//
// With -v1 and -v2,
// modver checks whether the change from OLDERVERSION to NEWERVERSION
// (two version strings)
// is adequate for the differences detected between OLDER and NEWER.
// Output is either "OK" or "ERR"
// (followed by a description)
// and the exit code is 0 for OK and 1 for ERR.
// In quiet mode (-q),
// there is no output.
// With -git REPO and -versions instead of -v1 and -v2,
// the values for -v1 and -v2 are determined by querying the repo at the given revisions.
//
// Without -v1 and -v2
// (or -versions),
// output is a string describing the minimum version-number change required.
// In quiet mode (-q),
// there is no output,
// and the exit status is 0, 1, 2, 3, or 4
// for None, Patchlevel, Minor, Major, and error.
package main

import (
"context"
"fmt"
"io"
"os"

"golang.org/x/mod/semver"

"github.com/bobg/modver/v2"
)

const errorStatus = 4

func main() {
opts, err := parseArgs()
if err != nil {
fmt.Fprintf(os.Stderr, "Error parsing args: %s\n", err)
os.Exit(errorStatus)
}

ctx := context.Background()
if opts.gitCmd != "" {
ctx = modver.WithGit(ctx, opts.gitCmd)
}

res, err := doCompare(ctx, opts)
if err != nil {
fmt.Fprintf(os.Stderr, "Error in comparing: %s\n", err)
os.Exit(errorStatus)
}

exitCode := doShowResult(os.Stdout, res, opts)
os.Exit(exitCode)
}

func doShowResult(out io.Writer, res modver.Result, opts options) int {
if opts.v1 != "" && opts.v2 != "" {
var ok bool

cmp := semver.Compare(opts.v1, opts.v2)
switch res.Code() {
case modver.None:
ok = cmp <= 0 // v1 <= v2

case modver.Patchlevel:
ok = cmp < 0 // v1 < v2

case modver.Minor:
var (
min1 = semver.MajorMinor(opts.v1)
min2 = semver.MajorMinor(opts.v2)
)
ok = semver.Compare(min1, min2) < 0 // min1 < min2

case modver.Major:
var (
maj1 = semver.Major(opts.v1)
maj2 = semver.Major(opts.v2)
)
ok = semver.Compare(maj1, maj2) < 0 // maj1 < maj2
}

if ok {
if !opts.quiet {
if opts.versions {
fmt.Fprintf(out, "OK using versions %s and %s: %s\n", opts.v1, opts.v2, res)
} else {
fmt.Fprintf(out, "OK %s\n", res)
}
}
return 0
}
if !opts.quiet {
if opts.versions {
fmt.Fprintf(out, "ERR using versions %s and %s: %s\n", opts.v1, opts.v2, res)
} else {
fmt.Fprintf(out, "ERR %s\n", res)
}
}
return 1
}

if opts.quiet {
return int(res.Code())
}

if opts.pretty {
modver.Pretty(out, res)
} else {
fmt.Fprintln(out, res)
}

return 0
}
74 changes: 74 additions & 0 deletions cmd/modver/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package main

import (
"bytes"
"fmt"
"testing"

"github.com/bobg/modver/v2"
)

func TestDoShowResult(t *testing.T) {
cases := []struct {
res modver.Result
opts options
wantExitCode int
want string
}{{
res: modver.Patchlevel,
opts: options{quiet: true},
wantExitCode: int(modver.Patchlevel),
}, {
res: modver.Patchlevel,
want: modver.Patchlevel.String() + "\n",
}, {
res: modver.None,
opts: options{v1: "v1.0.0", v2: "v1.0.1"},
want: "OK None\n",
}, {
res: modver.None,
opts: options{v1: "v1.0.1", v2: "v1.0.0"},
want: "ERR None\n",
wantExitCode: 1,
}, {
res: modver.Patchlevel,
opts: options{v1: "v1.0.0", v2: "v1.0.1"},
want: "OK Patchlevel\n",
}, {
res: modver.Patchlevel,
opts: options{v1: "v1.0.0", v2: "v1.0.0"},
want: "ERR Patchlevel\n",
wantExitCode: 1,
}, {
res: modver.Minor,
opts: options{v1: "v1.0.0", v2: "v1.1.0"},
want: "OK Minor\n",
}, {
res: modver.Minor,
opts: options{v1: "v1.0.0", v2: "v1.0.1"},
want: "ERR Minor\n",
wantExitCode: 1,
}, {
res: modver.Major,
opts: options{v1: "v1.0.0", v2: "v2.0.0"},
want: "OK Major\n",
}, {
res: modver.Major,
opts: options{v1: "v1.0.0", v2: "v1.1.0"},
want: "ERR Major\n",
wantExitCode: 1,
}}

for i, tc := range cases {
t.Run(fmt.Sprintf("case_%02d", i+1), func(t *testing.T) {
buf := new(bytes.Buffer)
exitCode := doShowResult(buf, tc.res, tc.opts)
if exitCode != tc.wantExitCode {
t.Errorf("got exit code %d, want %d", exitCode, tc.wantExitCode)
}
if buf.String() != tc.want {
t.Errorf("got %s, want %s", buf, tc.want)
}
})
}
}