mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2025-01-30 02:59:49 +00:00
194e01c9c6
* CI: run "build" on pull too * vendor build tools too
174 lines
2.9 KiB
Go
174 lines
2.9 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"bytes"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"log"
|
|
"net/textproto"
|
|
"os"
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/bmatcuk/doublestar"
|
|
"github.com/urfave/cli"
|
|
|
|
"github.com/bradrydzewski/togo/template"
|
|
)
|
|
|
|
type (
|
|
httptestParams struct {
|
|
Package string
|
|
Routes []*httptestRoute
|
|
}
|
|
httptestRoute struct {
|
|
Source string
|
|
Method string
|
|
Path string
|
|
Body string
|
|
Status int
|
|
Header map[string]string
|
|
}
|
|
)
|
|
|
|
var httptestCommand = cli.Command{
|
|
Name: "httptest",
|
|
Usage: "generate httptest server",
|
|
Action: httptestAction,
|
|
Flags: []cli.Flag{
|
|
cli.StringFlag{
|
|
Name: "package",
|
|
Value: "testdata",
|
|
},
|
|
cli.StringFlag{
|
|
Name: "input",
|
|
Value: "files/**",
|
|
},
|
|
cli.StringFlag{
|
|
Name: "output",
|
|
Value: "testdata_gen.go",
|
|
},
|
|
cli.StringFlag{
|
|
Name: "exclude",
|
|
},
|
|
},
|
|
}
|
|
|
|
func httptestAction(c *cli.Context) error {
|
|
pattern := c.Args().First()
|
|
if pattern == "" {
|
|
pattern = c.String("input")
|
|
}
|
|
|
|
matches, err := doublestar.Glob(pattern)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
var exclude *regexp.Regexp
|
|
if s := c.String("exclude"); s != "" {
|
|
exclude = regexp.MustCompilePOSIX(s)
|
|
}
|
|
|
|
params := httptestParams{
|
|
Package: c.String("package"),
|
|
}
|
|
|
|
for _, match := range matches {
|
|
stat, oserr := os.Stat(match)
|
|
if oserr != nil {
|
|
return oserr
|
|
}
|
|
if stat.IsDir() {
|
|
continue
|
|
}
|
|
if exclude != nil && exclude.MatchString(match) {
|
|
continue
|
|
}
|
|
|
|
log.Printf("parsing file %s", match)
|
|
|
|
raw, ioerr := ioutil.ReadFile(match)
|
|
if ioerr != nil {
|
|
return ioerr
|
|
}
|
|
|
|
route, parseErr := parseRoute(raw)
|
|
if parseErr != nil {
|
|
return parseErr
|
|
}
|
|
route.Source = strings.TrimPrefix(match, "files/")
|
|
|
|
params.Routes = append(params.Routes, route)
|
|
}
|
|
|
|
wr := os.Stdout
|
|
if output := c.String("output"); output != "" {
|
|
wr, err = os.Create(output)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer wr.Close()
|
|
}
|
|
|
|
return template.Execute(wr, "httptest.tmpl", ¶ms)
|
|
}
|
|
|
|
func parseRoute(in []byte) (*httptestRoute, error) {
|
|
out := new(httptestRoute)
|
|
out.Header = map[string]string{}
|
|
|
|
buf := bufio.NewReader(bytes.NewBuffer(in))
|
|
r := textproto.NewReader(buf)
|
|
|
|
//
|
|
// parses the method and path
|
|
//
|
|
|
|
line, err := r.ReadLine()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
parts := strings.Split(line, " ")
|
|
if len(parts) != 2 {
|
|
return nil, fmt.Errorf("Invalid request line. Want <method> <path>.")
|
|
}
|
|
out.Method = parts[0]
|
|
out.Path = parts[1]
|
|
|
|
//
|
|
// parses the mime headers
|
|
//
|
|
|
|
header, err := r.ReadMIMEHeader()
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
}
|
|
for k, v := range header {
|
|
out.Header[k] = strings.Join(v, "; ")
|
|
}
|
|
|
|
//
|
|
// extracts the response status code
|
|
//
|
|
|
|
out.Status, err = strconv.Atoi(header.Get("Status"))
|
|
if err != nil {
|
|
return nil, fmt.Errorf("Invalid Status code. %s", err)
|
|
}
|
|
delete(out.Header, "Status")
|
|
|
|
//
|
|
// parse the remainder of the file as the body
|
|
//
|
|
|
|
body, err := ioutil.ReadAll(buf)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
out.Body = string(body)
|
|
|
|
return out, nil
|
|
}
|