diff --git a/cmd.go b/cmd.go index c6fd56c..42b5d1f 100644 --- a/cmd.go +++ b/cmd.go @@ -10,6 +10,7 @@ import ( "net/url" "os" "strconv" + "strings" "github.com/aktau/github-release/github" ) @@ -41,12 +42,6 @@ func infocmd(opt Options) error { } } - renderer := renderInfoText - - if opt.Info.JSON { - renderer = renderInfoJSON - } - // List releases + assets. var releases []Release if tag == "" { @@ -66,10 +61,23 @@ func infocmd(opt Options) error { releases = []Release{*release} } - return renderer(tags, releases) + renderer := renderInfoText + + switch { + case opt.Info.JSON: + renderer = renderInfoJSON + case opt.Info.Markdown: + renderer = renderInfoMarkdown + if !opt.Info.Prerelease { + // Exclude pre-releases unless they were requested + releases = filterPreReleases(releases) + } + } + + return renderer(opt.Info.Repo, tags, releases) } -func renderInfoText(tags []Tag, releases []Release) error { +func renderInfoText(_ string, tags []Tag, releases []Release) error { fmt.Println("tags:") for _, tag := range tags { fmt.Println("-", &tag) @@ -83,7 +91,7 @@ func renderInfoText(tags []Tag, releases []Release) error { return nil } -func renderInfoJSON(tags []Tag, releases []Release) error { +func renderInfoJSON(_ string, tags []Tag, releases []Release) error { out := struct { Tags []Tag Releases []Release @@ -97,6 +105,43 @@ func renderInfoJSON(tags []Tag, releases []Release) error { return enc.Encode(&out) } +func renderInfoMarkdown(repo string, tags []Tag, releases []Release) error { + tagMap := make(map[string]Tag) + for _, t := range tags { + tagMap[t.Name] = t + } + + fmt.Printf("# %s Changelog\n", strings.ToTitle(repo)) + fmt.Println() + for _, r := range releases { + fmt.Printf("## %s - %s\n\n", r.TagName, r.Name) + fmt.Printf("Published %s\n\n", r.Published) + fmt.Println(r.Description) + fmt.Println() + if len(r.TagName) != 0 { + t, ok := tagMap[r.TagName] + if !ok { + return fmt.Errorf("No definition for tag: %v in %v", r.TagName, r.Name) + } + fmt.Printf("Commit [%s](%s) Download [zip](%s)\n", t.Commit.Sha, t.Commit.Url, t.ZipBallUrl) + fmt.Println() + } + } + + return nil +} + +func filterPreReleases(releases []Release) []Release { + f := make([]Release, 0, len(releases)) + for _, r := range releases { + if !r.Prerelease { + f = append(f, r) + } + } + + return f +} + func uploadcmd(opt Options) error { user := nvls(opt.Upload.User, EnvUser) repo := nvls(opt.Upload.Repo, EnvRepo) diff --git a/github-release.go b/github-release.go index 9c6f27c..34f3ea7 100644 --- a/github-release.go +++ b/github-release.go @@ -63,11 +63,13 @@ type Options struct { Tag string `goptions:"-t, --tag, obligatory, description='Git tag of release to delete'"` } `goptions:"delete"` Info struct { - Token string `goptions:"-s, --security-token, description='Github token ($GITHUB_TOKEN if set). required if repo is private.'"` - User string `goptions:"-u, --user, description='Github repo user or organisation (required if $GITHUB_USER not set)'"` - Repo string `goptions:"-r, --repo, description='Github repo (required if $GITHUB_REPO not set)'"` - Tag string `goptions:"-t, --tag, description='Git tag to query (optional)'"` - JSON bool `goptions:"-j, --json, description='Emit info as JSON instead of text'"` + Token string `goptions:"-s, --security-token, description='Github token ($GITHUB_TOKEN if set). required if repo is private.'"` + User string `goptions:"-u, --user, description='Github repo user or organisation (required if $GITHUB_USER not set)'"` + Repo string `goptions:"-r, --repo, description='Github repo (required if $GITHUB_REPO not set)'"` + Tag string `goptions:"-t, --tag, description='Git tag to query (optional)'"` + JSON bool `goptions:"-j, --json, description='Emit info as JSON instead of text'"` + Markdown bool `goptions:"-m, --markdown, description='Emit info as human readable markdown changelog.md'"` + Prerelease bool `goptions:"-p, --pre-release, description='Include pre-releases in markdown output'"` } `goptions:"info"` }