xref: /aosp_15_r20/external/bazelbuild-rules_android/src/tools/ak/ak.go (revision 9e965d6fece27a77de5377433c2f7e6999b8cc0b)
1// Copyright 2018 The Bazel Authors. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//    http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// AK (Android Kit) is a command line tool that combines useful commands.
16package main
17
18import (
19	"flag"
20	"fmt"
21	"log"
22	"os"
23	"sort"
24
25	_ "src/common/golang/flagfile"
26	"src/tools/ak/akcommands"
27	"src/tools/ak/types"
28)
29
30const helpHeader = "AK Android Kit is a command line tool that combines useful commands.\n\nUsage: ak %s <options>\n\n"
31
32var (
33	cmds = akcommands.Cmds
34)
35
36func helpDesc() string {
37	return "Prints help for commands, or the index."
38}
39
40func main() {
41	cmds["help"] = types.Command{
42		Init: func() {},
43		Run:  printHelp,
44		Desc: helpDesc,
45	}
46
47	switch len(os.Args) {
48	case 1:
49		printHelp()
50	case 3:
51		if os.Args[1] == "help" {
52			cmdHelp(os.Args[2])
53			os.Exit(0)
54		}
55		fallthrough
56	default:
57		cmd := os.Args[1]
58		if _, present := cmds[cmd]; present {
59			runCmd(cmd)
60		} else {
61			log.Fatalf("Command %q not found. Try 'ak help'.", cmd)
62		}
63	}
64}
65
66func runCmd(cmd string) {
67	cmds[cmd].Init()
68	flag.CommandLine.Parse(os.Args[2:])
69	cmds[cmd].Run()
70}
71
72func printHelp() {
73	fmt.Printf(helpHeader, "<command>")
74	printCmds()
75	fmt.Println("\nGetting more help:")
76	fmt.Println("  ak help <command>")
77	fmt.Println("             Prints help and options for <command>.")
78}
79
80func printCmds() {
81	fmt.Println("Available commands:")
82	var keys []string
83	for k := range cmds {
84		keys = append(keys, k)
85	}
86	sort.Strings(keys)
87	for _, k := range keys {
88		fmt.Printf("  %-10s %v\n", k, cmds[k].Desc())
89	}
90}
91
92func cmdHelp(cmd string) {
93	if _, present := cmds[cmd]; present {
94		cmds[cmd].Init()
95		fmt.Printf(helpHeader, cmd)
96		fmt.Println(cmds[cmd].Desc())
97		if cmds[cmd].Flags != nil {
98			fmt.Println("\nOptions:")
99			for _, f := range cmds[cmd].Flags {
100				fmt.Println(flagDesc(f))
101			}
102		}
103	} else {
104		fmt.Printf("Command %q not found.\n\n", cmd)
105		printCmds()
106	}
107}
108
109func flagDesc(name string) string {
110	flag := flag.Lookup(name)
111	if flag == nil {
112		return fmt.Sprintf("Flag %q not found!", name)
113	}
114	flagType := fmt.Sprintf("%T", flag.Value)
115	flagType = flagType[6 : len(flagType)-5]
116	return fmt.Sprintf("  -%-16s %s (a %s; default: \"%s\")", flag.Name, flag.Usage, flagType, flag.DefValue)
117}
118