From 1320a86cbed1fefc545604adf903a669119b4925 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Mon, 3 Oct 2016 12:36:46 +0100 Subject: [PATCH] Serve the api docs from the speculator There are a few parts to this: * when we generate the spec for a particular git sha, also run the script which turns our yaml api descriptions into a swagger json file. * tweak serveSpec to add another header when serving the generated json. * add a link to the generated index which will (via js hackery) redirect to our hosted swagger UI at http://matrix.org/docs/api/client-server, with a "url" query-param pointing at the generated json. Also, factor makeTempDir out of gitClone, so that we can give clearer log lines. --- scripts/speculator/main.go | 108 +++++++++++++++++++++++++++++-------- 1 file changed, 86 insertions(+), 22 deletions(-) diff --git a/scripts/speculator/main.go b/scripts/speculator/main.go index b433a327..87ee4bf6 100644 --- a/scripts/speculator/main.go +++ b/scripts/speculator/main.go @@ -27,6 +27,7 @@ import ( "strings" "sync" "syscall" + "text/template" "time" "github.com/hashicorp/golang-lru" @@ -83,19 +84,15 @@ func accessTokenQuerystring() string { return fmt.Sprintf("?access_token=%s", *accessToken) } -func gitClone(url string, shared bool) (string, error) { - directory := path.Join("/tmp/matrix-doc", strconv.FormatInt(rand.Int63(), 10)) - if err := os.MkdirAll(directory, permissionsOwnerFull); err != nil { - return "", fmt.Errorf("error making directory %s: %v", directory, err) - } +func gitClone(url string, directory string, shared bool) error { args := []string{"clone", url, directory} if shared { args = append(args, "--shared") } if err := runGitCommand(directory, args); err != nil { - return "", err + return err } - return directory, nil + return nil } func gitCheckout(path, sha string) error { @@ -159,6 +156,16 @@ func generate(dir string) error { if err := cmd.Run(); err != nil { return fmt.Errorf("error generating spec: %v\nOutput from gendoc:\n%v", err, b.String()) } + + // cheekily dump the swagger docs into the gen directory so they can be + // served by serveSpec + cmd = exec.Command("python", "dump-swagger.py", "gen/api-docs.json") + cmd.Dir = path.Join(dir, "scripts") + cmd.Stderr = &b + if err := cmd.Run(); err != nil { + return fmt.Errorf("error generating api docs: %v\nOutput from dump-swagger:\n%v", err, b.String()) + } + return nil } @@ -195,8 +202,14 @@ func (s *server) generateAt(sha string) (dst string, err error) { return } } + + dst, err = makeTempDir() + if err != nil { + return + } + log.Printf("Generating %s in %s\n", sha, dst) s.mu.Lock() - dst, err = gitClone(s.matrixDocCloneURL, true) + err = gitClone(s.matrixDocCloneURL, dst, true) s.mu.Unlock() if err != nil { return @@ -219,7 +232,7 @@ func (s *server) getSHAOf(ref string) (string, error) { err := cmd.Run() s.mu.Unlock() if err != nil { - return "", fmt.Errorf("error generating spec: %v\nOutput from gendoc:\n%v", err, b.String()) + return "", fmt.Errorf("error generating spec: %v\nOutput from git:\n%v", err, b.String()) } return strings.TrimSpace(b.String()), nil } @@ -396,6 +409,11 @@ func (s *server) serveSpec(w http.ResponseWriter, req *http.Request) { cache.Add(sha, pathToContent) } + if requestedPath == "api-docs.json" { + // allow other swagger UIs access to our swagger + w.Header().Set("Access-Control-Allow-Origin", "*") + } + if b, ok := pathToContent[requestedPath]; ok { w.Write(b) return @@ -588,12 +606,6 @@ func (srv *server) makeIndex(w http.ResponseWriter, req *http.Request) { writeError(w, 500, err) return } - s := "" branches, err := srv.getBranches() if err != nil { @@ -601,7 +613,48 @@ func (srv *server) makeIndex(w http.ResponseWriter, req *http.Request) { return } - s += `
View the spec at:
")) + b.WriteTo(w) } func ignoreExitCodeOne(err error) error { @@ -655,10 +707,14 @@ func main() { log.Fatal(err) } rand.Seed(time.Now().Unix()) - masterCloneDir, err := gitClone(matrixDocCloneURL, false) + masterCloneDir, err := makeTempDir() if err != nil { log.Fatal(err) } + log.Printf("Creating master clone dir %s\n", masterCloneDir) + if err = gitClone(matrixDocCloneURL, masterCloneDir, false); err != nil { + log.Fatal(err) + } s := server{matrixDocCloneURL: masterCloneDir} http.HandleFunc("/spec/", forceHTML(s.serveSpec)) http.HandleFunc("/diff/rst/", s.serveRSTDiff) @@ -691,3 +747,11 @@ func initCache() error { styledSpecCache = c2 return err } + +func makeTempDir() (string, error) { + directory := path.Join("/tmp/matrix-doc", strconv.FormatInt(rand.Int63(), 10)) + if err := os.MkdirAll(directory, permissionsOwnerFull); err != nil { + return "", fmt.Errorf("error making directory %s: %v", directory, err) + } + return directory, nil +}