summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Pointner <equinox@spreadspace.org>2017-05-19 21:18:43 +0200
committerChristian Pointner <equinox@spreadspace.org>2017-05-19 21:23:30 +0200
commit36ef789f056d9ba55810c0a21bc4560b13325e74 (patch)
tree1b029c8b9f524e2c5e2772f89313b148da5a07c3
parentfixed default config (diff)
upgraded to lates release
-rw-r--r--Dockerfile19
-rw-r--r--Makefile14
-rw-r--r--README.md11
-rw-r--r--debian/changelog7
-rw-r--r--debian/patches/allow-dashes-in-repository-names.patch13
-rw-r--r--debian/patches/series1
-rw-r--r--main.go146
-rw-r--r--refs_test.go8
-rw-r--r--vendor/vendor.json19
-rw-r--r--version.go27
-rw-r--r--version_test.go127
11 files changed, 160 insertions, 232 deletions
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..3db7251
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,19 @@
+FROM debian:jessie
+
+RUN apt-get update
+
+RUN apt-get install -y curl
+
+ENV VANITY_VERSION 0.1.3
+
+ENV VANITY_URL https://github.com/xiam/vanity/releases/download/v${VANITY_VERSION}/vanity_linux_amd64.gz
+
+RUN curl --silent -L ${VANITY_URL} | gzip -d > /bin/vanity
+
+RUN chmod +x /bin/vanity
+
+RUN mkdir -p /var/run/vanity
+
+EXPOSE 8080
+
+ENTRYPOINT ["/bin/vanity"]
diff --git a/Makefile b/Makefile
index 9cf51a6..b0db260 100644
--- a/Makefile
+++ b/Makefile
@@ -1,9 +1,11 @@
GOX_OSARCH ?= "darwin/amd64 linux/amd64 linux/arm freebsd/386 freebsd/amd64 linux/386 windows/386"
GOX_OUTPUT_DIR ?= bin
-GH_ACCESS_TOKEN ?= Missing access token.
+GH_ACCESS_TOKEN ?=
MESSAGE ?= Latest release.
-all: clean
+all: build
+
+build: clean
@mkdir -p $(GOX_OUTPUT_DIR) && \
gox -osarch=$(GOX_OSARCH) -output "$(GOX_OUTPUT_DIR)/{{.Dir}}_{{.OS}}_{{.Arch}}" && \
gzip bin/vanity_darwin_* && \
@@ -14,7 +16,10 @@ all: clean
require-version:
@if [[ -z "$$VERSION" ]]; then echo "Missing \$$VERSION"; exit 1; fi
-release: require-version
+require-access-token:
+ @if [[ -z "$(GH_ACCESS_TOKEN)" ]]; then echo "Missing \$$GH_ACCESS_TOKEN"; exit 1; fi
+
+release: require-version require-access-token build
@RESP=$$(curl --silent --data '{ \
"tag_name": "v$(VERSION)", \
"name": "v$(VERSION)", \
@@ -36,3 +41,6 @@ release: require-version
clean:
@rm -rf $(GOX_OUTPUT_DIR)
+
+docker:
+ docker build -t xiam/vanity .
diff --git a/README.md b/README.md
index 6f2f3a2..34aaaa2 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,7 @@
# vanity
-Use `vanity` to provide pretty package names using your own custom domain:
+Use `vanity` to provide pretty package import names using your own custom
+domain:
```go
import (
@@ -10,7 +11,7 @@ import (
## A simple example
-Let's see the available parameters:
+See the available `vanity` parameters with `-h`:
```
vanity -h
@@ -69,7 +70,7 @@ Hello, Go examples!
### Versioning support
`vanity` also comes with versioning support from the original
-[http://gopkg.in](http://gopkg.in) with no extra cost. For instance, the
+[http://gopkg.in](http://gopkg.in) at no extra cost. For instance, the
following import
```
@@ -154,8 +155,8 @@ curl "upper.io/db" -L
...
```
-You'll see some HTML gibberish made for humans, now request it again but this
-time using the `go-get=1` parameter (this is what `go get` does):
+You'll see some HTML gibberish made for human readers, now request it again but
+this time using the `go-get=1` parameter (that is what `go get` does):
```
curl "upper.io/db?go-get=1" -L
diff --git a/debian/changelog b/debian/changelog
index bd91542..7bbf8ed 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+vanity (0.2-1) unstable; urgency=medium
+
+ * new upstream release.
+ * drop all patches
+
+ -- Christian Pointner <equinox@spreadspace.org> Fri, 19 May 2017 21:17:47 +0200
+
vanity (0.1.1-5) unstable; urgency=medium
* fixed default config
diff --git a/debian/patches/allow-dashes-in-repository-names.patch b/debian/patches/allow-dashes-in-repository-names.patch
deleted file mode 100644
index 9fe5994..0000000
--- a/debian/patches/allow-dashes-in-repository-names.patch
+++ /dev/null
@@ -1,13 +0,0 @@
-This allows '-' for package names
-see: https://github.com/xiam/vanity/pull/6
---- a/main.go
-+++ b/main.go
-@@ -24,7 +24,7 @@
- repoRootFlag = flag.String("repo-root", "", "Git repository root URL (e.g.: https://github.com/upper).")
- )
-
--var packagePattern = regexp.MustCompile(`^/([a-zA-Z0-9]+)\.?(v[1-9][0-9]*)?(.*)$`)
-+var packagePattern = regexp.MustCompile(`^/([-a-zA-Z0-9]+)\.?(v[1-9][0-9]*)?(.*)$`)
-
- var httpClient = &http.Client{Timeout: 10 * time.Second}
-
diff --git a/debian/patches/series b/debian/patches/series
deleted file mode 100644
index f599fcd..0000000
--- a/debian/patches/series
+++ /dev/null
@@ -1 +0,0 @@
-allow-dashes-in-repository-names.patch
diff --git a/main.go b/main.go
index c935f13..2ee0255 100644
--- a/main.go
+++ b/main.go
@@ -15,6 +15,8 @@ import (
"strings"
"text/template"
"time"
+
+ "github.com/coreos/go-semver/semver"
)
var (
@@ -24,7 +26,7 @@ var (
repoRootFlag = flag.String("repo-root", "", "Git repository root URL (e.g.: https://github.com/upper).")
)
-var packagePattern = regexp.MustCompile(`^/([a-zA-Z0-9]+)\.?(v[1-9][0-9]*)?(.*)$`)
+var packagePattern = regexp.MustCompile(`^/([-a-zA-Z0-9]+)\.?(v([0-9]*))?(.*)$`)
var httpClient = &http.Client{Timeout: 10 * time.Second}
@@ -136,9 +138,8 @@ func NewRepoRoot(repoURL string, vanityURL string) (*RepoRoot, error) {
// NewRepo creates a new repository.
func (root *RepoRoot) NewRepo(name string) *Repo {
return &Repo{
- Root: root,
- Name: name,
- FullVersion: InvalidVersion,
+ Root: root,
+ Name: name,
}
}
@@ -146,25 +147,27 @@ func (root *RepoRoot) NewRepo(name string) *Repo {
type Repo struct {
Root *RepoRoot
- Name string
- MajorVersion Version
+ Name string
+ Major string
+
+ RequestedVersion semver.Version
// FullVersion is the best version in AllVersions that matches MajorVersion.
// It defaults to InvalidVersion if there are no matches.
- FullVersion Version
+ FullVersion *semver.Version
// AllVersions holds all versions currently available in the repository,
// either coming from branch names or from tag names. Version zero (v0)
// is only present in the list if it really exists in the repository.
- AllVersions VersionList
+ AllVersions semver.Versions
}
// SetVersions records in the relevant fields the details about which
// package versions are available in the repository.
-func (repo *Repo) SetVersions(all []Version) {
+func (repo *Repo) SetVersions(all semver.Versions) {
repo.AllVersions = all
for _, v := range repo.AllVersions {
- if v.Major == repo.MajorVersion.Major && v.Unstable == repo.MajorVersion.Unstable && repo.FullVersion.Less(v) {
+ if v.Major == repo.RequestedVersion.Major && (repo.FullVersion == nil || repo.FullVersion.LessThan(*v)) {
repo.FullVersion = v
}
}
@@ -182,7 +185,7 @@ func (repo *Repo) VanityRoot() string {
// GitTree returns the repository tree name for the selected version.
func (repo *Repo) GitTree() string {
- if repo.FullVersion == InvalidVersion {
+ if repo.FullVersion == nil || repo.Major == "" {
return "master"
}
return repo.FullVersion.String()
@@ -190,7 +193,10 @@ func (repo *Repo) GitTree() string {
// VanityPath returns the real package path, without a schema.
func (repo *Repo) VanityPath() string {
- return repo.VanityVersionRoot(repo.MajorVersion)
+ if repo.Major == "" {
+ return repo.VanityRoot()
+ }
+ return repo.VanityRoot() + ".v" + repo.Major
}
// VanityURL returns the vanity package's URL.
@@ -203,25 +209,12 @@ func (repo *Repo) RepoRootURL() string {
return repo.Root.repoURL.Scheme + "://" + repo.RepoRoot()
}
-// VanityVersionRoot returns the package's vanity root for the provided
-// version, without a schema.
-func (repo *Repo) VanityVersionRoot(version Version) string {
- version.Minor = -1
- version.Patch = -1
- v := version.String()
- if v == "v0" {
- return repo.VanityRoot()
- }
- return repo.VanityRoot() + "." + v
-}
-
func newHandler(repoRoot *RepoRoot) func(http.ResponseWriter, *http.Request) {
return func(resp http.ResponseWriter, req *http.Request) {
if req.URL.Path == "/health-check" {
resp.Write([]byte("ok"))
return
}
-
log.Printf("%s requested %s", req.RemoteAddr, req.URL)
if req.URL.Path == "/" {
@@ -237,28 +230,20 @@ func newHandler(repoRoot *RepoRoot) func(http.ResponseWriter, *http.Request) {
p := packagePattern.FindStringSubmatch(u.Path)
- pkgName := p[1]
- version := p[2]
- extra := p[3]
-
+ pkgName, _, version, extra := p[1], p[2], p[3], p[4]
repo := repoRoot.NewRepo(pkgName)
- if version == "" {
- version = "v0"
- }
-
- var ok bool
- repo.MajorVersion, ok = parseVersion(version)
- if !ok {
- sendNotFound(resp, "Version %q improperly considered invalid; please warn the service maintainers.", version)
- return
+ var requestedVersion semver.Version
+ if version != "" {
+ repo.Major = version
+ repo.RequestedVersion.Major, _ = strconv.ParseInt(repo.Major, 10, 64)
}
var changed []byte
- var versions VersionList
+ var versions semver.Versions
original, err := fetchRefs(repo)
if err == nil {
- changed, versions, err = changeRefs(original, repo.MajorVersion)
+ changed, versions, err = changeRefs(original, &repo.RequestedVersion)
repo.SetVersions(versions)
}
@@ -269,14 +254,7 @@ func newHandler(repoRoot *RepoRoot) func(http.ResponseWriter, *http.Request) {
sendNotFound(resp, "Git repository not found at https://%s", repo.RepoRoot())
return
case ErrNoVersion:
- major := repo.MajorVersion
- suffix := ""
- if major.Unstable {
- major.Unstable = false
- suffix = unstableSuffix
- }
- v := major.String()
- sendNotFound(resp, `Git repository at https://%s has no branch or tag "%s%s", "%s.N%s" or "%s.N.M%s"`, repo.RepoRoot(), v, suffix, v, suffix, v, suffix)
+ sendNotFound(resp, `Git repository at https://%s has no tag %v`, repo.RepoRoot(), requestedVersion)
return
default:
resp.WriteHeader(http.StatusBadGateway)
@@ -286,8 +264,41 @@ func newHandler(repoRoot *RepoRoot) func(http.ResponseWriter, *http.Request) {
switch extra {
case `/git-upload-pack`:
- resp.Header().Set("Location", "https://"+repo.RepoRoot()+"/git-upload-pack")
- resp.WriteHeader(http.StatusMovedPermanently)
+ proxyURL := "https://" + repo.RepoRoot() + "/git-upload-pack"
+
+ proxyReq, err := http.NewRequest(req.Method, proxyURL, req.Body)
+ if err != nil {
+ resp.WriteHeader(http.StatusInternalServerError)
+ return
+ }
+ for k, v := range req.Header {
+ proxyReq.Header[k] = v
+ }
+
+ proxyRes, err := http.DefaultClient.Do(proxyReq)
+ if err != nil {
+ log.Printf("Proxy: %v", err)
+ resp.WriteHeader(http.StatusServiceUnavailable)
+ return
+ }
+ defer proxyRes.Body.Close()
+
+ for k, v := range proxyRes.Header {
+ resp.Header()[k] = v
+ }
+
+ buf, err := ioutil.ReadAll(proxyRes.Body)
+ if err != nil {
+ log.Printf("Proxy: %v", err)
+ resp.WriteHeader(http.StatusBadGateway)
+ return
+ }
+
+ if _, err = resp.Write(buf); err != nil {
+ log.Printf("Proxy: %v", err)
+ resp.WriteHeader(http.StatusInternalServerError)
+ return
+ }
return
case `/info/refs`:
resp.Header().Set("Content-Type", "application/x-git-upload-pack-advertisement")
@@ -349,16 +360,16 @@ func fetchRefs(repo *Repo) (data []byte, err error) {
return data, err
}
-func changeRefs(data []byte, major Version) (changed []byte, versions VersionList, err error) {
+func changeRefs(data []byte, major *semver.Version) (changed []byte, versions semver.Versions, err error) {
var hlinei, hlinej int // HEAD reference line start/end
var mlinei, mlinej int // master reference line start/end
var vrefhash string
var vrefname string
- var vrefv = InvalidVersion
+ var vrefv *semver.Version
// Record all available versions, the locations of the master and HEAD lines,
// and details of the best reference satisfying the requested major version.
- versions = make([]Version, 0)
+ versions = semver.Versions{}
sdata := string(data)
for i, j := 0, 0; i < len(data); i = j {
size, err := strconv.ParseInt(sdata[i:i+4], 16, 32)
@@ -402,28 +413,25 @@ func changeRefs(data []byte, major Version) (changed []byte, versions VersionLis
mlinej = j
}
- if strings.HasPrefix(name, "refs/heads/v") || strings.HasPrefix(name, "refs/tags/v") {
- if strings.HasSuffix(name, "^{}") {
- // Annotated tag is peeled off and overrides the same version just parsed.
- name = name[:len(name)-3]
+ if strings.HasPrefix(name, "refs/tags/v") {
+ if !strings.HasSuffix(name, "^{}") {
+ continue // Only accept annotated tags.
}
- v, ok := parseVersion(name[strings.IndexByte(name, 'v'):])
- if ok && major.Contains(v) && (v == vrefv || !vrefv.IsValid() || vrefv.Less(v)) {
- vrefv = v
- vrefhash = sdata[hashi:hashj]
- vrefname = name
- }
- if ok {
+ // Annotated tag is peeled off and overrides the same version just parsed.
+ name = name[:len(name)-3]
+
+ v, err := semver.NewVersion(name[strings.IndexByte(name, 'v')+1:])
+ if err == nil {
versions = append(versions, v)
+ if major.Major == v.Major && (vrefv == nil || v == vrefv || vrefv.LessThan(*v)) {
+ vrefv = v
+ vrefhash = sdata[hashi:hashj]
+ vrefname = name
+ }
}
}
}
- // If v0 was requested, accept the master as-is.
- if major == (Version{0, -1, -1, false}) {
- return data, nil, nil
- }
-
// If the file has no HEAD line or the version was not found, report as unavailable.
if hlinei == 0 || vrefhash == "" {
return nil, nil, ErrNoVersion
diff --git a/refs_test.go b/refs_test.go
index 55580c5..cd02871 100644
--- a/refs_test.go
+++ b/refs_test.go
@@ -5,6 +5,8 @@ import (
"fmt"
. "gopkg.in/check.v1"
"sort"
+
+ "github.com/coreos/go-semver/semver"
)
var _ = Suite(&RefsSuite{})
@@ -173,9 +175,9 @@ func (s *RefsSuite) TestChangeRefs(c *C) {
for _, test := range refsTests {
c.Logf(test.summary)
- v, ok := parseVersion(test.version)
- if !ok {
- c.Fatalf("Test has an invalid version: %q", test.version)
+ v, err := semver.NewVersion(test.version)
+ if err != nil {
+ c.Fatalf("Test has an invalid version: %q: %v", test.version, err)
}
changed, versions, err := changeRefs([]byte(test.original), v)
diff --git a/vendor/vendor.json b/vendor/vendor.json
new file mode 100644
index 0000000..f9c8c4a
--- /dev/null
+++ b/vendor/vendor.json
@@ -0,0 +1,19 @@
+{
+ "comment": "",
+ "ignore": "test",
+ "package": [
+ {
+ "checksumSHA1": "butr+Orbf1fd1hcLqNXYwUDAjcI=",
+ "path": "github.com/coreos/go-semver/semver",
+ "revision": "8ab6407b697782a06568d4b7f1db25550ec2e4c6",
+ "revisionTime": "2016-07-13T22:46:27Z"
+ },
+ {
+ "checksumSHA1": "UD3Xnjdx6vWSFVmKUopMjuTwuz0=",
+ "path": "gopkg.in/check.v1",
+ "revision": "11d3bc7aa68e238947792f30573146a3231fc0f1",
+ "revisionTime": "2015-07-29T08:04:31Z"
+ }
+ ],
+ "rootPath": "github.com/xiam/vanity"
+}
diff --git a/version.go b/version.go
index 6fcb9c1..f2aaffd 100644
--- a/version.go
+++ b/version.go
@@ -70,34 +70,39 @@ func (v Version) Contains(other Version) bool {
// IsValid returns trus if the version is valid.
func (v Version) IsValid() bool {
- return v != InvalidVersion
+ return v != *InvalidVersion
}
-// InvalidVersion represents a version that can't be parsed.
-var InvalidVersion = Version{-1, -1, -1, false}
+var (
+ // InvalidVersion represents a version that can't be parsed.
+ InvalidVersion = &Version{-1, -1, -1, false}
-func parseVersion(s string) (v Version, ok bool) {
- v = InvalidVersion
+ // ZeroVersion represents the zero version.
+ ZeroVersion = &Version{0, 0, 0, false}
+)
+
+func parseVersion(s string) (*Version, bool) {
+ defaultVersion := *InvalidVersion
if len(s) < 2 {
- return
+ return &defaultVersion, false
}
if s[0] != 'v' {
- return
+ return &defaultVersion, false
}
- vout := InvalidVersion
+ vout := *InvalidVersion
unstable := false
i := 1
for _, vptr := range []*int{&vout.Major, &vout.Minor, &vout.Patch} {
*vptr, unstable, i = parseVersionPart(s, i)
if i < 0 {
- return
+ return &defaultVersion, false
}
if i == len(s) {
vout.Unstable = unstable
- return vout, true
+ return &vout, true
}
}
- return
+ return &defaultVersion, true
}
func parseVersionPart(s string, i int) (part int, unstable bool, newi int) {
diff --git a/version_test.go b/version_test.go
deleted file mode 100644
index 22774fd..0000000
--- a/version_test.go
+++ /dev/null
@@ -1,127 +0,0 @@
-package main
-
-import (
- "testing"
-
- . "gopkg.in/check.v1"
-)
-
-func Test(t *testing.T) { TestingT(t) }
-
-var _ = Suite(&VersionSuite{})
-
-type VersionSuite struct{}
-
-var versionParseTests = []struct {
- major int
- minor int
- patch int
- dev bool
- s string
-}{
- {-1, -1, -1, false, "v"},
- {-1, -1, -1, false, "v-1"},
- {-1, -1, -1, false, "v-deb"},
- {-1, -1, -1, false, "v01"},
- {-1, -1, -1, false, "v1.01"},
- {-1, -1, -1, false, "a1"},
- {-1, -1, -1, false, "v1a"},
- {-1, -1, -1, false, "v1..2"},
- {-1, -1, -1, false, "v1.2.3.4"},
- {-1, -1, -1, false, "v1."},
- {-1, -1, -1, false, "v1.2."},
- {-1, -1, -1, false, "v1.2.3."},
-
- {0, -1, -1, false, "v0"},
- {0, -1, -1, true, "v0-unstable"},
- {1, -1, -1, false, "v1"},
- {1, -1, -1, true, "v1-unstable"},
- {1, 2, -1, false, "v1.2"},
- {1, 2, -1, true, "v1.2-unstable"},
- {1, 2, 3, false, "v1.2.3"},
- {1, 2, 3, true, "v1.2.3-unstable"},
- {12, 34, 56, false, "v12.34.56"},
- {12, 34, 56, true, "v12.34.56-unstable"},
-}
-
-func (s *VersionSuite) TestParse(c *C) {
- for _, t := range versionParseTests {
- got, ok := parseVersion(t.s)
- if t.major == -1 {
- if ok || got != InvalidVersion {
- c.Fatalf("version %q is invalid but parsed as %#v", t.s, got)
- }
- } else {
- want := Version{t.major, t.minor, t.patch, t.dev}
- if got != want {
- c.Fatalf("version %q must parse as %#v, got %#v", t.s, want, got)
- }
- if got.String() != t.s {
- c.Fatalf("version %q got parsed as %#v and stringified as %q", t.s, got, got.String())
- }
- }
- }
-}
-
-var versionLessTests = []struct {
- oneMajor, oneMinor, onePatch int
- oneUnstable bool
- twoMajor, twoMinor, twoPatch int
- twoUnstable, less bool
-}{
- {0, 0, 0, false, 0, 0, 0, false, false},
- {1, 0, 0, false, 1, 0, 0, false, false},
- {1, 0, 0, false, 1, 1, 0, false, true},
- {1, 0, 0, false, 2, 0, 0, false, true},
- {0, 1, 0, false, 0, 1, 0, false, false},
- {0, 1, 0, false, 0, 1, 1, false, true},
- {0, 0, 0, false, 0, 2, 0, false, true},
- {0, 0, 1, false, 0, 0, 1, false, false},
- {0, 0, 1, false, 0, 0, 2, false, true},
-
- {0, 0, 0, false, 0, 0, 0, true, false},
- {0, 0, 0, true, 0, 0, 0, false, true},
- {0, 0, 1, true, 0, 0, 0, false, false},
-}
-
-func (s *VersionSuite) TestLess(c *C) {
- for _, t := range versionLessTests {
- one := Version{t.oneMajor, t.oneMinor, t.onePatch, t.oneUnstable}
- two := Version{t.twoMajor, t.twoMinor, t.twoPatch, t.twoUnstable}
- if one.Less(two) != t.less {
- c.Fatalf("version %s < %s returned %v", one, two, !t.less)
- }
- }
-}
-
-var versionContainsTests = []struct {
- oneMajor, oneMinor, onePatch int
- oneUnstable bool
- twoMajor, twoMinor, twoPatch int
- twoUnstable, contains bool
-}{
- {12, 34, 56, false, 12, 34, 56, false, true},
- {12, 34, 56, false, 12, 34, 78, false, false},
- {12, 34, -1, false, 12, 34, 56, false, true},
- {12, 34, -1, false, 12, 78, 56, false, false},
- {12, -1, -1, false, 12, 34, 56, false, true},
- {12, -1, -1, false, 78, 34, 56, false, false},
-
- {12, -1, -1, true, 12, -1, -1, false, false},
- {12, -1, -1, false, 12, -1, -1, true, false},
-}
-
-func (s *VersionSuite) TestContains(c *C) {
- for _, t := range versionContainsTests {
- one := Version{t.oneMajor, t.oneMinor, t.onePatch, t.oneUnstable}
- two := Version{t.twoMajor, t.twoMinor, t.twoPatch, t.twoUnstable}
- if one.Contains(two) != t.contains {
- c.Fatalf("version %s.Contains(%s) returned %v", one, two, !t.contains)
- }
- }
-}
-
-func (s *VersionSuite) TestIsValid(c *C) {
- c.Assert(InvalidVersion.IsValid(), Equals, false)
- c.Assert(Version{0, 0, 0, false}.IsValid(), Equals, true)
-}