vcs as string, not int.
No longer do we keep track of const iota style. Just encode the behavior in the server for defaults, add a validation function, call it a day. Change-Id: I603e9dd287a57084c78c543f1ce83b0acf47a765
This commit is contained in:
parent
a1f6e15f28
commit
ce00d933aa
66
api_test.go
66
api_test.go
@ -2,21 +2,21 @@ package vain
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestAdd(t *testing.T) {
|
func TestAdd(t *testing.T) {
|
||||||
ms := NewSimpleStore("")
|
ms := NewSimpleStore("")
|
||||||
s := &Server{
|
sm := http.NewServeMux()
|
||||||
storage: ms,
|
_ = NewServer(sm, ms)
|
||||||
}
|
ts := httptest.NewServer(sm)
|
||||||
ts := httptest.NewServer(s)
|
|
||||||
s.hostname = ts.URL
|
|
||||||
resp, err := http.Get(ts.URL)
|
resp, err := http.Get(ts.URL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("couldn't GET: %v", err)
|
t.Errorf("couldn't GET: %v", err)
|
||||||
@ -36,8 +36,25 @@ func TestAdd(t *testing.T) {
|
|||||||
t.Errorf("started with something in it; got %d, want %d", len(ms.p), 0)
|
t.Errorf("started with something in it; got %d, want %d", len(ms.p), 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
good := fmt.Sprintf("%s/foo", ts.URL)
|
{
|
||||||
resp, err = http.Post(good, "application/json", strings.NewReader(`{"repo": "https://s.mcquay.me/sm/vain"}`))
|
u := fmt.Sprintf("%s/db/", ts.URL)
|
||||||
|
resp, err := http.Get(u)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
io.Copy(buf, resp.Body)
|
||||||
|
pkgs := []Package{}
|
||||||
|
if err := json.NewDecoder(buf).Decode(&pkgs); err != nil {
|
||||||
|
t.Errorf("problem parsing json: %v, \n%q", err, buf)
|
||||||
|
}
|
||||||
|
if got, want := len(pkgs), 0; got != want {
|
||||||
|
t.Errorf("should have empty pkg list; got %d, want %d", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
u := fmt.Sprintf("%s/foo", ts.URL)
|
||||||
|
resp, err = http.Post(u, "application/json", strings.NewReader(`{"repo": "https://s.mcquay.me/sm/vain"}`))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("couldn't POST: %v", err)
|
t.Errorf("couldn't POST: %v", err)
|
||||||
}
|
}
|
||||||
@ -46,6 +63,11 @@ func TestAdd(t *testing.T) {
|
|||||||
t.Errorf("storage should have something in it; got %d, want %d", len(ms.p), 1)
|
t.Errorf("storage should have something in it; got %d, want %d", len(ms.p), 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ur, err := url.Parse(ts.URL)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
good := fmt.Sprintf("%s/foo", ur.Host)
|
||||||
p, ok := ms.p[good]
|
p, ok := ms.p[good]
|
||||||
if !ok {
|
if !ok {
|
||||||
t.Fatalf("did not find package for %s; should have posted a valid package", good)
|
t.Fatalf("did not find package for %s; should have posted a valid package", good)
|
||||||
@ -56,8 +78,8 @@ func TestAdd(t *testing.T) {
|
|||||||
if want := "https://s.mcquay.me/sm/vain"; p.Repo != want {
|
if want := "https://s.mcquay.me/sm/vain"; p.Repo != want {
|
||||||
t.Errorf("repo did not go through as expected; got %q, want %q", p.Repo, want)
|
t.Errorf("repo did not go through as expected; got %q, want %q", p.Repo, want)
|
||||||
}
|
}
|
||||||
if want := Git; p.Vcs != want {
|
if got, want := p.Vcs, "git"; got != want {
|
||||||
t.Errorf("Vcs did not go through as expected; got %q, want %q", p.Vcs, want)
|
t.Errorf("Vcs did not go through as expected; got %q, want %q", got, want)
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err = http.Get(ts.URL)
|
resp, err = http.Get(ts.URL)
|
||||||
@ -75,6 +97,23 @@ func TestAdd(t *testing.T) {
|
|||||||
if got, want := strings.Count(buf.String(), "meta"), 1; got != want {
|
if got, want := strings.Count(buf.String(), "meta"), 1; got != want {
|
||||||
t.Errorf("did not find all the tags I need; got %d, want %d", got, want)
|
t.Errorf("did not find all the tags I need; got %d, want %d", got, want)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
u := fmt.Sprintf("%s/db/", ts.URL)
|
||||||
|
resp, err := http.Get(u)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
io.Copy(buf, resp.Body)
|
||||||
|
pkgs := []Package{}
|
||||||
|
if err := json.NewDecoder(buf).Decode(&pkgs); err != nil {
|
||||||
|
t.Errorf("problem parsing json: %v, \n%q", err, buf)
|
||||||
|
}
|
||||||
|
if got, want := len(pkgs), 1; got != want {
|
||||||
|
t.Errorf("should (mildly) populated pkg list; got %d, want %d", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInvalidPath(t *testing.T) {
|
func TestInvalidPath(t *testing.T) {
|
||||||
@ -83,7 +122,6 @@ func TestInvalidPath(t *testing.T) {
|
|||||||
storage: ms,
|
storage: ms,
|
||||||
}
|
}
|
||||||
ts := httptest.NewServer(s)
|
ts := httptest.NewServer(s)
|
||||||
s.hostname = ts.URL
|
|
||||||
|
|
||||||
resp, err := http.Post(ts.URL, "application/json", strings.NewReader(`{"repo": "https://s.mcquay.me/sm/vain"}`))
|
resp, err := http.Post(ts.URL, "application/json", strings.NewReader(`{"repo": "https://s.mcquay.me/sm/vain"}`))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -103,7 +141,6 @@ func TestCannotDuplicateExistingPath(t *testing.T) {
|
|||||||
storage: ms,
|
storage: ms,
|
||||||
}
|
}
|
||||||
ts := httptest.NewServer(s)
|
ts := httptest.NewServer(s)
|
||||||
s.hostname = ts.URL
|
|
||||||
|
|
||||||
url := fmt.Sprintf("%s/foo", ts.URL)
|
url := fmt.Sprintf("%s/foo", ts.URL)
|
||||||
resp, err := http.Post(url, "application/json", strings.NewReader(`{"repo": "https://s.mcquay.me/sm/vain"}`))
|
resp, err := http.Post(url, "application/json", strings.NewReader(`{"repo": "https://s.mcquay.me/sm/vain"}`))
|
||||||
@ -128,7 +165,6 @@ func TestCannotAddExistingSubPath(t *testing.T) {
|
|||||||
storage: ms,
|
storage: ms,
|
||||||
}
|
}
|
||||||
ts := httptest.NewServer(s)
|
ts := httptest.NewServer(s)
|
||||||
s.hostname = ts.URL
|
|
||||||
|
|
||||||
url := fmt.Sprintf("%s/foo/bar", ts.URL)
|
url := fmt.Sprintf("%s/foo/bar", ts.URL)
|
||||||
resp, err := http.Post(url, "application/json", strings.NewReader(`{"repo": "https://s.mcquay.me/sm/vain"}`))
|
resp, err := http.Post(url, "application/json", strings.NewReader(`{"repo": "https://s.mcquay.me/sm/vain"}`))
|
||||||
@ -156,7 +192,6 @@ func TestMissingRepo(t *testing.T) {
|
|||||||
storage: ms,
|
storage: ms,
|
||||||
}
|
}
|
||||||
ts := httptest.NewServer(s)
|
ts := httptest.NewServer(s)
|
||||||
s.hostname = ts.URL
|
|
||||||
url := fmt.Sprintf("%s/foo", ts.URL)
|
url := fmt.Sprintf("%s/foo", ts.URL)
|
||||||
resp, err := http.Post(url, "application/json", strings.NewReader(`{}`))
|
resp, err := http.Post(url, "application/json", strings.NewReader(`{}`))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -176,7 +211,6 @@ func TestBadJson(t *testing.T) {
|
|||||||
storage: ms,
|
storage: ms,
|
||||||
}
|
}
|
||||||
ts := httptest.NewServer(s)
|
ts := httptest.NewServer(s)
|
||||||
s.hostname = ts.URL
|
|
||||||
url := fmt.Sprintf("%s/foo", ts.URL)
|
url := fmt.Sprintf("%s/foo", ts.URL)
|
||||||
resp, err := http.Post(url, "application/json", strings.NewReader(`{`))
|
resp, err := http.Post(url, "application/json", strings.NewReader(`{`))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -196,7 +230,6 @@ func TestUnsupportedMethod(t *testing.T) {
|
|||||||
storage: ms,
|
storage: ms,
|
||||||
}
|
}
|
||||||
ts := httptest.NewServer(s)
|
ts := httptest.NewServer(s)
|
||||||
s.hostname = ts.URL
|
|
||||||
url := fmt.Sprintf("%s/foo", ts.URL)
|
url := fmt.Sprintf("%s/foo", ts.URL)
|
||||||
client := &http.Client{}
|
client := &http.Client{}
|
||||||
req, err := http.NewRequest("PUT", url, nil)
|
req, err := http.NewRequest("PUT", url, nil)
|
||||||
@ -215,9 +248,8 @@ func TestUnsupportedMethod(t *testing.T) {
|
|||||||
func TestNewServer(t *testing.T) {
|
func TestNewServer(t *testing.T) {
|
||||||
ms := NewSimpleStore("")
|
ms := NewSimpleStore("")
|
||||||
sm := http.NewServeMux()
|
sm := http.NewServeMux()
|
||||||
s := NewServer(sm, ms, "foo")
|
s := NewServer(sm, ms)
|
||||||
ts := httptest.NewServer(s)
|
ts := httptest.NewServer(s)
|
||||||
s.hostname = ts.URL
|
|
||||||
url := fmt.Sprintf("%s/foo", ts.URL)
|
url := fmt.Sprintf("%s/foo", ts.URL)
|
||||||
client := &http.Client{}
|
client := &http.Client{}
|
||||||
req, err := http.NewRequest("PUT", url, nil)
|
req, err := http.NewRequest("PUT", url, nil)
|
||||||
|
@ -65,7 +65,7 @@ func main() {
|
|||||||
c := &config{
|
c := &config{
|
||||||
Port: 4040,
|
Port: 4040,
|
||||||
}
|
}
|
||||||
if err := envconfig.Process("ysv", c); err != nil {
|
if err := envconfig.Process("vain", c); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "problem processing environment: %v", err)
|
fmt.Fprintf(os.Stderr, "problem processing environment: %v", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
@ -77,7 +77,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if c.DB == "" {
|
if c.DB == "" {
|
||||||
log.Printf("warning: in-memory db mode; if you do not want this set YSV_DB")
|
log.Printf("warning: in-memory db mode; if you do not want this set VAIN_DB")
|
||||||
}
|
}
|
||||||
hostname := "localhost"
|
hostname := "localhost"
|
||||||
if hn, err := os.Hostname(); err != nil {
|
if hn, err := os.Hostname(); err != nil {
|
||||||
|
20
server.go
20
server.go
@ -12,7 +12,7 @@ func NewServer(sm *http.ServeMux, store Storage) *Server {
|
|||||||
s := &Server{
|
s := &Server{
|
||||||
storage: store,
|
storage: store,
|
||||||
}
|
}
|
||||||
sm.Handle("/", s)
|
addRoutes(sm, s)
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,6 +43,13 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||||||
http.Error(w, fmt.Sprintf("invalid repository %q", req.URL.Path), http.StatusBadRequest)
|
http.Error(w, fmt.Sprintf("invalid repository %q", req.URL.Path), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if p.Vcs == "" {
|
||||||
|
p.Vcs = "git"
|
||||||
|
}
|
||||||
|
if !valid(p.Vcs) {
|
||||||
|
http.Error(w, fmt.Sprintf("invalid vcs %q", p.Vcs), http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
p.path = fmt.Sprintf("%s/%s", req.Host, strings.Trim(req.URL.Path, "/"))
|
p.path = fmt.Sprintf("%s/%s", req.Host, strings.Trim(req.URL.Path, "/"))
|
||||||
if !Valid(p.path, s.storage.All()) {
|
if !Valid(p.path, s.storage.All()) {
|
||||||
http.Error(w, fmt.Sprintf("invalid path; prefix already taken %q", req.URL.Path), http.StatusConflict)
|
http.Error(w, fmt.Sprintf("invalid path; prefix already taken %q", req.URL.Path), http.StatusConflict)
|
||||||
@ -56,3 +63,14 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||||||
http.Error(w, fmt.Sprintf("unsupported method %q; accepted: POST, GET", req.Method), http.StatusMethodNotAllowed)
|
http.Error(w, fmt.Sprintf("unsupported method %q; accepted: POST, GET", req.Method), http.StatusMethodNotAllowed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Server) db(w http.ResponseWriter, req *http.Request) {
|
||||||
|
all := s.storage.All()
|
||||||
|
w.Header().Set("Content-type", "application/json")
|
||||||
|
json.NewEncoder(w).Encode(&all)
|
||||||
|
}
|
||||||
|
|
||||||
|
func addRoutes(sm *http.ServeMux, s *Server) {
|
||||||
|
sm.Handle("/", s)
|
||||||
|
sm.HandleFunc("/db/", s.db)
|
||||||
|
}
|
||||||
|
11
storage.go
11
storage.go
@ -107,5 +107,14 @@ func (ms *SimpleStore) Load() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
return json.NewDecoder(f).Decode(&ms.p)
|
|
||||||
|
in := map[string]Package{}
|
||||||
|
if err := json.NewDecoder(f).Decode(&in); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for k, v := range in {
|
||||||
|
v.path = k
|
||||||
|
ms.p[k] = v
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
package vain
|
package vain
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -13,7 +16,7 @@ func equiv(a, b map[string]Package) (bool, []error) {
|
|||||||
errs := []error{}
|
errs := []error{}
|
||||||
if got, want := len(a), len(b); got != want {
|
if got, want := len(a), len(b); got != want {
|
||||||
equiv = false
|
equiv = false
|
||||||
errs = append(errs, fmt.Errorf("uncorrect number of elements: got %d, want %d", got, want))
|
errs = append(errs, fmt.Errorf("incorrect number of elements: got %d, want %d", got, want))
|
||||||
return false, errs
|
return false, errs
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,10 +40,14 @@ func TestSimpleStorage(t *testing.T) {
|
|||||||
db := filepath.Join(root, "vain.json")
|
db := filepath.Join(root, "vain.json")
|
||||||
ms := NewSimpleStore(db)
|
ms := NewSimpleStore(db)
|
||||||
orig := map[string]Package{
|
orig := map[string]Package{
|
||||||
"foo": {},
|
"foo": {Vcs: "mercurial"},
|
||||||
"bar": {},
|
"bar": {Vcs: "bzr"},
|
||||||
"baz": {},
|
"baz": {},
|
||||||
}
|
}
|
||||||
|
for k, v := range orig {
|
||||||
|
v.path = k
|
||||||
|
orig[k] = v
|
||||||
|
}
|
||||||
ms.p = orig
|
ms.p = orig
|
||||||
if err := ms.Save(); err != nil {
|
if err := ms.Save(); err != nil {
|
||||||
t.Errorf("should have been able to Save: %v", err)
|
t.Errorf("should have been able to Save: %v", err)
|
||||||
@ -49,7 +56,7 @@ func TestSimpleStorage(t *testing.T) {
|
|||||||
if err := ms.Load(); err != nil {
|
if err := ms.Load(); err != nil {
|
||||||
t.Errorf("should have been able to Load: %v", err)
|
t.Errorf("should have been able to Load: %v", err)
|
||||||
}
|
}
|
||||||
if ok, errs := equiv(orig, ms.p); !ok {
|
if ok, errs := equiv(ms.p, orig); !ok {
|
||||||
for _, err := range errs {
|
for _, err := range errs {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
@ -82,3 +89,39 @@ func TestRemove(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPackageJsonParsing(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
input string
|
||||||
|
output string
|
||||||
|
parsed Package
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
input: `{"vcs":"git","repo":"https://s.mcquay.me/sm/ud/"}`,
|
||||||
|
output: `{"vcs":"git","repo":"https://s.mcquay.me/sm/ud/"}`,
|
||||||
|
parsed: Package{Vcs: "git", Repo: "https://s.mcquay.me/sm/ud/"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: `{"vcs":"hg","repo":"https://s.mcquay.me/sm/ud/"}`,
|
||||||
|
output: `{"vcs":"hg","repo":"https://s.mcquay.me/sm/ud/"}`,
|
||||||
|
parsed: Package{Vcs: "hg", Repo: "https://s.mcquay.me/sm/ud/"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
p := Package{}
|
||||||
|
if err := json.NewDecoder(strings.NewReader(test.input)).Decode(&p); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
if p != test.parsed {
|
||||||
|
t.Errorf("got:\n\t%v, want\n\t%v", p, test.parsed)
|
||||||
|
}
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
if err := json.NewEncoder(buf).Encode(&p); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
if got, want := strings.TrimSpace(buf.String()), test.output; got != want {
|
||||||
|
t.Errorf("got %v, want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
60
vain.go
60
vain.go
@ -3,45 +3,20 @@
|
|||||||
// The executable, cmd/vaind, is located in the respective subdirectory.
|
// The executable, cmd/vaind, is located in the respective subdirectory.
|
||||||
package vain
|
package vain
|
||||||
|
|
||||||
import (
|
import "fmt"
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
type vcs int
|
var vcss = map[string]bool{
|
||||||
|
"hg": true,
|
||||||
const (
|
"git": true,
|
||||||
// Git is the default Vcs.
|
"bzr": true,
|
||||||
Git vcs = iota
|
"svn": true,
|
||||||
|
|
||||||
// Hg is mercurial
|
|
||||||
Hg
|
|
||||||
|
|
||||||
// Svn
|
|
||||||
Svn
|
|
||||||
|
|
||||||
// Bazaar
|
|
||||||
Bzr
|
|
||||||
)
|
|
||||||
|
|
||||||
var vcss = [...]string{
|
|
||||||
"git",
|
|
||||||
"mercurial",
|
|
||||||
"svn",
|
|
||||||
"bazaar",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var labelToVcs = map[string]vcs{
|
func valid(vcs string) bool {
|
||||||
"git": Git,
|
_, ok := vcss[vcs]
|
||||||
"mercurial": Hg,
|
return ok
|
||||||
"hg": Hg,
|
|
||||||
"svn": Svn,
|
|
||||||
"bazaar": Bzr,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns the name of the vcs ("git", "mercurial", ...).
|
|
||||||
func (v vcs) String() string { return vcss[v] }
|
|
||||||
|
|
||||||
// Package stores the three pieces of information needed to create the meta
|
// 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
|
// 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
|
// determined implicitly by the path POSTed to. For more information refer to
|
||||||
@ -49,8 +24,8 @@ func (v vcs) String() string { return vcss[v] }
|
|||||||
//
|
//
|
||||||
// https://golang.org/cmd/go/#hdr-Remote_import_paths
|
// https://golang.org/cmd/go/#hdr-Remote_import_paths
|
||||||
type Package struct {
|
type Package struct {
|
||||||
//Vcs (version control system) supported: "git", "mercurial"
|
//Vcs (version control system) supported: "hg", "git", "bzr", "svn"
|
||||||
Vcs vcs `json:"vcs"`
|
Vcs string `json:"vcs"`
|
||||||
// Repo: the remote repository url
|
// Repo: the remote repository url
|
||||||
Repo string `json:"repo"`
|
Repo string `json:"repo"`
|
||||||
|
|
||||||
@ -65,16 +40,3 @@ func (p Package) String() string {
|
|||||||
p.Repo,
|
p.Repo,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Package) UnmarshalJSON(b []byte) (err error) {
|
|
||||||
pkg := struct {
|
|
||||||
Vcs string
|
|
||||||
Repo string
|
|
||||||
}{}
|
|
||||||
err = json.Unmarshal(b, &pkg)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
p.Vcs, p.Repo = labelToVcs[pkg.Vcs], pkg.Repo
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
22
vain_test.go
22
vain_test.go
@ -7,6 +7,7 @@ import (
|
|||||||
|
|
||||||
func TestString(t *testing.T) {
|
func TestString(t *testing.T) {
|
||||||
p := Package{
|
p := Package{
|
||||||
|
Vcs: "git",
|
||||||
path: "mcquay.me/bps",
|
path: "mcquay.me/bps",
|
||||||
Repo: "https://s.mcquay.me/sm/bps",
|
Repo: "https://s.mcquay.me/sm/bps",
|
||||||
}
|
}
|
||||||
@ -21,19 +22,22 @@ func TestString(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVcsStrings(t *testing.T) {
|
func TestSupportedVcsStrings(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
got string
|
in string
|
||||||
want string
|
want bool
|
||||||
}{
|
}{
|
||||||
{fmt.Sprintf("%+v", Git), "git"},
|
{"hg", true},
|
||||||
{fmt.Sprintf("%+v", Hg), "mercurial"},
|
{"git", true},
|
||||||
{fmt.Sprintf("%+v", Svn), "svn"},
|
{"bzr", true},
|
||||||
{fmt.Sprintf("%+v", Bzr), "bazaar"},
|
|
||||||
|
{"", false},
|
||||||
|
{"bazar", false},
|
||||||
|
{"mercurial", false},
|
||||||
}
|
}
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
if test.got != test.want {
|
if got, want := valid(test.in), test.want; got != want {
|
||||||
t.Errorf("incorrect conversion of vain.Vcs -> string; got %q, want %q", test.got, test.want)
|
t.Errorf("%s: %t is incorrect validity", test.in, got)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user