vain/vain.go

113 lines
2.4 KiB
Go
Raw Normal View History

2016-02-11 11:57:16 -08:00
package vain
2016-02-07 23:54:55 -08:00
import (
"bytes"
"crypto/rand"
"encoding/hex"
"errors"
"fmt"
"io"
"strings"
"time"
)
2016-02-07 23:54:55 -08:00
// Email is a vain type for storing email addresses.
type Email string
// Token is a vain type for an api token.
type Token string
type namespace string
type path string
var vcss = map[string]bool{
"hg": true,
"git": true,
"bzr": true,
"svn": true,
2016-02-07 23:54:55 -08:00
}
func valid(vcs string) bool {
_, ok := vcss[vcs]
return ok
2016-02-07 23:54:55 -08:00
}
2016-02-15 01:10:14 -08:00
// Package stores the three pieces of information needed to create the meta
// tag. Two of these (Vcs and Repo) are stored explicitly, and the third is
// determined implicitly by the path POSTed to. For more information refer to
// the documentation for the go tool:
//
// https://golang.org/cmd/go/#hdr-Remote_import_paths
2016-02-08 00:14:30 -08:00
type Package struct {
//Vcs (version control system) supported: "hg", "git", "bzr", "svn"
Vcs string `json:"vcs"`
2016-02-15 01:10:14 -08:00
// Repo: the remote repository url
2016-02-07 23:54:55 -08:00
Repo string `json:"repo"`
2016-02-15 01:10:14 -08:00
Path string `json:"path"`
Ns namespace `json:"-"`
2016-02-07 23:54:55 -08:00
}
// User stores the information about a user including email used, their
// token, whether they have registerd and the requested timestamp
type User struct {
Email Email
token Token
Registered bool
Requested time.Time
}
2016-02-08 00:14:30 -08:00
func (p Package) String() string {
2016-02-07 23:54:55 -08:00
return fmt.Sprintf(
"<meta name=\"go-import\" content=\"%s %s %s\">",
p.Path,
2016-02-07 23:54:55 -08:00
p.Vcs,
p.Repo,
)
}
func splitPathHasPrefix(path, prefix []string) bool {
if len(path) < len(prefix) {
return false
}
for i, p := range prefix {
if path[i] != p {
return false
}
}
return true
}
// Valid checks that p will not confuse the go tool if added to packages.
func Valid(p string, packages []Package) bool {
ps := strings.Split(p, "/")
for _, pkg := range packages {
pre := strings.Split(pkg.Path, "/")
if splitPathHasPrefix(ps, pre) || splitPathHasPrefix(pre, ps) {
return false
}
}
return true
}
func parseNamespace(path string) (namespace, error) {
path = strings.TrimLeft(path, "/")
if path == "" {
return "", errors.New("path does not contain namespace")
}
elems := strings.Split(path, "/")
return namespace(elems[0]), nil
}
// FreshToken returns a random token string.
func FreshToken() Token {
buf := &bytes.Buffer{}
io.Copy(buf, io.LimitReader(rand.Reader, 6))
s := hex.EncodeToString(buf.Bytes())
r := []string{}
for i := 0; i < len(s)/4; i++ {
r = append(r, s[i*4:(i+1)*4])
}
return Token(strings.Join(r, "-"))
}