cmd/checker: improvements
* do a GET first to complete cookie dance.
* custom type for timestamps. Gerrit doesn't follow standard JSON
conventions
* add trailing slashes if they're were missing.
diff --git a/cmd/checker/main.go b/cmd/checker/main.go
index 9651639..a34484f 100644
--- a/cmd/checker/main.go
+++ b/cmd/checker/main.go
@@ -78,13 +78,16 @@
func (g *gerrit) postPath(p string, contentType string, content []byte) ([]byte, error) {
u := g.URL
u.Path = path.Join(u.Path, p)
-
+ if strings.HasSuffix(p, "/") && !strings.HasSuffix(u.Path, "/") {
+ // Ugh.
+ u.Path += "/"
+ }
rep, err := g.client.Post(u.String(), contentType, bytes.NewBuffer(content))
if err != nil {
return nil, err
}
if rep.StatusCode != 200 {
- return nil, fmt.Errorf("Get %s: status %d", u, rep.StatusCode)
+ return nil, fmt.Errorf("Post %s: status %d", u.String(), rep.StatusCode)
}
defer rep.Body.Close()
@@ -142,6 +145,26 @@
Query string
}
+const timeLayout = "2006-01-02 15:04:05.000000000"
+
+type Timestamp time.Time
+
+func (ts *Timestamp) MarshalJSON() ([]byte, error) {
+ t := (*time.Time)(ts)
+ return []byte("\"" + t.Format(timeLayout) + "\""), nil
+}
+
+func (ts *Timestamp) UnmarshalJSON(b []byte) error {
+ b = bytes.TrimPrefix(b, []byte{'"'})
+ b = bytes.TrimSuffix(b, []byte{'"'})
+ t, err := time.Parse(timeLayout, string(b))
+ if err != nil {
+ return err
+ }
+ *ts = Timestamp(t)
+ return nil
+}
+
type CheckerInfo struct {
UUID string
Name string
@@ -149,13 +172,13 @@
URL string `json:"url"`
Repository string
Status string
- Blocking string
+ Blocking []string
Query string
- Created time.Time
- Updated time.Time
+ Created Timestamp
+ Updated Timestamp
}
-func (g *gerrit) CreateChecker() error {
+func (g *gerrit) CreateChecker() (*CheckerInfo, error) {
in := CheckerInput{
Name: "fmtserver",
Description: "check source code formatting.",
@@ -165,28 +188,33 @@
body, err := json.Marshal(&in)
if err != nil {
- return err
+ return nil, err
}
- content, err := g.postPath("plugins/checks/checkers", "application/json", body)
-
+ content, err := g.postPath("a/plugins/checks/checkers/", "application/json", body)
+ if err != nil {
+ return nil, err
+ }
if !bytes.HasPrefix(content, jsonPrefix) {
if len(content) > 100 {
content = content[:100]
}
bodyStr := string(content)
- return fmt.Errorf("prefix %q not found, got %s", jsonPrefix, bodyStr)
+ return nil, fmt.Errorf("prefix %q not found, got %s", jsonPrefix, bodyStr)
}
content = bytes.TrimPrefix(content, []byte(jsonPrefix))
- out := CheckerInfo{}
+ out := []CheckerInfo{}
if err := json.Unmarshal(content, &out); err != nil {
- return fmt.Errorf("Unmarshal: %v", err)
+ return nil, fmt.Errorf("Unmarshal: %v", err)
}
- return nil
+ for _, ch := range out {
+ log.Printf("ch %#v", ch)
+ }
+ return &out[0], nil
}
type gerritChecker struct {
@@ -239,9 +267,8 @@
register := flag.Bool("register", false, "Register with the host")
list := flag.Bool("list", false, "List pending checks")
agent := flag.String("agent", "fmtserver", "user-agent for the fmtserver.")
- cookieJar := flag.String("cookies", "", "path to cURL-style cookie jar file.")
+ cookieJar := flag.String("cookies", "", "comma separated paths to cURL-style cookie jar file.")
flag.Parse()
-
if *gerritURL == "" {
log.Fatal("must set --gerrit")
}
@@ -254,6 +281,7 @@
g := &gerrit{
URL: *u,
}
+
if nm := *cookieJar; nm != "" {
jar, err := cookie.NewJar(nm)
if err != nil {
@@ -263,7 +291,6 @@
log.Printf("WatchJar: %v", err)
log.Println("continuing despite WatchJar failure", err)
}
-
g.client.Jar = jar
}
g.UserAgent = *agent
@@ -275,7 +302,13 @@
return nil
}
- _ = *register
+ // Do a GET first to complete any cookie dance, because POST aren't redirected properly.
+ if c, err := g.getPath("accounts/self"); err != nil {
+ log.Fatalf("ListCheckers: %v", err)
+ } else {
+ io.Copy(os.Stdout, bytes.NewBuffer(c))
+ }
+
if *list {
if c, err := g.getPath("plugins/checks/checkers/"); err != nil {
log.Fatalf("ListCheckers: %v", err)
@@ -284,6 +317,14 @@
}
os.Exit(0)
}
+ if *register {
+ ch, err := g.CreateChecker()
+ if err != nil {
+ log.Fatalf("CreateChecker: %v", err)
+ }
+ log.Printf("CreateChecker result: %v", ch)
+ os.Exit(0)
+ }
if *addr == "" {
log.Fatal("must set --addr")