You've already forked go-semantic-release
feat(init): increase version depending on commit (angular format)
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -10,3 +10,5 @@
|
|||||||
|
|
||||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||||
*.out
|
*.out
|
||||||
|
.version
|
||||||
|
.vscode/settings.json
|
||||||
|
|||||||
14
README.md
14
README.md
@@ -1 +1,15 @@
|
|||||||
# go-semantic-release
|
# go-semantic-release
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
`go build ./cmd/go-semantic-release/`
|
||||||
|
|
||||||
|
## Run
|
||||||
|
|
||||||
|
Print the next version
|
||||||
|
|
||||||
|
`./go-semantic-release version next`
|
||||||
|
|
||||||
|
Set a version
|
||||||
|
|
||||||
|
`./go-semantic-release version set v1.1.1`
|
||||||
|
|||||||
112
cmd/go-semantic-release/main.go
Normal file
112
cmd/go-semantic-release/main.go
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/Nightapes/go-semantic-release/pkg/semanticrelease"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"gopkg.in/urfave/cli.v1" // imports as package "cli"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
app := cli.NewApp()
|
||||||
|
|
||||||
|
app.Flags = []cli.Flag{
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "loglevel",
|
||||||
|
Value: "error",
|
||||||
|
Usage: "Set loglevel 'LEVEL",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
app.Commands = []cli.Command{
|
||||||
|
{
|
||||||
|
Name: "version",
|
||||||
|
Aliases: []string{"v"},
|
||||||
|
Usage: "version commands",
|
||||||
|
Subcommands: []cli.Command{
|
||||||
|
{
|
||||||
|
Name: "set",
|
||||||
|
Usage: "set version `VERSION`",
|
||||||
|
Action: func(c *cli.Context) error {
|
||||||
|
setLoglevel(c.GlobalString("loglevel"))
|
||||||
|
path := c.String("path")
|
||||||
|
version := c.Args().First()
|
||||||
|
log.Infof("Version %s", version)
|
||||||
|
return semanticrelease.SetVersion(version, path)
|
||||||
|
},
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "config, c",
|
||||||
|
Value: "release-config.json",
|
||||||
|
Usage: "Load release configuration from `FILE`",
|
||||||
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "path, p",
|
||||||
|
Usage: "`PATH` to repro ",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "next",
|
||||||
|
Usage: "get next `VERSION` or the set one ",
|
||||||
|
Action: func(c *cli.Context) error {
|
||||||
|
setLoglevel(c.GlobalString("loglevel"))
|
||||||
|
path := c.String("path")
|
||||||
|
return semanticrelease.GetNextVersion(path)
|
||||||
|
},
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "config, c",
|
||||||
|
Value: "release-config.json",
|
||||||
|
Usage: "Load release configuration from `FILE`",
|
||||||
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "path, p",
|
||||||
|
Usage: "`PATH` to repro ",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "release",
|
||||||
|
Aliases: []string{},
|
||||||
|
Usage: "make release",
|
||||||
|
Action: func(c *cli.Context) error {
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "config, c",
|
||||||
|
Value: "release-config.json",
|
||||||
|
Usage: "Load release configuration from `FILE`",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "init",
|
||||||
|
Aliases: []string{},
|
||||||
|
Usage: "create config",
|
||||||
|
Action: func(c *cli.Context) error {
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
//gitutil.GetCommits(folder)
|
||||||
|
err := app.Run(os.Args)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func setLoglevel(level string) {
|
||||||
|
parsed, err := log.ParseLevel(level)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("Invalid loglevel %s", level)
|
||||||
|
} else {
|
||||||
|
log.SetLevel(parsed)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
13
go.mod
Normal file
13
go.mod
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
module github.com/Nightapes/go-semantic-release
|
||||||
|
|
||||||
|
go 1.12
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/Masterminds/semver v1.4.2
|
||||||
|
github.com/sirupsen/logrus v1.4.1
|
||||||
|
github.com/urfave/cli v1.20.0 // indirect
|
||||||
|
golang.org/x/tools v0.0.0-20190508150211-cf84161cff3f // indirect
|
||||||
|
gopkg.in/src-d/go-git.v4 v4.11.0
|
||||||
|
gopkg.in/urfave/cli.v1 v1.20.0
|
||||||
|
gopkg.in/yaml.v2 v2.2.2
|
||||||
|
)
|
||||||
78
go.sum
Normal file
78
go.sum
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
github.com/Masterminds/semver v1.4.2 h1:WBLTQ37jOCzSLtXNdoo8bNM8876KhNqOKvrlGITgsTc=
|
||||||
|
github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
||||||
|
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=
|
||||||
|
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
|
||||||
|
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||||
|
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/emirpasic/gods v1.9.0 h1:rUF4PuzEjMChMiNsVjdI+SyLu7rEqpQ5reNFnhC7oFo=
|
||||||
|
github.com/emirpasic/gods v1.9.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
|
||||||
|
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||||
|
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
||||||
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
|
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
||||||
|
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
||||||
|
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||||
|
github.com/kevinburke/ssh_config v0.0.0-20180830205328-81db2a75821e h1:RgQk53JHp/Cjunrr1WlsXSZpqXn+uREuHvUVcK82CV8=
|
||||||
|
github.com/kevinburke/ssh_config v0.0.0-20180830205328-81db2a75821e/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||||
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||||
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
|
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||||
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
|
github.com/kr/pty v1.1.1/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/mitchellh/go-homedir v1.0.0 h1:vKb8ShqSby24Yrqr/yDYkuFz8d0WUjys40rvnGC8aR0=
|
||||||
|
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||||
|
github.com/pelletier/go-buffruneio v0.2.0 h1:U4t4R6YkofJ5xHm3dJzuRpPZ0mr5MMCoAWooScCR7aA=
|
||||||
|
github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo=
|
||||||
|
github.com/pkg/errors v0.8.0/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/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
|
||||||
|
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||||
|
github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k=
|
||||||
|
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||||
|
github.com/src-d/gcfg v1.4.0 h1:xXbNR5AlLSA315x2UO+fTSSAXCDf+Ar38/6oyGbDKQ4=
|
||||||
|
github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI=
|
||||||
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||||
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
|
github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
|
||||||
|
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||||
|
github.com/xanzy/ssh-agent v0.2.0 h1:Adglfbi5p9Z0BmK2oKU9nTG+zKfniSfnaMYB+ULd+Ro=
|
||||||
|
github.com/xanzy/ssh-agent v0.2.0/go.mod h1:0NyE30eGUDliuLEHJgYte/zncp2zdTStcOnWhgSqHD8=
|
||||||
|
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793 h1:u+LnwYTOOW7Ukr/fppxEb1Nwz0AtPflrblfvUudpo+I=
|
||||||
|
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA=
|
||||||
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
|
||||||
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
|
||||||
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sys v0.0.0-20180903190138-2b024373dcd9 h1:lkiLiLBHGoH3XnqSLUIaBsilGMUjI+Uy2Xu2JLUtTas=
|
||||||
|
golang.org/x/sys v0.0.0-20180903190138-2b024373dcd9/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190508150211-cf84161cff3f h1:sjxqKRXfnzgJFg/igBXeLZoBVAKXuAAljgr+PcNr7u8=
|
||||||
|
golang.org/x/tools v0.0.0-20190508150211-cf84161cff3f/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/src-d/go-billy.v4 v4.2.1 h1:omN5CrMrMcQ+4I8bJ0wEhOBPanIRWzFC953IiXKdYzo=
|
||||||
|
gopkg.in/src-d/go-billy.v4 v4.2.1/go.mod h1:tm33zBoOwxjYHZIE+OV8bxTWFMJLrconzFMd38aARFk=
|
||||||
|
gopkg.in/src-d/go-git-fixtures.v3 v3.1.1 h1:XWW/s5W18RaJpmo1l0IYGqXKuJITWRFuA45iOf1dKJs=
|
||||||
|
gopkg.in/src-d/go-git-fixtures.v3 v3.1.1/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g=
|
||||||
|
gopkg.in/src-d/go-git.v4 v4.11.0 h1:cJwWgJ0DXifrNrXM6RGN1Y2yR60Rr1zQ9Q5DX5S9qgU=
|
||||||
|
gopkg.in/src-d/go-git.v4 v4.11.0/go.mod h1:Vtut8izDyrM8BUVQnzJ+YvmNcem2J89EmfZYCkLokZk=
|
||||||
|
gopkg.in/urfave/cli.v1 v1.20.0 h1:NdAVW6RYxDif9DhDHaAortIu956m2c0v+09AZBPTbE0=
|
||||||
|
gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0=
|
||||||
|
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
|
||||||
|
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||||
|
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||||
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
63
internal/analyzer/analyzer.go
Normal file
63
internal/analyzer/analyzer.go
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
package analyzer
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/Nightapes/go-semantic-release/internal/gitutil"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Analyzer struct {
|
||||||
|
CommitFormat string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Rules struct {
|
||||||
|
Tag string
|
||||||
|
Release string
|
||||||
|
}
|
||||||
|
|
||||||
|
type AnalyzeCommit interface {
|
||||||
|
Analyze(commit gitutil.Commit, tag string) (AnalyzedCommit, bool)
|
||||||
|
GetRules() []Rules
|
||||||
|
}
|
||||||
|
|
||||||
|
type AnalyzedCommit struct {
|
||||||
|
Commit gitutil.Commit
|
||||||
|
ParsedMessage string
|
||||||
|
Scope string
|
||||||
|
ParsedBreakingChangeMessage string
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(format string) *Analyzer {
|
||||||
|
return &Analyzer{
|
||||||
|
CommitFormat: format,
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Analyzer) Analyze(commits []gitutil.Commit) map[string][]AnalyzedCommit {
|
||||||
|
|
||||||
|
var commitAnalayzer AnalyzeCommit
|
||||||
|
switch a.CommitFormat {
|
||||||
|
case "angular":
|
||||||
|
log.Infof("analyze angular format")
|
||||||
|
commitAnalayzer = NewAngular()
|
||||||
|
}
|
||||||
|
|
||||||
|
analyzedCommits := make(map[string][]AnalyzedCommit)
|
||||||
|
analyzedCommits["major"] = make([]AnalyzedCommit, 0)
|
||||||
|
analyzedCommits["minor"] = make([]AnalyzedCommit, 0)
|
||||||
|
analyzedCommits["patch"] = make([]AnalyzedCommit, 0)
|
||||||
|
|
||||||
|
for _, commit := range commits {
|
||||||
|
for _, rule := range commitAnalayzer.GetRules() {
|
||||||
|
analyzedCommit, hasBreakingChange := commitAnalayzer.Analyze(commit, rule.Tag)
|
||||||
|
if hasBreakingChange {
|
||||||
|
analyzedCommits["major"] = append(analyzedCommits["major"], analyzedCommit)
|
||||||
|
} else {
|
||||||
|
analyzedCommits[rule.Release] = append(analyzedCommits[rule.Release], analyzedCommit)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return analyzedCommits
|
||||||
|
}
|
||||||
65
internal/analyzer/angular.go
Normal file
65
internal/analyzer/angular.go
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
package analyzer
|
||||||
|
|
||||||
|
import (
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/Nightapes/go-semantic-release/internal/gitutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Angular struct {
|
||||||
|
rules []Rules
|
||||||
|
regex string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAngular() *Angular {
|
||||||
|
return &Angular{
|
||||||
|
regex: `(TAG)(?:\((.*)\))?: (.*)`,
|
||||||
|
rules: []Rules{
|
||||||
|
{
|
||||||
|
Tag: "feat",
|
||||||
|
Release: "minor",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Tag: "fix",
|
||||||
|
Release: "patch",
|
||||||
|
}, {
|
||||||
|
Tag: "perf",
|
||||||
|
Release: "patch",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Angular) GetRules() []Rules {
|
||||||
|
return a.rules
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Angular) Analyze(commit gitutil.Commit, tag string) (AnalyzedCommit, bool) {
|
||||||
|
|
||||||
|
analyzed := AnalyzedCommit{
|
||||||
|
Commit: commit,
|
||||||
|
}
|
||||||
|
|
||||||
|
re := regexp.MustCompile(strings.Replace(a.regex, "TAG", tag, -1))
|
||||||
|
matches := re.FindAllStringSubmatch(commit.Message+" "+commit.Message, -1)
|
||||||
|
if len(matches) >= 1 {
|
||||||
|
if len(matches[0]) >= 3 {
|
||||||
|
analyzed.Scope = matches[0][2]
|
||||||
|
|
||||||
|
message := strings.Join(matches[0][3:], "")
|
||||||
|
splitted := strings.SplitN(message, "BREAKING CHANGE:", 1)
|
||||||
|
|
||||||
|
if len(splitted) == 1 {
|
||||||
|
analyzed.ParsedMessage = splitted[0]
|
||||||
|
return analyzed, false
|
||||||
|
}
|
||||||
|
analyzed.ParsedMessage = splitted[0]
|
||||||
|
analyzed.ParsedBreakingChangeMessage = splitted[1]
|
||||||
|
return analyzed, true
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return analyzed, false
|
||||||
|
|
||||||
|
}
|
||||||
140
internal/gitutil/gitutil.go
Normal file
140
internal/gitutil/gitutil.go
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
package gitutil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
|
||||||
|
"github.com/Masterminds/semver"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"gopkg.in/src-d/go-git.v4"
|
||||||
|
"gopkg.in/src-d/go-git.v4/plumbing/object"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Commit struct {
|
||||||
|
Message string
|
||||||
|
Author string
|
||||||
|
Hash string
|
||||||
|
}
|
||||||
|
|
||||||
|
type GitUtils struct {
|
||||||
|
Repository *git.Repository
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(folder string) (*GitUtils, error) {
|
||||||
|
r, err := git.PlainOpen(folder)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
utils := &GitUtils{
|
||||||
|
Repository: r,
|
||||||
|
}
|
||||||
|
return utils, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *GitUtils) GetHash() (string, error) {
|
||||||
|
ref, err := g.Repository.Head()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return ref.Hash().String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *GitUtils) GetBranch() (string, error) {
|
||||||
|
ref, err := g.Repository.Head()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !ref.Name().IsBranch() {
|
||||||
|
return "", fmt.Errorf("No branch found, found %s, please checkout a branch (git checkout <BRANCH>)", ref.Name().String())
|
||||||
|
}
|
||||||
|
|
||||||
|
return ref.Name().Short(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *GitUtils) GetLastVersion() (*semver.Version, string, error) {
|
||||||
|
|
||||||
|
log.Debugf("GetLastVersion")
|
||||||
|
|
||||||
|
tagObjects, err := g.Repository.TagObjects()
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
var tags []*semver.Version
|
||||||
|
|
||||||
|
err = tagObjects.ForEach(func(t *object.Tag) error {
|
||||||
|
v, err := semver.NewVersion(t.Name)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Debugf("Tag %s is not a valid version, skip", t.Name)
|
||||||
|
} else {
|
||||||
|
log.Debugf("Add tag %s", t.Name)
|
||||||
|
tags = append(tags, v)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Sort(sort.Reverse(semver.Collection(tags)))
|
||||||
|
|
||||||
|
if len(tags) == 0 {
|
||||||
|
log.Debugf("Found no tags")
|
||||||
|
return nil, "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("Found old version %s", tags[0].String())
|
||||||
|
|
||||||
|
tag, err := g.Repository.Tag(tags[0].Original())
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
tagObject, err := g.Repository.TagObject(tag.Hash())
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("Found old hash %s", tagObject.Target.String())
|
||||||
|
return tags[0], tagObject.Target.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *GitUtils) GetCommits(lastTagHash string) ([]Commit, error) {
|
||||||
|
|
||||||
|
log.Printf("Read head")
|
||||||
|
ref, err := g.Repository.Head()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
cIter, err := g.Repository.Log(&git.LogOptions{From: ref.Hash(), Order: git.LogOrderCommitterTime})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var commits []Commit
|
||||||
|
var foundEnd bool
|
||||||
|
|
||||||
|
err = cIter.ForEach(func(c *object.Commit) error {
|
||||||
|
if c.Hash.String() == lastTagHash {
|
||||||
|
log.Infof("%s == %s", c.Hash.String(), lastTagHash)
|
||||||
|
foundEnd = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if !foundEnd {
|
||||||
|
commit := Commit{
|
||||||
|
Message: c.Message,
|
||||||
|
Author: c.Committer.Name,
|
||||||
|
Hash: c.Hash.String(),
|
||||||
|
}
|
||||||
|
commits = append(commits, commit)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
return commits, nil
|
||||||
|
}
|
||||||
0
internal/sdk/sdk.go
Normal file
0
internal/sdk/sdk.go
Normal file
42
internal/storage/storage.go
Normal file
42
internal/storage/storage.go
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
package storage
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
|
||||||
|
"gopkg.in/yaml.v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
// VersionFileContent struct
|
||||||
|
type VersionFileContent struct {
|
||||||
|
Version string `yaml:"version"`
|
||||||
|
NextVersion string `yaml:"nextVersion"`
|
||||||
|
Commit string `yaml:"commit"`
|
||||||
|
Branch string `yaml:"branch"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write version into .version
|
||||||
|
func Write(versionFileContent VersionFileContent) error {
|
||||||
|
data, err := yaml.Marshal(&versionFileContent)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return ioutil.WriteFile(".version", data, 0644)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read version into .version
|
||||||
|
func Read() (*VersionFileContent, error) {
|
||||||
|
|
||||||
|
content, err := ioutil.ReadFile(".version")
|
||||||
|
if err != nil {
|
||||||
|
return &VersionFileContent{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var versionFileContent VersionFileContent
|
||||||
|
err = yaml.Unmarshal(content, &versionFileContent)
|
||||||
|
if err != nil {
|
||||||
|
return &VersionFileContent{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &versionFileContent, nil
|
||||||
|
}
|
||||||
114
pkg/semanticrelease/semantic-release.go
Normal file
114
pkg/semanticrelease/semantic-release.go
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
package semanticrelease
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/Masterminds/semver"
|
||||||
|
"github.com/Nightapes/go-semantic-release/internal/analyzer"
|
||||||
|
"github.com/Nightapes/go-semantic-release/internal/gitutil"
|
||||||
|
"github.com/Nightapes/go-semantic-release/internal/storage"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetNextVersion from .version or calculate new
|
||||||
|
func GetNextVersion(repro string) error {
|
||||||
|
util, err := gitutil.New(repro)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
hash, err := util.GetHash()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
content, err := storage.Read()
|
||||||
|
|
||||||
|
if err == nil && content.Commit == hash {
|
||||||
|
fmt.Printf(content.NextVersion)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("Mismatch git and version file %s - %s", content.Commit, hash)
|
||||||
|
|
||||||
|
lastVersion, lastVersionHash, err := util.GetLastVersion()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if lastVersion == nil {
|
||||||
|
defaultVersion, _ := semver.NewVersion("1.0.0")
|
||||||
|
SetVersion(defaultVersion.String(), repro)
|
||||||
|
fmt.Printf(defaultVersion.String())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
commits, err := util.GetCommits(lastVersionHash)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("Found %d commits till last release", len(commits))
|
||||||
|
|
||||||
|
a := analyzer.New("angular")
|
||||||
|
result := a.Analyze(commits)
|
||||||
|
|
||||||
|
var newVersion semver.Version
|
||||||
|
|
||||||
|
if len(result["major"]) > 0 {
|
||||||
|
newVersion = lastVersion.IncMajor()
|
||||||
|
return nil
|
||||||
|
} else if len(result["minor"]) > 0 {
|
||||||
|
newVersion = lastVersion.IncMinor()
|
||||||
|
} else if len(result["patch"]) > 0 {
|
||||||
|
newVersion = lastVersion.IncPatch()
|
||||||
|
}
|
||||||
|
|
||||||
|
SetVersion(newVersion.String(), repro)
|
||||||
|
fmt.Printf(newVersion.String())
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetVersion(version string, repro string) error {
|
||||||
|
|
||||||
|
util, err := gitutil.New(repro)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
newVersion, err := semver.NewVersion(version)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
hash, err := util.GetHash()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
branch, err := util.GetBranch()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
newVersionContent := storage.VersionFileContent{
|
||||||
|
Commit: hash,
|
||||||
|
NextVersion: newVersion.String(),
|
||||||
|
Branch: branch,
|
||||||
|
}
|
||||||
|
|
||||||
|
lastVersion, _, err := util.GetLastVersion()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if lastVersion != nil {
|
||||||
|
newVersionContent.Version = lastVersion.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
return storage.Write(newVersionContent)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Release() {
|
||||||
|
}
|
||||||
20
release-config.json
Normal file
20
release-config.json
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"commitFormat": "angular",
|
||||||
|
"branch": {
|
||||||
|
"master": "release",
|
||||||
|
"rc-*": "rc",
|
||||||
|
"beta-*": "beta",
|
||||||
|
"alpha-*": "alpha",
|
||||||
|
"*": "none"
|
||||||
|
},
|
||||||
|
"changelog": {
|
||||||
|
"print": "all/compact",
|
||||||
|
"template": ""
|
||||||
|
},
|
||||||
|
"github": {
|
||||||
|
"url": ""
|
||||||
|
},
|
||||||
|
"gitlab": {
|
||||||
|
"url": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user