From 950144945ff8470e56b63e1313fc44b6690e8d46 Mon Sep 17 00:00:00 2001 From: Nicolas Martin Date: Wed, 5 Feb 2020 15:41:40 +0100 Subject: [PATCH 01/18] Use glamour as markdown rendering backend for issue & pr previews glamour uses the CommonMark compliant Goldmark markdown parser instead of go-termd which is based on Blackfriday. --- command/issue.go | 12 ++++++++---- command/pr.go | 12 ++++++++---- go.mod | 3 ++- go.sum | 39 ++++++++++++++++++++------------------- utils/utils.go | 34 ++++++++-------------------------- 5 files changed, 46 insertions(+), 54 deletions(-) diff --git a/command/issue.go b/command/issue.go index b9987d0e5..ea35d9393 100644 --- a/command/issue.go +++ b/command/issue.go @@ -232,8 +232,7 @@ func issueView(cmd *cobra.Command, args []string) error { if preview { out := colorableOut(cmd) - printIssuePreview(out, issue) - return nil + return printIssuePreview(out, issue) } else { fmt.Fprintf(cmd.ErrOrStderr(), "Opening %s in your browser.\n", openURL) return utils.OpenInBrowser(openURL) @@ -241,7 +240,7 @@ func issueView(cmd *cobra.Command, args []string) error { } -func printIssuePreview(out io.Writer, issue *api.Issue) { +func printIssuePreview(out io.Writer, issue *api.Issue) error { coloredLabels := labelList(*issue) if coloredLabels != "" { coloredLabels = utils.Gray(fmt.Sprintf("(%s)", coloredLabels)) @@ -255,9 +254,14 @@ func printIssuePreview(out io.Writer, issue *api.Issue) { coloredLabels, ))) fmt.Fprintln(out) - fmt.Fprintln(out, utils.RenderMarkdown(issue.Body)) + md, err := utils.RenderMarkdown(issue.Body) + if err != nil { + return err + } + fmt.Fprintln(out, md) fmt.Fprintln(out) fmt.Fprintf(out, utils.Gray("View this issue on GitHub: %s\n"), issue.URL) + return nil } var issueURLRE = regexp.MustCompile(`^https://github\.com/([^/]+)/([^/]+)/issues/(\d+)`) diff --git a/command/pr.go b/command/pr.go index 624debac0..7676b09a7 100644 --- a/command/pr.go +++ b/command/pr.go @@ -303,15 +303,14 @@ func prView(cmd *cobra.Command, args []string) error { if preview { out := colorableOut(cmd) - printPrPreview(out, pr) - return nil + return printPrPreview(out, pr) } else { fmt.Fprintf(cmd.ErrOrStderr(), "Opening %s in your browser.\n", openURL) return utils.OpenInBrowser(openURL) } } -func printPrPreview(out io.Writer, pr *api.PullRequest) { +func printPrPreview(out io.Writer, pr *api.PullRequest) error { fmt.Fprintln(out, utils.Bold(pr.Title)) fmt.Fprintln(out, utils.Gray(fmt.Sprintf( "%s wants to merge %s into %s from %s", @@ -321,9 +320,14 @@ func printPrPreview(out io.Writer, pr *api.PullRequest) { pr.HeadRefName, ))) fmt.Fprintln(out) - fmt.Fprintln(out, utils.RenderMarkdown(pr.Body)) + md, err := utils.RenderMarkdown(pr.Body) + if err != nil { + return err + } + fmt.Fprintln(out, md) fmt.Fprintln(out) fmt.Fprintf(out, utils.Gray("View this pull request on GitHub: %s\n"), pr.URL) + return nil } var prURLRE = regexp.MustCompile(`^https://github\.com/([^/]+)/([^/]+)/pull/(\d+)`) diff --git a/go.mod b/go.mod index 106484546..8b3711e37 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.13 require ( github.com/AlecAivazis/survey/v2 v2.0.4 + github.com/charmbracelet/glamour v0.1.0 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 github.com/hashicorp/go-version v1.2.0 github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 @@ -13,7 +14,7 @@ require ( github.com/mitchellh/go-homedir v1.1.0 github.com/spf13/cobra v0.0.5 github.com/spf13/pflag v1.0.5 - github.com/vilmibm/go-termd v0.0.4 + github.com/stretchr/testify v1.4.0 // indirect golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5 gopkg.in/yaml.v3 v3.0.0-20191010095647-fc94e3f71652 ) diff --git a/go.sum b/go.sum index 79806902b..79cc2305e 100644 --- a/go.sum +++ b/go.sum @@ -9,8 +9,8 @@ github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61 github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38 h1:smF2tmSOzy2Mm+0dGI2AIUHY+w0BUc+4tn40djz7+6U= github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38/go.mod h1:r7bzyVFMNntcxPZXK3/+KdruV1H5KSlyVY0gc+NgInI= -github.com/alecthomas/chroma v0.6.8 h1:TW4JJaIdbAbMyUtGEd6BukFlOKYvVQz3vVhLBEUNwMU= -github.com/alecthomas/chroma v0.6.8/go.mod h1:o9ohftueRi7H5be3+Q2cQCNa/YnLBFUNx40ZJfGVFKA= +github.com/alecthomas/chroma v0.7.0 h1:z+0HgTUmkpRDRz0SRSdMaqOLfJV4F+N1FPDZUZIDUzw= +github.com/alecthomas/chroma v0.7.0/go.mod h1:1U/PfCsTALWWYHDnsIQkxEBM0+6LLe0v8+RSVMOwxeY= github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721 h1:JHZL0hZKJ1VENNfmXvHbgYlbUOvpzYzvy2aZU5gXVeo= github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721/go.mod h1:QO9JBoKquHd+jz9nshCh40fOfO+JzsoXy8qTHF68zU0= github.com/alecthomas/kong v0.1.17-0.20190424132513-439c674f7ae0/go.mod h1:+inYUSluD+p4L8KdviBSgzcqEjUQOfC5fQDRFuc36lI= @@ -19,8 +19,8 @@ github.com/alecthomas/kong-hcl v0.1.8-0.20190615233001-b21fea9723c8/go.mod h1:MR github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897 h1:p9Sln00KOTlrYkxI1zYWl1QLnEqAqEARBEYa8FQnQcY= github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59 h1:WWB576BN5zNSZc/M9d/10pqEx5VHNhaQ/yOVAkmj5Yo= -github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I= +github.com/charmbracelet/glamour v0.1.0 h1:BHCtc+YJjoBjNUnFKBtXyyM4Bp9u7L2kf49qV+/AGYw= +github.com/charmbracelet/glamour v0.1.0/go.mod h1:Z1C2JkVGBom/RYfoKcPBZ81lHMR3xp3W6OCLNWWEIMc= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= @@ -51,11 +51,12 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= 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.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 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/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/logrusorgru/aurora v0.0.0-20191116043053-66b7ad493a23 h1:Wp7NjqGKGN9te9N/rvXYRhlVcrulGdxnz8zadXWs7fc= +github.com/logrusorgru/aurora v0.0.0-20191116043053-66b7ad493a23/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= +github.com/lucasb-eyer/go-colorful v1.0.3 h1:QIbQXiugsb+q10B+MI+7DI1oQLdmnep86tWFlaaUAac= +github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= @@ -64,14 +65,20 @@ github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9 h1:d5US/mDsogSGW37IV293h//ZFaeajb69h+EHFsv2xGg= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= +github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54= +github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= 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/microcosm-cc/bluemonday v1.0.2 h1:5lPfLTTAvAbtS0VqT+94yOtFnGfUWYyx0+iToC3Os3s= +github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4= -github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/muesli/reflow v0.0.0-20191216070243-e5efeac4e302 h1:jOh3Kh03uOFkRPV3PI4Am5tqACv2aELgbPgr7YgNX00= +github.com/muesli/reflow v0.0.0-20191216070243-e5efeac4e302/go.mod h1:I9bWAt7QTg/que/qmUCJBGlj7wEq8OAFBjPNjc6xK4I= github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E= +github.com/olekukonko/tablewriter v0.0.4 h1:vHD/YYe1Wolo78koG299f7V/VAS08c6IpCLn+Ejf/w8= +github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= @@ -80,12 +87,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -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/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -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/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s= @@ -103,21 +106,19 @@ github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/tj/assert v0.0.0-20190920132354-ee03d75cd160 h1:NSWpaDaurcAJY7PkL8Xt0PhZE7qpvbZl5ljd8r6U0bI= -github.com/tj/assert v0.0.0-20190920132354-ee03d75cd160/go.mod h1:mZ9/Rh9oLWpLLDRpvE+3b7gP/C2YyLFYxNmcLnPTMe0= -github.com/tj/go-css v0.0.0-20191108133013-220a796d1705 h1:+UA89aFRjPMqdccHd9A0HLNCRDXIoElaDoW2C1V3TzA= -github.com/tj/go-css v0.0.0-20191108133013-220a796d1705/go.mod h1:e+JPLQ9wyQCgRnPenX2bo7MJoLphBHz5c1WUqaANSeA= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= -github.com/vilmibm/go-termd v0.0.4 h1:uCmDUZ3qZUblTN/D5Hvl+g1rTJj/HW746JQFWidqAyk= -github.com/vilmibm/go-termd v0.0.4/go.mod h1:ys+dRO6wlM3el0vPJmYBkhOPPozViBgDXHOEn1x5Vsc= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yuin/goldmark v1.1.19 h1:0s2/60x0XsFCXHeFut+F3azDVAAyIMyUfJRbRexiTYs= +github.com/yuin/goldmark v1.1.19/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9 h1:mKdxBk7AujPs8kU4m80U72y/zjbZ3UcXC7dClwKbUI0= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 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-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/utils/utils.go b/utils/utils.go index fbd7e84de..a3af92fcb 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -1,12 +1,12 @@ package utils import ( - "bytes" "fmt" + "strings" "time" + "github.com/charmbracelet/glamour" "github.com/cli/cli/pkg/browser" - md "github.com/vilmibm/go-termd" ) // OpenInBrowser opens the url in a web browser based on OS and $BROWSER environment variable @@ -18,32 +18,14 @@ func OpenInBrowser(url string) error { return PrepareCmd(browseCmd).Run() } -func normalizeNewlines(d []byte) []byte { - d = bytes.Replace(d, []byte("\r\n"), []byte("\n"), -1) - d = bytes.Replace(d, []byte("\r"), []byte("\n"), -1) - return d +func normalizeNewlines(s string) string { + s = strings.Replace(s, "\r\n", "\n", -1) + s = strings.Replace(s, "\r", "\n", -1) + return s } -func RenderMarkdown(text string) string { - textB := []byte(text) - textB = normalizeNewlines(textB) - mdCompiler := md.Compiler{ - Columns: 100, - SyntaxHighlighter: md.SyntaxTheme{ - "keyword": md.Style{Color: "#9196ed"}, - "comment": md.Style{ - Color: "#c0c0c2", - }, - "literal": md.Style{ - Color: "#aaedf7", - }, - "name": md.Style{ - Color: "#fe8eb5", - }, - }, - } - - return mdCompiler.Compile(string(textB)) +func RenderMarkdown(text string) (string, error) { + return glamour.Render(normalizeNewlines(text), "dark") } func Pluralize(num int, thing string) string { From 1b7009087e9e3d0565fbcca6f95488a1f84bfc86 Mon Sep 17 00:00:00 2001 From: Morten Linderud Date: Thu, 13 Feb 2020 11:14:39 +0100 Subject: [PATCH 02/18] [Makefile] Support reproducible builds It's bad form to embed timestamps in binaries as it prevents reproducible builds of the resulting binary. The Reproducible Builds project defines SOURCE_DATE_EPOCH to help reproduce binaries by allowing the date format to be overridden. This patch adds support for this for GNU and BSD date. Go 1.13 introduces `-trimpath` which strips build paths from all compiled binaries. This enables people to reproduce the distributed cli binary without having to recreate the build path. https://reproducible-builds.org/specs/source-date-epoch/ https://reproducible-builds.org/docs/build-path/ Signed-off-by: Morten Linderud --- Makefile | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index be2483cdc..3b8aba5ea 100644 --- a/Makefile +++ b/Makefile @@ -2,15 +2,21 @@ BUILD_FILES = $(shell go list -f '{{range .GoFiles}}{{$$.Dir}}/{{.}}\ {{end}}' ./...) GH_VERSION ?= $(shell git describe --tags 2>/dev/null || git rev-parse --short HEAD) +DATE_FMT = +%Y-%m-%d +ifdef SOURCE_DATE_EPOCH + BUILD_DATE ?= $(shell date -u -d "@$(SOURCE_DATE_EPOCH)" "$(DATE_FMT)" 2>/dev/null || date -u -r "$(SOURCE_DATE_EPOCH)" "$(DATE_FMT)" 2>/dev/null || date -u "$(DATE_FMT)") +else + BUILD_DATE ?= $(shell date "$(DATE_FMT)") +endif LDFLAGS := -X github.com/cli/cli/command.Version=$(GH_VERSION) $(LDFLAGS) -LDFLAGS := -X github.com/cli/cli/command.BuildDate=$(shell date +%Y-%m-%d) $(LDFLAGS) +LDFLAGS := -X github.com/cli/cli/command.BuildDate=$(BUILD_DATE) $(LDFLAGS) ifdef GH_OAUTH_CLIENT_SECRET LDFLAGS := -X github.com/cli/cli/context.oauthClientID=$(GH_OAUTH_CLIENT_ID) $(LDFLAGS) LDFLAGS := -X github.com/cli/cli/context.oauthClientSecret=$(GH_OAUTH_CLIENT_SECRET) $(LDFLAGS) endif bin/gh: $(BUILD_FILES) - @go build -ldflags "$(LDFLAGS)" -o "$@" ./cmd/gh + @go build -trimpath -ldflags "$(LDFLAGS)" -o "$@" ./cmd/gh test: go test ./... From 5c8dd70bb7e00d613e36ec255869e8790fd03e78 Mon Sep 17 00:00:00 2001 From: TaKO8Ki Date: Sat, 15 Feb 2020 23:20:15 +0900 Subject: [PATCH 03/18] fix typo --- update/update.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/update/update.go b/update/update.go index 42eb5955f..5a96bed56 100644 --- a/update/update.go +++ b/update/update.go @@ -21,7 +21,7 @@ type StateEntry struct { LatestRelease ReleaseInfo `yaml:"latest_release"` } -// CheckForUpdate checks whether this software has had a newer relase on GitHub +// CheckForUpdate checks whether this software has had a newer release on GitHub func CheckForUpdate(client *api.Client, stateFilePath, repo, currentVersion string) (*ReleaseInfo, error) { latestRelease, err := getLatestReleaseInfo(client, stateFilePath, repo, currentVersion) if err != nil { From 71b1c492274d10aef975a283499a31b478a38df2 Mon Sep 17 00:00:00 2001 From: Gary Ewan Park Date: Sat, 15 Feb 2020 15:19:24 +0000 Subject: [PATCH 04/18] (doc) Update Windows installation options To include installing/upgrading from Chocolatey --- README.md | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 01e367902..34374d6f0 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,9 @@ Upgrade: `brew update && brew upgrade gh` ### Windows -`gh` is available via [scoop][]: +`gh` is available via [scoop][], [Chocolatey][], and as signed MSI's: + +#### scoop Install: @@ -55,6 +57,22 @@ scoop install gh Upgrade: `scoop update gh` +#### Chocolatey + +Install: + +``` +choco install gh +``` + +Upgrade: + +``` +choco upgrade gh +``` + +#### Signed MSI + Signed MSI installers are also available on the [releases page][]. ### Debian/Ubuntu Linux @@ -87,6 +105,7 @@ Install a prebuilt binary from the [releases page][] [docs]: https://cli.github.com/manual [scoop]: https://scoop.sh +[Chocolatey]: https://chocolatey.org [releases page]: https://github.com/cli/cli/releases/latest [hub]: https://github.com/github/hub [contributing page]: https://github.com/cli/cli/blob/master/.github/CONTRIBUTING.md From 3075af84d97bf0b1b78afcc0dd994a008eabd0bb Mon Sep 17 00:00:00 2001 From: Emerson Castaneda Date: Sat, 15 Feb 2020 16:08:54 -0500 Subject: [PATCH 05/18] Add Go ver. note for installing from source --- source.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source.md b/source.md index da27f29fe..3e13f002f 100644 --- a/source.md +++ b/source.md @@ -10,6 +10,8 @@ $ git clone https://github.com/cli/cli.git ~/.githubcli $ cd ~/.githubcli && make ``` +_Note: it requires Go 1.13+_ + 3. Add `~/.githubcli/bin` to your $PATH for access to the gh command-line utility. * For **bash**: From b67bb5538345efc45627f1463e8096326aaf410f Mon Sep 17 00:00:00 2001 From: Dmitry Sharshakov Date: Sun, 16 Feb 2020 17:28:03 +0300 Subject: [PATCH 06/18] Correct typoes --- command/pr.go | 2 +- update/update.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/command/pr.go b/command/pr.go index d1cb7e5be..1e0c43aa3 100644 --- a/command/pr.go +++ b/command/pr.go @@ -193,7 +193,7 @@ func prList(cmd *cobra.Command, args []string) error { } if len(prs) == 0 { - colorErr := colorableErr(cmd) // Send to stderr because otherwise when piping this command it would seem like the "no open prs" message is acually a pr + colorErr := colorableErr(cmd) // Send to stderr because otherwise when piping this command it would seem like the "no open prs" message is actually a pr msg := "There are no open pull requests" userSetFlags := false diff --git a/update/update.go b/update/update.go index 42eb5955f..5a96bed56 100644 --- a/update/update.go +++ b/update/update.go @@ -21,7 +21,7 @@ type StateEntry struct { LatestRelease ReleaseInfo `yaml:"latest_release"` } -// CheckForUpdate checks whether this software has had a newer relase on GitHub +// CheckForUpdate checks whether this software has had a newer release on GitHub func CheckForUpdate(client *api.Client, stateFilePath, repo, currentVersion string) (*ReleaseInfo, error) { latestRelease, err := getLatestReleaseInfo(client, stateFilePath, repo, currentVersion) if err != nil { From 101fbc27e1c5a0953b5a9dc4695a298e11bd2966 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mislav=20Marohni=C4=87?= Date: Mon, 17 Feb 2020 10:37:14 +0100 Subject: [PATCH 07/18] Reword Windows install instructions --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 34374d6f0..04d00bd74 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ Upgrade: `brew update && brew upgrade gh` ### Windows -`gh` is available via [scoop][], [Chocolatey][], and as signed MSI's: +`gh` is available via [scoop][], [Chocolatey][], and as downloadable MSI. #### scoop @@ -73,7 +73,7 @@ choco upgrade gh #### Signed MSI -Signed MSI installers are also available on the [releases page][]. +MSI installers are available for download on the [releases page][]. ### Debian/Ubuntu Linux From 3138b3b2a634f29c55eb374e17f557fcfcbc0b7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mislav=20Marohni=C4=87?= Date: Mon, 17 Feb 2020 12:07:39 +0100 Subject: [PATCH 08/18] Update note about required Go version --- source.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source.md b/source.md index 3e13f002f..75d1e1c5a 100644 --- a/source.md +++ b/source.md @@ -1,5 +1,11 @@ # Installation from source +0. Verify that you have Go 1.13+ installed +``` +$ go version +go version go1.13.7 +``` + 1. Clone cli into `~/.githubcli` ``` $ git clone https://github.com/cli/cli.git ~/.githubcli @@ -10,8 +16,6 @@ $ git clone https://github.com/cli/cli.git ~/.githubcli $ cd ~/.githubcli && make ``` -_Note: it requires Go 1.13+_ - 3. Add `~/.githubcli/bin` to your $PATH for access to the gh command-line utility. * For **bash**: From 5f6fd35a99dd09b8fe0660589846209607af704e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mislav=20Marohni=C4=87?= Date: Mon, 17 Feb 2020 12:52:48 +0100 Subject: [PATCH 09/18] Enable CI for pull requests from forks --- .github/workflows/go.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 9800d2827..557f87049 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -1,5 +1,5 @@ name: Tests -on: [push] +on: [push, pull_request] jobs: build: strategy: From 69d859a47f7b6f664eb4fabf4b82c647a9b2fc26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mislav=20Marohni=C4=87?= Date: Mon, 17 Feb 2020 15:43:51 +0100 Subject: [PATCH 10/18] Add labels to issue template --- .github/ISSUE_TEMPLATE/bug_report.md | 3 +++ .github/ISSUE_TEMPLATE/submit-a-request.md | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 19e727fdf..16e5348f1 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,6 +1,9 @@ --- name: "\U0001F41B Bug report" about: Report a bug or unexpected behavior while using GitHub CLI +title: '' +labels: bug +assignees: '' --- diff --git a/.github/ISSUE_TEMPLATE/submit-a-request.md b/.github/ISSUE_TEMPLATE/submit-a-request.md index 585afa21e..4f66ac457 100644 --- a/.github/ISSUE_TEMPLATE/submit-a-request.md +++ b/.github/ISSUE_TEMPLATE/submit-a-request.md @@ -1,6 +1,9 @@ --- -name: "\U00002B50 Submit a request" +name: "⭐ Submit a request" about: Surface a feature or problem that you think should be solved +title: '' +labels: enhancement +assignees: '' --- From 103d62b309632aa33ca79934b811660188be133d Mon Sep 17 00:00:00 2001 From: Emerson Castaneda Date: Mon, 17 Feb 2020 21:28:51 -0500 Subject: [PATCH 11/18] Add manual-pages-are-automatically-generated clarification --- .github/CONTRIBUTING.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 381d4b0ce..e5ad39f5c 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -26,6 +26,8 @@ Contributions to this project are [released][legal] to the public under the [pro Please note that this project adheres to a [Contributor Code of Conduct][code-of-conduct]. By participating in this project you agree to abide by its terms. +We generate manual pages from source on every release! You do not need to submit PRs for those specifically; the docs will get updated if your PR gets accepted. + ## Resources - [How to Contribute to Open Source](https://opensource.guide/how-to-contribute/) From abfc4d3b1af3db4df4baad7cc10f5bd6986e4bb0 Mon Sep 17 00:00:00 2001 From: Joshua Schmid Date: Tue, 18 Feb 2020 08:53:37 +0100 Subject: [PATCH 12/18] Add openSUSE/SUSE install instructions to README --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 04d00bd74..c98b207d0 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,13 @@ Install and upgrade: 1. Download the `.rpm` file from the [releases page][] 2. `sudo yum localinstall gh_*_linux_amd64.rpm` install the downloaded file +### openSUSE/SUSE Linux + +Install and upgrade: + +1. Download the `.rpm` file from the [releases page][] +2. `sudo zypper in gh_*_linux_amd64.rpm` install the downloaded file + ### Arch Linux Arch Linux users can install from the AUR: https://aur.archlinux.org/packages/github-cli/ From de6e99aa75c0d2684f93d4d3c5fa9a8d529db75a Mon Sep 17 00:00:00 2001 From: Colin Arnott Date: Tue, 18 Feb 2020 07:55:16 +0000 Subject: [PATCH 13/18] command: default to toolchain version Since the Go toolchain is able to extract the module version at build time, we should use that as a default instead of DEV. This means customers installing via go-get will get the correct version. Unfortunately, the toolchain does not store when the build occurs, so BuildTime now defaults to the empty string. It is still set if build officially, just not for go-get. --- command/root.go | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/command/root.go b/command/root.go index 0864bfca7..21b26778b 100644 --- a/command/root.go +++ b/command/root.go @@ -5,6 +5,7 @@ import ( "io" "os" "regexp" + "runtime/debug" "strings" "github.com/cli/cli/api" @@ -15,16 +16,26 @@ import ( "github.com/spf13/cobra" ) -// Version is dynamically set at build time in the Makefile -var Version = "DEV" +// Version is dynamically set by the toolchain or overriden by the Makefile. +var Version = func(info *debug.BuildInfo, ok bool) string { + if !ok { + return "(devel)" + } + return info.Main.Version +}(debug.ReadBuildInfo()) -// BuildDate is dynamically set at build time in the Makefile -var BuildDate = "YYYY-MM-DD" +// BuildDate is dynamically set at build time in the Makefile. +var BuildDate = "" // YYYY-MM-DD var versionOutput = "" func init() { - RootCmd.Version = fmt.Sprintf("%s (%s)", strings.TrimPrefix(Version, "v"), BuildDate) + Version = strings.TrimPrefix(info.Main.Version, "v") + if BuildDate == "" { + RootCmd.Version = Version + } else { + RootCmd.Version = fmt.Sprintf("%s (%s)", Version, BuildDate) + } versionOutput = fmt.Sprintf("gh version %s\n%s\n", RootCmd.Version, changelogURL(Version)) RootCmd.AddCommand(versionCmd) RootCmd.SetVersionTemplate(versionOutput) From 408b565fd96064876b1107b0dfc34d054a5c170b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mislav=20Marohni=C4=87?= Date: Tue, 18 Feb 2020 13:47:57 +0100 Subject: [PATCH 14/18] Allow setting version via ldflags again --- command/root.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/command/root.go b/command/root.go index 21b26778b..4f9d5ba09 100644 --- a/command/root.go +++ b/command/root.go @@ -17,12 +17,7 @@ import ( ) // Version is dynamically set by the toolchain or overriden by the Makefile. -var Version = func(info *debug.BuildInfo, ok bool) string { - if !ok { - return "(devel)" - } - return info.Main.Version -}(debug.ReadBuildInfo()) +var Version = "DEV" // BuildDate is dynamically set at build time in the Makefile. var BuildDate = "" // YYYY-MM-DD @@ -30,7 +25,12 @@ var BuildDate = "" // YYYY-MM-DD var versionOutput = "" func init() { - Version = strings.TrimPrefix(info.Main.Version, "v") + if Version == "DEV" { + if info, ok := debug.ReadBuildInfo(); ok && info.Main.Version != "(devel)" { + Version = info.Main.Version + } + } + Version = strings.TrimPrefix(Version, "v") if BuildDate == "" { RootCmd.Version = Version } else { From 213f4a5333c21020da030012979bd326a34fb28c Mon Sep 17 00:00:00 2001 From: Colin Arnott Date: Tue, 18 Feb 2020 08:00:18 +0000 Subject: [PATCH 15/18] context: use the real oauth credentials It is trivial to extract this information from the released artefacts, thus there is no security benefit to the safe/development credentials. This approach also prevents users from using go-get to install. As proof of concept, and to enable go-get, this change embeds the GitHub CLI credentials, instead of GitHub CLI (dev). --- context/config_setup.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/context/config_setup.go b/context/config_setup.go index 4d91a4c62..4236a81d9 100644 --- a/context/config_setup.go +++ b/context/config_setup.go @@ -18,10 +18,8 @@ const ( ) var ( - // The GitHub app that is meant for development - oauthClientID = "4d747ba5675d5d66553f" - // This value is safe to be embedded in version control - oauthClientSecret = "d4fee7b3f9c2ef4284a5ca7be0ee200cf15b6f8d" + oauthClientID = "178c6fc778ccc68e1d6a" + oauthClientSecret = "34ddeff2b558a23d38fba8a6de74f086ede1cc0b" ) // TODO: have a conversation about whether this belongs in the "context" package From 72bde685b06271e5bc4288ea034c91207d4d901f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mislav=20Marohni=C4=87?= Date: Tue, 18 Feb 2020 19:22:01 +0100 Subject: [PATCH 16/18] Add back comments explaining OAuth app credentials --- context/config_setup.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/context/config_setup.go b/context/config_setup.go index 4236a81d9..6cb8ddb6c 100644 --- a/context/config_setup.go +++ b/context/config_setup.go @@ -18,7 +18,9 @@ const ( ) var ( - oauthClientID = "178c6fc778ccc68e1d6a" + // The "GitHub CLI" OAuth app + oauthClientID = "178c6fc778ccc68e1d6a" + // This value is safe to be embedded in version control oauthClientSecret = "34ddeff2b558a23d38fba8a6de74f086ede1cc0b" ) From c32bcee4bb4216ad3c749d314e93add6b5863c2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mislav=20Marohni=C4=87?= Date: Tue, 18 Feb 2020 19:23:37 +0100 Subject: [PATCH 17/18] No need to configure production OAuth app on release anymore --- .github/workflows/releases.yml | 2 -- .goreleaser.yml | 2 -- 2 files changed, 4 deletions(-) diff --git a/.github/workflows/releases.yml b/.github/workflows/releases.yml index e8a3c0143..f241dc1d9 100644 --- a/.github/workflows/releases.yml +++ b/.github/workflows/releases.yml @@ -25,8 +25,6 @@ jobs: version: latest args: release --release-notes=CHANGELOG.md env: - GH_OAUTH_CLIENT_ID: 178c6fc778ccc68e1d6a - GH_OAUTH_CLIENT_SECRET: ${{secrets.OAUTH_CLIENT_SECRET}} GITHUB_TOKEN: ${{secrets.UPLOAD_GITHUB_TOKEN}} msi: needs: goreleaser diff --git a/.goreleaser.yml b/.goreleaser.yml index 1eb611313..619180def 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -13,8 +13,6 @@ builds: main: ./cmd/gh ldflags: - -s -w -X github.com/cli/cli/command.Version={{.Version}} -X github.com/cli/cli/command.BuildDate={{time "2006-01-02"}} - - -X github.com/cli/cli/context.oauthClientID={{.Env.GH_OAUTH_CLIENT_ID}} - - -X github.com/cli/cli/context.oauthClientSecret={{.Env.GH_OAUTH_CLIENT_SECRET}} - -X main.updaterEnabled=cli/cli id: macos goos: [darwin] From 61ff5d73bd899308f733e1d3b0168fd7df8e77ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mislav=20Marohni=C4=87?= Date: Tue, 18 Feb 2020 20:03:09 +0100 Subject: [PATCH 18/18] Fix crash in `issue/pr list` for narrow terminals If the available column width is smaller than 3, don't try to truncate with ellipsis (`...`). Instead, just truncate to available width. --- utils/table_printer.go | 5 ++++- utils/table_printer_test.go | 31 +++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 utils/table_printer_test.go diff --git a/utils/table_printer.go b/utils/table_printer.go index 649e246e1..e1bf9bc36 100644 --- a/utils/table_printer.go +++ b/utils/table_printer.go @@ -176,7 +176,10 @@ func (t *tsvTablePrinter) Render() error { func truncate(maxLength int, title string) string { if len(title) > maxLength { - return title[0:maxLength-3] + "..." + if maxLength > 3 { + return title[0:maxLength-3] + "..." + } + return title[0:maxLength] } return title } diff --git a/utils/table_printer_test.go b/utils/table_printer_test.go new file mode 100644 index 000000000..2e3e4e803 --- /dev/null +++ b/utils/table_printer_test.go @@ -0,0 +1,31 @@ +package utils + +import ( + "bytes" + "testing" +) + +func Test_ttyTablePrinter_truncate(t *testing.T) { + buf := bytes.Buffer{} + tp := &ttyTablePrinter{ + out: &buf, + maxWidth: 5, + } + + tp.AddField("1", nil, nil) + tp.AddField("hello", nil, nil) + tp.EndRow() + tp.AddField("2", nil, nil) + tp.AddField("world", nil, nil) + tp.EndRow() + + err := tp.Render() + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + expected := "1 he\n2 wo\n" + if buf.String() != expected { + t.Errorf("expected: %q, got: %q", expected, buf.String()) + } +}