OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include <algorithm> |
| 6 #include <iterator> |
| 7 #include <set> |
| 8 #include <vector> |
| 9 |
| 10 #include "base/files/file_path.h" |
| 11 #include "base/files/file_util.h" |
| 12 #include "tools/gn/commands.h" |
| 13 #include "tools/gn/filesystem_utils.h" |
| 14 #include "tools/gn/graph.h" |
| 15 #include "tools/gn/location.h" |
| 16 #include "tools/gn/setup.h" |
| 17 |
| 18 namespace commands { |
| 19 |
| 20 const char kAnalyze[] = "analyze"; |
| 21 const char kAnalyze_HelpShort[] = |
| 22 "analyze: Analyze which targets are affected by a list of files."; |
| 23 const char kAnalyze_Help[] = |
| 24 "gn analyze <out_dir> <input_path> <output_path>\n" |
| 25 "\n" |
| 26 " Analyze which targets are affected by a list of files.\n" |
| 27 "\n" |
| 28 " This command takes two arguments, input_path and output_path\n" |
| 29 "\n" |
| 30 " input_path is a path to a JSON file containing a dict with three\n" |
| 31 " keys:\n" |
| 32 "\n" |
| 33 " - \"files\": A list of the filenames to check.\n" |
| 34 "\n" |
| 35 " - \"test_targets\": An list of the labels for targets that\n" |
| 36 " are needed to run the tests we wish to run.\n" |
| 37 "\n" |
| 38 " - \"compile_targets\": A list of the labels targets that we wish to\n" |
| 39 " rebuild, but aren't necessarily needed for testing. The\n" |
| 40 " important difference between this field and \"test_targets\"\n" |
| 41 " is that if an item in the compile_targets list is a group, then\n" |
| 42 " any dependencies of that group will be returned if they are out\n" |
| 43 " of date, but the group itself does not need to be. If the\n" |
| 44 " dependencies themselves are groups, the same filtering is\n" |
| 45 " repeated. This filtering can be used to avoid rebuilding\n" |
| 46 " dependencies of a group that are unaffected by the input files.\n" |
| 47 " The list may contain the string \"all\" to refer to a\n" |
| 48 " pseudo-group that contains every root target in the build graph.\n" |
| 49 "\n" |
| 50 " output_path is a path indicating where the results of the command\n" |
| 51 " are to be written. The results will be a JSON file containing a dict\n" |
| 52 " with one or more of following keys:\n" |
| 53 "\n" |
| 54 " - \"compile_targets\": A list of the labels derived from the input\n" |
| 55 " compile_targets list that are affected by the input files.\n" |
| 56 " Due to the way the filtering works for compile targets as\n" |
| 57 " described above, this list may contain targets that do not appear\n" |
| 58 " in the input list.\n" |
| 59 "\n" |
| 60 " - \"test_targets\": A list of the labels from the input\n" |
| 61 " test_targets list that are affected by the input files. This list\n" |
| 62 " will be a proper subset of the input list.\n" |
| 63 "\n" |
| 64 " - \"invalid_targets\": A list of any names from the input that\n" |
| 65 " do not exist in the build graph.\n" |
| 66 "\n" |
| 67 " - \"status\": A string containing one of three values:\n" |
| 68 " - \"Found dependency\"\n" |
| 69 " - \"No dependency\"\n" |
| 70 " - \"Found dependency (all)\"\n" |
| 71 " In the first case, the lists returned in compile_targets and\n" |
| 72 " test_targets should be passed to ninja to build. In the second\n" |
| 73 " case, nothing was affected and no build is necessary. In the third\n" |
| 74 " case, GN could not determine the correct answer and returned the\n" |
| 75 " input as the output in order to be safe.\n" |
| 76 "\n" |
| 77 " - \"error\": This will only be present if an error occurred, and\n" |
| 78 " will contain a string describing the error. In addition, in this\n" |
| 79 " case the return code of the command will beĀ 1.\n"; |
| 80 |
| 81 int RunAnalyze(const std::vector<std::string>& args) { |
| 82 if (args.size() != 3) { |
| 83 Err(Location(), "You're holding it wrong.", |
| 84 "Usage: \"gn analyze <out_dir> <input_path> <output_path>") |
| 85 .PrintToStdout(); |
| 86 return 1; |
| 87 } |
| 88 |
| 89 std::string input; |
| 90 bool ret = base::ReadFileToString(UTF8ToFilePath(args[1]), &input); |
| 91 if (!ret) { |
| 92 Err(Location(), "Input file " + args[1] + " not found.").PrintToStdout(); |
| 93 return 1; |
| 94 } |
| 95 |
| 96 Setup* setup = new Setup; |
| 97 setup->build_settings().set_check_for_bad_items(false); |
| 98 if (!setup->DoSetup(args[0], false) || !setup->Run()) |
| 99 return 1; |
| 100 |
| 101 Graph graph(setup->builder().GetAllResolvedTargets(), |
| 102 setup->loader()->default_toolchain_label()); |
| 103 |
| 104 std::string output; |
| 105 Err err = Analyze(graph, input, &output); |
| 106 if (err.has_error()) { |
| 107 err.PrintToStdout(); |
| 108 return 1; |
| 109 } |
| 110 |
| 111 std::string output_path = args[2]; |
| 112 WriteFile(base::FilePath(output_path), output, &err); |
| 113 if (err.has_error()) { |
| 114 err.PrintToStdout(); |
| 115 return 1; |
| 116 } |
| 117 |
| 118 return 0; |
| 119 } |
| 120 |
| 121 } // namespace commands |
OLD | NEW |