| // depstool is a command-line tool for manipulating QUICHE WORKSPACE.bazel file. |
| package main |
| |
| import ( |
| "flag" |
| "fmt" |
| "io/ioutil" |
| "log" |
| "os" |
| "time" |
| |
| "github.com/bazelbuild/buildtools/build" |
| "quiche.googlesource.com/quiche/depstool/deps" |
| ) |
| |
| func list(path string, contents []byte) { |
| flags, err := deps.ParseHTTPArchiveRules(contents) |
| if err != nil { |
| log.Fatalf("Failed to parse %s: %v", path, err) |
| } |
| |
| fmt.Println("+------------------------------+--------------------------+") |
| fmt.Println("| Dependency | Last updated |") |
| fmt.Println("+------------------------------+--------------------------+") |
| for _, flag := range flags { |
| lastUpdated, err := time.Parse("2006-01-02", flag.LastUpdated) |
| if err != nil { |
| log.Fatalf("Failed to parse date %s: %v", flag.LastUpdated, err) |
| } |
| delta := time.Since(lastUpdated) |
| days := int(delta.Hours() / 24) |
| fmt.Printf("| %28s | %s, %3d days ago |\n", flag.Name, flag.LastUpdated, days) |
| } |
| fmt.Println("+------------------------------+--------------------------+") |
| } |
| |
| func validate(path string, contents []byte) { |
| file, err := build.ParseWorkspace(path, contents) |
| if err != nil { |
| log.Fatalf("Failed to parse the WORKSPACE.bazel file: %v", err) |
| } |
| |
| success := true |
| for _, stmt := range file.Stmt { |
| rule, ok := deps.HTTPArchiveRule(stmt) |
| if !ok { |
| // Skip unrelated rules |
| continue |
| } |
| if _, err := deps.ParseHTTPArchiveRule(rule); err != nil { |
| log.Printf("Failed to parse http_archive in %s on the line %d, issue: %v", path, rule.Pos.Line, err) |
| success = false |
| } |
| } |
| if !success { |
| os.Exit(1) |
| } |
| log.Printf("All http_archive rules have been validated successfully") |
| os.Exit(0) |
| } |
| |
| func fetch(path string, contents []byte, outdir string) { |
| rules, err := deps.ParseHTTPArchiveRules(contents) |
| if err != nil { |
| log.Fatalf("Failed to parse %s: %v", path, err) |
| } |
| |
| for _, rule := range rules { |
| log.Printf("Fetching %s into %s...", rule.Name, outdir) |
| outfile, err := deps.FetchEntry(rule, outdir) |
| if err != nil { |
| log.Fatalf("Failed to fetch %s: %s", rule.Name, err) |
| } |
| log.Printf("Successfully fetched %s into %s", rule.Name, outfile) |
| } |
| } |
| |
| func usage() { |
| fmt.Fprintf(flag.CommandLine.Output(), ` |
| usage: depstool [WORKSPACE file] [subcommand] |
| |
| Available subcommands: |
| list Lists all of the rules in the file |
| validate Validates that the WORKSPACE file is parsable |
| fetch Fetches all dependencies into the specified directory |
| |
| If no subcommand is specified, "list" is assumed. |
| `) |
| flag.PrintDefaults() |
| } |
| |
| func main() { |
| flag.Usage = usage |
| flag.Parse() |
| path := flag.Arg(0) |
| if path == "" { |
| usage() |
| os.Exit(1) |
| } |
| contents, err := ioutil.ReadFile(path) |
| if err != nil { |
| log.Fatalf("Failed to read WORKSPACE.bazel file: %v", err) |
| } |
| |
| subcommand := flag.Arg(1) |
| switch subcommand { |
| case "": |
| fallthrough // list is the default action |
| case "list": |
| list(path, contents) |
| case "validate": |
| validate(path, contents) |
| case "fetch": |
| fetch(path, contents, flag.Arg(2)) |
| default: |
| log.Fatalf("Unknown command: %s", subcommand) |
| } |
| } |