// 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) } }