• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// depstool is a command-line tool for manipulating QUICHE WORKSPACE.bazel file.
2package main
3
4import (
5	"flag"
6	"fmt"
7	"io/ioutil"
8	"log"
9	"os"
10	"time"
11
12	"github.com/bazelbuild/buildtools/build"
13	"quiche.googlesource.com/quiche/depstool/deps"
14)
15
16func list(path string, contents []byte) {
17	flags, err := deps.ParseHTTPArchiveRules(contents)
18	if err != nil {
19		log.Fatalf("Failed to parse %s: %v", path, err)
20	}
21
22	fmt.Println("+------------------------------+--------------------------+")
23	fmt.Println("|                   Dependency | Last updated             |")
24	fmt.Println("+------------------------------+--------------------------+")
25	for _, flag := range flags {
26		lastUpdated, err := time.Parse("2006-01-02", flag.LastUpdated)
27		if err != nil {
28			log.Fatalf("Failed to parse date %s: %v", flag.LastUpdated, err)
29		}
30		delta := time.Since(lastUpdated)
31		days := int(delta.Hours() / 24)
32		fmt.Printf("| %28s | %s, %3d days ago |\n", flag.Name, flag.LastUpdated, days)
33	}
34	fmt.Println("+------------------------------+--------------------------+")
35}
36
37func validate(path string, contents []byte) {
38	file, err := build.ParseWorkspace(path, contents)
39	if err != nil {
40		log.Fatalf("Failed to parse the WORKSPACE.bazel file: %v", err)
41	}
42
43	success := true
44	for _, stmt := range file.Stmt {
45		rule, ok := deps.HTTPArchiveRule(stmt)
46		if !ok {
47			// Skip unrelated rules
48			continue
49		}
50		if _, err := deps.ParseHTTPArchiveRule(rule); err != nil {
51			log.Printf("Failed to parse http_archive in %s on the line %d, issue: %v", path, rule.Pos.Line, err)
52			success = false
53		}
54	}
55	if !success {
56		os.Exit(1)
57	}
58	log.Printf("All http_archive rules have been validated successfully")
59	os.Exit(0)
60}
61
62func usage() {
63	fmt.Fprintf(flag.CommandLine.Output(), `
64usage: depstool [WORKSPACE file] [subcommand]
65
66Available subcommands:
67    list       Lists all of the rules in the file
68    validate   Validates that the WORKSPACE file is parsable
69
70If no subcommand is specified, "list" is assumed.
71`)
72	flag.PrintDefaults()
73}
74
75func main() {
76	flag.Usage = usage
77	flag.Parse()
78	path := flag.Arg(0)
79	if path == "" {
80		usage()
81		os.Exit(1)
82	}
83	contents, err := ioutil.ReadFile(path)
84	if err != nil {
85		log.Fatalf("Failed to read WORKSPACE.bazel file: %v", err)
86	}
87
88	subcommand := flag.Arg(1)
89	switch subcommand {
90	case "":
91		fallthrough // list is the default action
92	case "list":
93		list(path, contents)
94	case "validate":
95		validate(path, contents)
96	default:
97		log.Fatalf("Unknown command: %s", subcommand)
98	}
99}
100