Documentation ¶
Overview ¶
Package semver provides Semantic Versioning for Go packages.
For more information about semver please see:
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 ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrNotPackageURL is the error returned by matchers when the URL is not // a valid package import path URL. ErrNotPackageURL = errors.New("not a valid package URL") )
var InvalidVersion = Version{ Major: -1, Minor: -1, Patch: -1, Unstable: false, }
InvalidVersion represents a completely invalid version.
Functions ¶
This section is empty.
Types ¶
type HTTPError ¶
type HTTPError struct { Status int // contains filtered or unexported fields }
HTTPError represents a HTTP error generated by a Handler's Relate function.
type Handler ¶
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.
type Matcher ¶
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 ¶
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-unstable → github.com/bob/pkg (branch/tag v3-unstable, v3.N-unstable, or v3.N.M-unstable)
type MatcherFunc ¶
MatcherFunc implements the Matcher interface by simply invoking the function.
type Repo ¶
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 // GoSource is literally the go-source meta tag content string. See the PR // for information on the go-source meta tag: // // https://github.com/golang/gddo/pull/212#issue-50104435 // GoSource string }
Repo defines a single repository and target version.
type Status ¶
type Status int
Status represents a single status code returned by a Handler's attempt to Handle any given request.
const ( // Unhandled is a status return when the request was not handled at all. Unhandled Status = iota // Handled is the status returned when the request was handled completely. Handled // PkgPage is the status returned when the request was not handled, but was // for the package page (e.g. when viewing the package's import path in a // web browser). PkgPage )
type Version ¶
type Version struct {
Major, Minor, Patch int
// If true, then this is the unstable version.
Unstable bool
}
Version represents a semantic version.
func ParseVersion ¶
ParseVersion parses a version string in the form of:
"v1" "v1.2" "v1.2.1" "v1-unstable" "v1.2-unstable" "v1.2.1-unstable"
It returns InvalidVersion for strings not suffixed with "v", like:
"1" "1.2-unstable"
func (Version) Less ¶
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 unstable version is *always* less than a stable version (e.g. v3-unstable is less than v2).
func (Version) 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, Unstable=true} -> "v1.2.3-unstable" Version{Major=1, Minor=2, Patch=-1} -> "v1.2" Version{Major=1, Minor=2, Patch=-1, Unstable=true} -> "v1.2-unstable" Version{Major=1, Minor=-1, Patch=-1} -> "v1" Version{Major=1, Minor=-1, Patch=-1, Unstable=true} -> "v1-unstable"