package main import ( "encoding/json" "errors" "flag" "fmt" "io/ioutil" "os" "path/filepath" "regexp" "strings" "text/template" ) type deps struct { ImportPath string } type godep struct { Deps []deps } type license struct { Path string URL string Text string } const ( markdown = `# Third Party Licenses {{range $item := .}} ## [{{$item.Path}}]({{$item.URL}}) {{$item.Text}} {{end}}` text = `Third Party Licenses {{range $item := .}} {{$item.Path}} {{$item.URL}} {{$item.Text}} {{end}}` ) var ( md bool file string lics []license errFound = errors.New("file found") licre = regexp.MustCompile("([Ll][Ii][Cc][Ee][Nn][Ss][Ee].*)") pathre = regexp.MustCompile("vendor/(.*/(.*/.*))/|vendor/(.*/.*/)") ) func init() { flag.BoolVar(&md, "md", false, "enable markdown output") flag.StringVar(&file, "f", "third_party_licenses.txt", "output file") } func trim(s string) string { if strings.Count(s, "/") <= 2 { return s } return trim(s[:strings.LastIndex(s, "/")]) } func main() { flag.Parse() var ( tmp *template.Template gd godep ) if md { tmp = template.Must(template.New("").Parse(markdown)) } else { tmp = template.Must(template.New("").Parse(text)) } godeps, err := ioutil.ReadFile("./Godeps/Godeps.json") if err != nil { exit(err) } err = json.Unmarshal(godeps, &gd) if err != nil { exit(err) } paths := make(map[string]struct{}) for _, d := range gd.Deps { path := trim(d.ImportPath) if _, ok := paths[path]; ok { continue } err := filepath.Walk(filepath.Join("vendor", path), walker) if err != nil && err != errFound { fmt.Fprintln(os.Stderr, err) } paths[path] = struct{}{} } output, err := os.Create(file) if err != nil { exit(err) } if err := tmp.Execute(output, lics); err != nil { output.Close() exit(err) } } func walker(path string, info os.FileInfo, err error) error { if info == nil { return nil } if info.IsDir() { return nil } if !licre.MatchString(info.Name()) { return nil } text, err := ioutil.ReadFile(path) if err != nil { return err } match := pathre.FindAllStringSubmatch(path, -1) if len(match) >= 1 { if len(match[0]) >= 4 { if match[0][1] == "" { match[0][1] = match[0][3] match[0][2] = match[0][3] } lics = append(lics, license{ Path: match[0][2], URL: match[0][1], Text: string(text), }) } } else { return nil } return errFound } func exit(err error) { fmt.Fprintln(os.Stderr, err) os.Exit(1) }