From 9993ee600c84cf77d3a0c634e8fa83c2580e137f Mon Sep 17 00:00:00 2001 From: axetroy Date: Mon, 23 Nov 2020 17:29:00 +0800 Subject: [PATCH] fix: improve ssh git url parser --- 4_generator/generate.go | 25 +++- CHANGELOG.md | 54 +++++++ go.mod | 1 + go.sum | 2 + vendor/github.com/whilp/git-urls/.travis.yml | 7 + vendor/github.com/whilp/git-urls/LICENSE | 21 +++ vendor/github.com/whilp/git-urls/Makefile | 16 ++ vendor/github.com/whilp/git-urls/README.md | 3 + vendor/github.com/whilp/git-urls/go.mod | 3 + vendor/github.com/whilp/git-urls/urls.go | 150 +++++++++++++++++++ vendor/modules.txt | 3 + 11 files changed, 281 insertions(+), 4 deletions(-) create mode 100644 CHANGELOG.md create mode 100644 vendor/github.com/whilp/git-urls/.travis.yml create mode 100644 vendor/github.com/whilp/git-urls/LICENSE create mode 100644 vendor/github.com/whilp/git-urls/Makefile create mode 100644 vendor/github.com/whilp/git-urls/README.md create mode 100644 vendor/github.com/whilp/git-urls/go.mod create mode 100644 vendor/github.com/whilp/git-urls/urls.go diff --git a/4_generator/generate.go b/4_generator/generate.go index 7b847e3a..cd1d2638 100644 --- a/4_generator/generate.go +++ b/4_generator/generate.go @@ -14,6 +14,7 @@ import ( transformer "github.com/axetroy/changelog/3_transformer" "github.com/axetroy/changelog/internal/client" "github.com/pkg/errors" + giturls "github.com/whilp/git-urls" ) func Generate(g *client.GitClient, contexts []*transformer.TemplateContext, format string, preset string, templateFile string) ([]byte, error) { @@ -27,12 +28,28 @@ func Generate(g *client.GitClient, contexts []*transformer.TemplateContext, form if remote != nil || len(remote.URLs) > 0 { for _, urlStr := range remote.URLs { - // prefer github and gitlab - if strings.HasPrefix(urlStr, "https://github.com") || strings.HasPrefix(urlStr, "https://gitlab.com") { - if remoteURL, err = url.Parse(urlStr); err != nil { + if remoteURL, err = giturls.Parse(urlStr); err != nil { + return nil, errors.WithStack(err) + } else { + if remoteURL.Host == "github.com" || remoteURL.Host == "gitlab.com" { + break + } + } + } + + if remoteURL != nil { + urlPath := strings.TrimSuffix(remoteURL.Path, ".git") + switch remoteURL.Scheme { + case "http": + fallthrough + case "https": + if remoteURL, err = url.Parse(fmt.Sprintf("%s://%s/%s", remoteURL.Scheme, remoteURL.Host, urlPath)); err != nil { + return nil, errors.WithStack(err) + } + case "ssh": + if remoteURL, err = url.Parse(fmt.Sprintf("https://%s/%s", remoteURL.Host, urlPath)); err != nil { return nil, errors.WithStack(err) } - break } } } diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..d83a1b5c --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,54 @@ +Unreleased +========== + +### New feature: + +- link commit for generation([b9432db](https://github.com/axetroy/changelog/commit/b9432db1d1f5afe170296b9e0bfebee1aa62fabb)) (thanks @axetroy) +- add full preset template([7553570](https://github.com/axetroy/changelog/commit/7553570590b571bd33e10a4f80ec5639d0613042)) (thanks @axetroy) +- support changelog for git submodule([ec6a957](https://github.com/axetroy/changelog/commit/ec6a957752fbca9faa261d8694826779e2cbec1f)) (thanks @axetroy) +- add writer step([441ad13](https://github.com/axetroy/changelog/commit/441ad1322b1fecaca89a170ecebaf2955a77d630)) (thanks @axetroy) +- add formatter for markdown output([8c177e0](https://github.com/axetroy/changelog/commit/8c177e032e8bdb1b76d135981ea10e7053f3ef34)) (thanks @axetroy) +- add --file flag to generate file([0e4fb09](https://github.com/axetroy/changelog/commit/0e4fb09789732fec5b09b247e208d61794c3da0d)) (thanks @axetroy) +- support custom tmeplate and preset([3aa0aee](https://github.com/axetroy/changelog/commit/3aa0aee2584036da1c63dea9bb399cb83b48a8db)) (thanks @axetroy) +- support tag ranges([3d14c9c](https://github.com/axetroy/changelog/commit/3d14c9cf2dc7d51e348fddc7764d8aba1691fac9)) (thanks @axetroy) +- support version range. eg v2.0.0~v1.0.0([a65a4a8](https://github.com/axetroy/changelog/commit/a65a4a8bd0122e41c7b20c98676e9def76e786d3)) (thanks @axetroy) +- parse commit message and generate to template([7f67e78](https://github.com/axetroy/changelog/commit/7f67e783926fed647d2ad5414f31448eea106fc3)) (thanks @axetroy) + +### Bugs fixed: + +- commit range not include commit of tag([f8df0ba](https://github.com/axetroy/changelog/commit/f8df0ba654c8faf67eccf98262cd55807e53e597)) (thanks @axetroy) +- unescape template([e118cbf](https://github.com/axetroy/changelog/commit/e118cbfafd201b945848f15303fdb261e251f058)) (thanks @axetroy) +- if empty argument for command line([9c79fd9](https://github.com/axetroy/changelog/commit/9c79fd91bbf88f7861b4aca89ced8384cf2b9bcd)) (thanks @axetroy) +- **ci**: remove unsued code([66bcf8f](https://github.com/axetroy/changelog/commit/66bcf8f43db85409e0392c93f2e347ed91699e81)) (thanks @axetroy) + +### Commits(29): + +- [b9432db](https://github.com/axetroy/changelog/commit/b9432db1d1f5afe170296b9e0bfebee1aa62fabb) feat: link commit for generation +- [7553570](https://github.com/axetroy/changelog/commit/7553570590b571bd33e10a4f80ec5639d0613042) feat: add full preset template +- [7068672](https://github.com/axetroy/changelog/commit/706867220fa9ca537855f359d3e04d0c3762b793) update readme +- [ec6a957](https://github.com/axetroy/changelog/commit/ec6a957752fbca9faa261d8694826779e2cbec1f) feat: support changelog for git submodule +- [f540d6f](https://github.com/axetroy/changelog/commit/f540d6f7123334dac558a37c6ac056fed1021cda) refactor: rename transform to transformer +- [441ad13](https://github.com/axetroy/changelog/commit/441ad1322b1fecaca89a170ecebaf2955a77d630) feat: add writer step +- [f8df0ba](https://github.com/axetroy/changelog/commit/f8df0ba654c8faf67eccf98262cd55807e53e597) fix: commit range not include commit of tag +- [8c177e0](https://github.com/axetroy/changelog/commit/8c177e032e8bdb1b76d135981ea10e7053f3ef34) feat: add formatter for markdown output +- [a47fe84](https://github.com/axetroy/changelog/commit/a47fe84d2141635d82c2dc49500bfc2a81c03535) docs: update how it works +- [0e4fb09](https://github.com/axetroy/changelog/commit/0e4fb09789732fec5b09b247e208d61794c3da0d) feat: add --file flag to generate file +- [3aa0aee](https://github.com/axetroy/changelog/commit/3aa0aee2584036da1c63dea9bb399cb83b48a8db) feat: support custom tmeplate and preset +- [e118cbf](https://github.com/axetroy/changelog/commit/e118cbfafd201b945848f15303fdb261e251f058) fix: unescape template +- [3d14c9c](https://github.com/axetroy/changelog/commit/3d14c9cf2dc7d51e348fddc7764d8aba1691fac9) feat: support tag ranges +- [44ce3cd](https://github.com/axetroy/changelog/commit/44ce3cd8d68b786a3aac6b5daba90e7f12b75200) docs: update readme +- [9c79fd9](https://github.com/axetroy/changelog/commit/9c79fd91bbf88f7861b4aca89ced8384cf2b9bcd) fix: if empty argument for command line +- [0b6ba0c](https://github.com/axetroy/changelog/commit/0b6ba0c3fc49139467025eaebbe16c158a0cce65) refactor: Refactor the software architecture to make it clearer and simpler +- [66bcf8f](https://github.com/axetroy/changelog/commit/66bcf8f43db85409e0392c93f2e347ed91699e81) fix(ci): remove unsued code +- [89fecf5](https://github.com/axetroy/changelog/commit/89fecf5588f1133f70a8aaf6db3488184ba2ceb2) refactor: remove unsued code +- [a65a4a8](https://github.com/axetroy/changelog/commit/a65a4a8bd0122e41c7b20c98676e9def76e786d3) feat: support version range. eg v2.0.0~v1.0.0 +- [6301c2f](https://github.com/axetroy/changelog/commit/6301c2f01d881ae861e6c4459a411a5f48c74ba0) update help information +- [770ed02](https://github.com/axetroy/changelog/commit/770ed02d43c4593ab9db8e71a9f93987812d97bc) update +- [585445d](https://github.com/axetroy/changelog/commit/585445d917d4cb74d80b1c385b446f7e09a1606c) cache tags +- [b47e49c](https://github.com/axetroy/changelog/commit/b47e49cf8efac3f5aba9df0149295694424beaf1) filter tag with semver version +- [7f67e78](https://github.com/axetroy/changelog/commit/7f67e783926fed647d2ad5414f31448eea106fc3) feat: parse commit message and generate to template +- [b907117](https://github.com/axetroy/changelog/commit/b907117bca3d6306955070b933361ecb0da0627e) update ci +- [ef5b38a](https://github.com/axetroy/changelog/commit/ef5b38ad50dd150cbdbeff031f6898d9d0aff35a) update ci linter version +- [dd55cc8](https://github.com/axetroy/changelog/commit/dd55cc85d6a3b9c482ba376fa862f20b6de11d5b) fix lint +- [26408cc](https://github.com/axetroy/changelog/commit/26408ccef0f6256ca70edda59e4ab1d1c15fca72) init +- [824d351](https://github.com/axetroy/changelog/commit/824d3511bf90e8fda3d1c7be679274d71ce73f52) Initial commit diff --git a/go.mod b/go.mod index 0b0c0ffb..a3d98449 100644 --- a/go.mod +++ b/go.mod @@ -10,4 +10,5 @@ require ( github.com/shurcooL/go v0.0.0-20200502201357-93f07166e636 // indirect github.com/shurcooL/markdownfmt v0.0.0-20191117054414-21fe95c248e9 github.com/stretchr/testify v1.4.0 + github.com/whilp/git-urls v1.0.0 ) diff --git a/go.sum b/go.sum index a060dc10..1b36fa0c 100644 --- a/go.sum +++ b/go.sum @@ -61,6 +61,8 @@ github.com/shurcooL/markdownfmt v0.0.0-20191117054414-21fe95c248e9/go.mod h1:wwC github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/whilp/git-urls v1.0.0 h1:95f6UMWN5FKW71ECsXRUd3FVYiXdrE7aX4NZKcPmIjU= +github.com/whilp/git-urls v1.0.0/go.mod h1:J16SAmobsqc3Qcy98brfl5f5+e0clUvg1krgwk/qCfE= github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70= github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= diff --git a/vendor/github.com/whilp/git-urls/.travis.yml b/vendor/github.com/whilp/git-urls/.travis.yml new file mode 100644 index 00000000..2f050db0 --- /dev/null +++ b/vendor/github.com/whilp/git-urls/.travis.yml @@ -0,0 +1,7 @@ +language: go + +go: + - 1.11 + +install: + - make deps install lint test diff --git a/vendor/github.com/whilp/git-urls/LICENSE b/vendor/github.com/whilp/git-urls/LICENSE new file mode 100644 index 00000000..2aa848db --- /dev/null +++ b/vendor/github.com/whilp/git-urls/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Will Maier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/whilp/git-urls/Makefile b/vendor/github.com/whilp/git-urls/Makefile new file mode 100644 index 00000000..7d6c569e --- /dev/null +++ b/vendor/github.com/whilp/git-urls/Makefile @@ -0,0 +1,16 @@ +default: test lint + +test: + go test -v ./... + go test -covermode=count -coverprofile=profile.cov . + +lint: + gometalinter ./... + +install: + go get -d -v ./... && go build -v ./... + gometalinter --install --update + +deps: + go get github.com/alecthomas/gometalinter + go get golang.org/x/tools/cmd/cover diff --git a/vendor/github.com/whilp/git-urls/README.md b/vendor/github.com/whilp/git-urls/README.md new file mode 100644 index 00000000..3acacc59 --- /dev/null +++ b/vendor/github.com/whilp/git-urls/README.md @@ -0,0 +1,3 @@ +# git-urls + +Docs: https://pkg.go.dev/github.com/whilp/git-urls?tab=overview diff --git a/vendor/github.com/whilp/git-urls/go.mod b/vendor/github.com/whilp/git-urls/go.mod new file mode 100644 index 00000000..59ec93f1 --- /dev/null +++ b/vendor/github.com/whilp/git-urls/go.mod @@ -0,0 +1,3 @@ +module github.com/whilp/git-urls + +go 1.13 diff --git a/vendor/github.com/whilp/git-urls/urls.go b/vendor/github.com/whilp/git-urls/urls.go new file mode 100644 index 00000000..02341030 --- /dev/null +++ b/vendor/github.com/whilp/git-urls/urls.go @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2014 Will Maier + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* +Package giturls parses Git URLs. + +These URLs include standard RFC 3986 URLs as well as special formats that +are specific to Git. Examples are provided in the Git documentation at +https://www.kernel.org/pub/software/scm/git/docs/git-clone.html. +*/ +package giturls + +import ( + "fmt" + "net/url" + "regexp" + "strings" +) + +var ( + // scpSyntax was modified from https://golang.org/src/cmd/go/vcs.go. + scpSyntax = regexp.MustCompile(`^([a-zA-Z0-9_]+@)?([a-zA-Z0-9._-]+):([a-zA-Z0-9./._-]+)(?:\?||$)(.*)$`) + + // Transports is a set of known Git URL schemes. + Transports = NewTransportSet( + "ssh", + "git", + "git+ssh", + "http", + "https", + "ftp", + "ftps", + "rsync", + "file", + ) +) + +// Parser converts a string into a URL. +type Parser func(string) (*url.URL, error) + +// Parse parses rawurl into a URL structure. Parse first attempts to +// find a standard URL with a valid Git transport as its scheme. If +// that cannot be found, it then attempts to find a SCP-like URL. And +// if that cannot be found, it assumes rawurl is a local path. If none +// of these rules apply, Parse returns an error. +func Parse(rawurl string) (u *url.URL, err error) { + parsers := []Parser{ + ParseTransport, + ParseScp, + ParseLocal, + } + + // Apply each parser in turn; if the parser succeeds, accept its + // result and return. + for _, p := range parsers { + u, err = p(rawurl) + if err == nil { + return u, err + } + } + + // It's unlikely that none of the parsers will succeed, since + // ParseLocal is very forgiving. + return new(url.URL), fmt.Errorf("failed to parse %q", rawurl) +} + +// ParseTransport parses rawurl into a URL object. Unless the URL's +// scheme is a known Git transport, ParseTransport returns an error. +func ParseTransport(rawurl string) (*url.URL, error) { + u, err := url.Parse(rawurl) + if err == nil && !Transports.Valid(u.Scheme) { + err = fmt.Errorf("scheme %q is not a valid transport", u.Scheme) + } + return u, err +} + +// ParseScp parses rawurl into a URL object. The rawurl must be +// an SCP-like URL, otherwise ParseScp returns an error. +func ParseScp(rawurl string) (*url.URL, error) { + match := scpSyntax.FindAllStringSubmatch(rawurl, -1) + if len(match) == 0 { + return nil, fmt.Errorf("no scp URL found in %q", rawurl) + } + m := match[0] + user := strings.TrimRight(m[1], "@") + var userinfo *url.Userinfo + if user != "" { + userinfo = url.User(user) + } + rawquery := "" + if len(m) > 3 { + rawquery = m[4] + } + return &url.URL{ + Scheme: "ssh", + User: userinfo, + Host: m[2], + Path: m[3], + RawQuery: rawquery, + }, nil +} + +// ParseLocal parses rawurl into a URL object with a "file" +// scheme. This will effectively never return an error. +func ParseLocal(rawurl string) (*url.URL, error) { + return &url.URL{ + Scheme: "file", + Host: "", + Path: rawurl, + }, nil +} + +// TransportSet represents a set of valid Git transport schemes. It +// maps these schemes to empty structs, providing a set-like +// interface. +type TransportSet struct { + Transports map[string]struct{} +} + +// NewTransportSet returns a TransportSet with the items keys mapped +// to empty struct values. +func NewTransportSet(items ...string) *TransportSet { + t := &TransportSet{ + Transports: map[string]struct{}{}, + } + for _, i := range items { + t.Transports[i] = struct{}{} + } + return t +} + +// Valid returns true if transport is a known Git URL scheme and false +// if not. +func (t *TransportSet) Valid(transport string) bool { + _, ok := t.Transports[transport] + return ok +} diff --git a/vendor/modules.txt b/vendor/modules.txt index e813eb4c..4238ae95 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -94,6 +94,9 @@ github.com/shurcooL/markdownfmt/markdown # github.com/stretchr/testify v1.4.0 ## explicit github.com/stretchr/testify/assert +# github.com/whilp/git-urls v1.0.0 +## explicit +github.com/whilp/git-urls # github.com/xanzy/ssh-agent v0.2.1 github.com/xanzy/ssh-agent # golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073