semver.v1: azul3d.org/semver.v1 Index | Files

package semver

import "azul3d.org/semver.v1"

Package semver provides Semantic Versioning for Go packages.

For more information about semver please see:

http://semver.org/

This package allows for implementing semantic versioning of Go packages on a single GitHub user or organization under a custom domain, for example:

go get example.com/pkg.v1

Would contact the Go HTTP server (using this package) running at example.com which would redirect the request to clone the Git repository located at:

github.com/someuser/pkg @ branch/tag [v1][v1.N][v1.N.N]

Usage is pretty simple, first create a Handler with your configuration:

// Create a semver HTTP handler:
pkgHandler := &semver.Handler{
    Host: "example.com",
    Matcher: semver.GitHub("someuser"),
}

Then register a root ("/") HTTP handler:

http.HandleFunc("/", handler)

Inside of the root HTTP handler give the semver HTTP handler a chance to handle the request if it needs to:

func handler(w http.ResponseWriter, r *http.Request) {
    // Give our semver handler the ability to handle the request.
    status, err := pkgHandler.Handle(w, r)
    if err != nil {
        log.Println(err) // e.g. IO error
    }
    if status == semver.Handled {
        // The request was handled by our semver pkgHandler, we don't need
        // to do anything else.
        return
    }
    if status == semver.PkgPage {
        // Package page, redirect them to godoc.org documentation.
        tmp := *r.URL
        tmp.Scheme = "https"
        tmp.Host = "godoc.org"
        tmp.Path = path.Join(pkgHandler.Host, tmp.Path)
        http.Redirect(w, r, tmp.String(), http.StatusSeeOther)
        return
    }

    // It's not a package request -- do something else (e.g. render the
    // home page).
}

The package exposes a matcher only for GitHub. But others can be implemented outside the package as well for e.g. Google Code or privately hosted Git repositories.

Index

Package Files

doc.go github.go gitpktline.go gitrefs.go handle.go matcher.go types.go version.go

Variables

var (
    ErrNotPackageURL = errors.New("not a valid package URL")
)
var InvalidVersion = Version{
    Major: -1,
    Minor: -1,
    Patch: -1,
    Dev:   false,
}

InvalidVersion represents a completely invalid version.

type HTTPError Uses

type HTTPError struct {
    Status int
    // contains filtered or unexported fields
}

HTTPError represents a HTTP error generated by a Handler's Relate function.

type Handler Uses

type Handler struct {
    // The host of this application, e.g. "example.org".
    Host string

    // If set to true then HTTPS is not used by default when a request's URL
    // is missing a schema.
    NoSecure bool

    // The matcher used to resolve package URL's to their associated
    // repositories.
    Matcher

    // HTTP client to utilize for outgoing requests to Git servers, if nil then
    // http.DefaultClient is used.
    Client *http.Client
}

Handler implements a semantic versioning HTTP request handler.

func (*Handler) Handle Uses

func (h *Handler) Handle(w http.ResponseWriter, r *http.Request) (s Status, err error)

Handle asks this handler to handle the given HTTP request by writing the appropriate response to the HTTP response writer.

type Matcher Uses

type Matcher interface {
    // Match should match the given URL to an associated repository (e.g. a git
    // repository).
    //
    // If the given URL is not a valid package URL, which may be the case very
    // often, then a nil repo and err=ErrNotPackageURL must be returned.
    //
    // If any *HTTPError is returned, then that error string is sent to the
    // client and the error's HTTP status code is written, the request is
    // considered handled.
    //
    // If any other error is returned, the request is left unhandled and the
    // error is directly returned to the caller of the Handle method.
    Match(u *url.URL) (r *Repo, err error)
}

Matcher defines an object responsible for matching any given URL to an associated repository.

func GitHub Uses

func GitHub(user string) Matcher

GitHub returns a URL Matcher that operates on a single GitHub user or organization. For instance if the service was running at example.com and the user string was "bob", it would match URLS in the pattern of:

example.com/pkg.v3 → github.com/bob/pkg (branch/tag v3, v3.N, or v3.N.M)
example.com/folder/pkg.v3 → github.com/bob/folder-pkg (branch/tag v3, v3.N, or v3.N.M)
example.com/multi/folder/pkg.v3 → github.com/bob/multi-folder-pkg (branch/tag v3, v3.N, or v3.N.M)
example.com/folder/pkg.v3/subpkg → github.com/bob/folder-pkg (branch/tag v3, v3.N, or v3.N.M)
example.com/pkg.v3/folder/subpkg → github.com/bob/pkg (branch/tag v3, v3.N, or v3.N.M)
example.com/pkg.v3-dev → github.com/bob/pkg (branch/tag v3-dev, v3.N-dev, or v3.N.M-dev)

type MatcherFunc Uses

type MatcherFunc func(u *url.URL) (r *Repo, err error)

MatcherFunc implements the Matcher interface by simply invoking the function.

func (MatcherFunc) Match Uses

func (m MatcherFunc) Match(u *url.URL) (r *Repo, err error)

Match simply invokes the function, m.

type Repo Uses

type Repo struct {
    Version

    // The root URL of the repository (excluding subpackages). For example a
    // package imported at:
    //
    //  https://example.com/pkg/subpkg
    //
    // Would have a root repository URL without "/subpkg":
    //
    //  https://github.com/example/pkg
    //
    // As that is where *the repository* lives; not the Go package itself.
    *url.URL

    // The subpath of the repository. It is joined with the repository root URL
    // in order to build the final package path. SubPath == "subpkg" in the
    // above example:
    //
    //  Repo.URL.String + repo.SubPath == "https://example.com/pkg/subpkg"
    //
    SubPath string
}

Repo defines a single repository and target version.

type Status Uses

type Status int

Status represents a single status code returned by a Handler's attempt to Handle any given request.

const (
    // The request was not handled.
    Unhandled Status = iota

    // The request was handled.
    Handled

    // The request was not handled, but was for the package page (e.g. when
    // viewing in a web browser).
    PkgPage
)

type Version Uses

type Version struct {
    Major, Minor, Patch int

    // If true, then this is the in-development version.
    Dev bool
}

Version represents a semantic version.

func ParseVersion Uses

func ParseVersion(vs string) Version

ParseVersion parses a version string in the form of:

"v1"
"v1.2"
"v1.2.1"
"v1-dev"
"v1.2-dev"
"v1.2.1-dev"

It returns InvalidVersion for strings not suffixed with "v", like:

"1"
"1.2-dev"

func (Version) Less Uses

func (v Version) Less(other Version) bool

Less tells if v is a lesser version than the other version.

It follows semver specification (e.g. v1.200.300 is less than v2). A dev version is *always* less than a non-dev version (e.g. v3-dev is less than v2).

func (Version) String Uses

func (v Version) String() string

String returns a string representation of this version, for example:

Version{Major=1, Minor=2, Patch=3}           -> "v1.2.3"
Version{Major=1, Minor=2, Patch=3, Dev=true} -> "v1.2.3-dev"

Version{Major=1, Minor=2, Patch=-1}           -> "v1.2"
Version{Major=1, Minor=2, Patch=-1, Dev=true} -> "v1.2-dev"

Version{Major=1, Minor=-1, Patch=-1}           -> "v1"
Version{Major=1, Minor=-1, Patch=-1, Dev=true} -> "v1-dev"

Package semver imports 13 packages (graph). Updated 2016-07-24. Refresh now. Tools for package owners.