1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.tradefed.command;
18 
19 import com.android.tradefed.config.ArgsOptionParser;
20 import com.android.tradefed.config.ConfigurationException;
21 import com.android.tradefed.config.Option;
22 
23 import java.io.File;
24 import java.io.IOException;
25 import java.util.ArrayList;
26 import java.util.List;
27 
28 /**
29  * Alternate Trade Federation entrypoint to validate command files
30  */
31 public class Verify {
32 
33     private static final int EXIT_STATUS_OKAY = 0x0;
34     private static final int EXIT_STATUS_FAILED = 0x1;
35 
36     @Option(name = "cmdfile", description = "command file to verify")
37     private List<File> mCmdFiles = new ArrayList<>();
38 
39     @Option(name = "show-commands", description = "Whether to print all generated commands")
40     private boolean mShowCommands = false;
41 
42     @Option(name = "quiet", shortName = 'q', description = "Whether to silence all output. " +
43             "Overrides all other output-related settings.")
44     private boolean mQuiet = false;
45 
46     @Option(name = "help", shortName = 'h', description = "Print help")
47     private boolean mHelp = false;
48 
49     /**
50      * Returns whether the "--help"/"-h" option was passed to the instance
51      */
isHelpMode()52     public boolean isHelpMode() {
53         return mHelp;
54     }
55 
56     /**
57      * Program main entrypoint
58      */
main(final String[] mainArgs)59     public static void main(final String[] mainArgs) throws ConfigurationException {
60         try {
61             Verify verify = new Verify();
62             ArgsOptionParser optionSetter = new ArgsOptionParser(verify);
63             optionSetter.parse(mainArgs);
64             if (verify.isHelpMode()) {
65                 // Print help, then exit
66                 System.err.println(ArgsOptionParser.getOptionHelp(false, verify));
67                 System.exit(EXIT_STATUS_OKAY);
68             }
69 
70             if (verify.run()) {
71                 // true == everything's good
72                 System.exit(EXIT_STATUS_OKAY);
73             } else {
74                 // false == whoopsie!
75                 System.exit(EXIT_STATUS_FAILED);
76             }
77 
78         } finally {
79             System.err.flush();
80             System.out.flush();
81         }
82     }
83 
84     /**
85      * Start validating all specified cmdfiles
86      */
run()87     public boolean run() {
88         boolean anyFailures = false;
89 
90         for (File cmdFile : mCmdFiles) {
91             try {
92                 // if verify returns false, then we set anyFailures to true
93                 anyFailures |= !runVerify(cmdFile);
94 
95             } catch (Throwable t) {
96                 if (!mQuiet) {
97                     System.err.format("Caught exception while parsing \"%s\"\n", cmdFile);
98                     System.err.println(t);
99                 }
100                 anyFailures = true;
101             }
102         }
103 
104         return !anyFailures;
105     }
106 
107     /**
108      * Validate the specified cmdfile
109      */
runVerify(File cmdFile)110     public boolean runVerify(File cmdFile) {
111         final CommandFileParser parser = new CommandFileParser();
112         try {
113             List<CommandFileParser.CommandLine> commands = parser.parseFile(cmdFile);
114             if (!mQuiet) {
115                 System.out.format("Successfully parsed %d commands from cmdfile %s\n",
116                         commands.size(), cmdFile);
117 
118                 if (mShowCommands) {
119                     int i = 1;
120                     int digits = (int) Math.ceil(Math.log10(commands.size()));
121                     // Create a format string that will leave enough space for an index prefix
122                     // without mucking up alignment
123                     String format = String.format("%%%dd: %%s\n", digits);
124                     for (CommandFileParser.CommandLine cmd : commands) {
125                         System.out.format(format, i++, cmd);
126                     }
127                 }
128                 System.out.println();
129             }
130         } catch (ConfigurationException | IOException e) {
131             if (!mQuiet) {
132                 System.err.format("Failed to parse %s:\n", cmdFile);
133                 System.err.println(e);
134             }
135 
136             return false;
137         }
138 
139         return true;
140     }
141 }
142