OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stddef.h> | 5 #include <stddef.h> |
6 | 6 |
7 #include <sstream> | 7 #include <sstream> |
8 | 8 |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/files/file_util.h" | 10 #include "base/files/file_util.h" |
11 #include "base/macros.h" | 11 #include "base/macros.h" |
12 #include "base/strings/string_split.h" | 12 #include "base/strings/string_split.h" |
13 #include "base/strings/string_util.h" | 13 #include "base/strings/string_util.h" |
14 #include "tools/gn/commands.h" | 14 #include "tools/gn/commands.h" |
15 #include "tools/gn/filesystem_utils.h" | 15 #include "tools/gn/filesystem_utils.h" |
16 #include "tools/gn/input_file.h" | 16 #include "tools/gn/input_file.h" |
17 #include "tools/gn/parser.h" | 17 #include "tools/gn/parser.h" |
18 #include "tools/gn/scheduler.h" | 18 #include "tools/gn/scheduler.h" |
19 #include "tools/gn/setup.h" | 19 #include "tools/gn/setup.h" |
20 #include "tools/gn/source_file.h" | 20 #include "tools/gn/source_file.h" |
21 #include "tools/gn/tokenizer.h" | 21 #include "tools/gn/tokenizer.h" |
22 | 22 |
23 namespace commands { | 23 namespace commands { |
24 | 24 |
25 const char kSwitchDryRun[] = "dry-run"; | 25 const char kSwitchDryRun[] = "dry-run"; |
26 const char kSwitchDumpTree[] = "dump-tree"; | 26 const char kSwitchDumpTree[] = "dump-tree"; |
27 const char kSwitchInPlace[] = "in-place"; | |
28 const char kSwitchStdin[] = "stdin"; | 27 const char kSwitchStdin[] = "stdin"; |
29 | 28 |
30 const char kFormat[] = "format"; | 29 const char kFormat[] = "format"; |
31 const char kFormat_HelpShort[] = | 30 const char kFormat_HelpShort[] = |
32 "format: Format .gn file."; | 31 "format: Format .gn file."; |
33 const char kFormat_Help[] = | 32 const char kFormat_Help[] = |
34 "gn format [--dump-tree] [--in-place] [--stdin] BUILD.gn\n" | 33 "gn format [--dump-tree] [--stdin | <build_file> ]\n" |
scottmg
2016/08/05 17:31:48
no space between file> and ]. Or probably better t
| |
35 "\n" | 34 "\n" |
36 " Formats .gn file to a standard format.\n" | 35 " Formats .gn file to a standard format.\n" |
37 "\n" | 36 "\n" |
38 " The contents of some lists ('sources', 'deps', etc.) will be sorted to\n" | 37 " The contents of some lists ('sources', 'deps', etc.) will be sorted to\n" |
39 " a canonical order. To suppress this, you can add a comment of the form\n" | 38 " a canonical order. To suppress this, you can add a comment of the form\n" |
40 " \"# NOSORT\" immediately preceeding the assignment. e.g.\n" | 39 " \"# NOSORT\" immediately preceeding the assignment. e.g.\n" |
41 "\n" | 40 "\n" |
42 " # NOSORT\n" | 41 " # NOSORT\n" |
43 " sources = [\n" | 42 " sources = [\n" |
44 " \"z.cc\",\n" | 43 " \"z.cc\",\n" |
45 " \"a.cc\",\n" | 44 " \"a.cc\",\n" |
46 " ]\n" | 45 " ]\n" |
47 "\n" | 46 "\n" |
48 "Arguments\n" | 47 "Arguments\n" |
48 "\n" | |
49 " --dry-run\n" | 49 " --dry-run\n" |
50 " Does not change or output anything, but sets the process exit code\n" | 50 " Does not change or output anything, but sets the process exit code\n" |
51 " based on whether output would be different than what's on disk.\n" | 51 " based on whether output would be different than what's on disk.\n" |
52 " This is useful for presubmit/lint-type checks.\n" | 52 " This is useful for presubmit/lint-type checks.\n" |
53 " - Exit code 0: successful format, matches on disk.\n" | 53 " - Exit code 0: successful format, matches on disk.\n" |
54 " - Exit code 1: general failure (parse error, etc.)\n" | 54 " - Exit code 1: general failure (parse error, etc.)\n" |
55 " - Exit code 2: successful format, but differs from on disk.\n" | 55 " - Exit code 2: successful format, but differs from on disk.\n" |
56 "\n" | 56 "\n" |
57 " --dump-tree\n" | 57 " --dump-tree\n" |
58 " For debugging only, dumps the parse tree.\n" | 58 " For debugging only, dumps the parse tree.\n" |
59 "\n" | 59 "\n" |
60 " --in-place\n" | |
61 " Instead of writing the formatted file to stdout, replace the input\n" | |
62 " file with the formatted output. If no reformatting is required,\n" | |
63 " the input file will not be touched, and nothing printed.\n" | |
64 "\n" | |
65 " --stdin\n" | 60 " --stdin\n" |
66 " Read input from stdin (and write to stdout). Not compatible with\n" | 61 " Read input from stdin and write to stdout rather than update\n" |
67 " --in-place of course.\n" | 62 " a file in-place.\n" |
68 "\n" | 63 "\n" |
69 "Examples\n" | 64 "Examples\n" |
70 " gn format //some/BUILD.gn\n" | 65 " gn format //some/BUILD.gn\n" |
71 " gn format some\\BUILD.gn\n" | 66 " gn format some\\BUILD.gn\n" |
72 " gn format /abspath/some/BUILD.gn\n" | 67 " gn format /abspath/some/BUILD.gn\n" |
73 " gn format --stdin\n"; | 68 " gn format --stdin\n"; |
74 | 69 |
75 namespace { | 70 namespace { |
76 | 71 |
77 const int kIndentSize = 2; | 72 const int kIndentSize = 2; |
(...skipping 917 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
995 return true; | 990 return true; |
996 } | 991 } |
997 | 992 |
998 int RunFormat(const std::vector<std::string>& args) { | 993 int RunFormat(const std::vector<std::string>& args) { |
999 bool dry_run = | 994 bool dry_run = |
1000 base::CommandLine::ForCurrentProcess()->HasSwitch(kSwitchDryRun); | 995 base::CommandLine::ForCurrentProcess()->HasSwitch(kSwitchDryRun); |
1001 bool dump_tree = | 996 bool dump_tree = |
1002 base::CommandLine::ForCurrentProcess()->HasSwitch(kSwitchDumpTree); | 997 base::CommandLine::ForCurrentProcess()->HasSwitch(kSwitchDumpTree); |
1003 bool from_stdin = | 998 bool from_stdin = |
1004 base::CommandLine::ForCurrentProcess()->HasSwitch(kSwitchStdin); | 999 base::CommandLine::ForCurrentProcess()->HasSwitch(kSwitchStdin); |
1005 bool in_place = | |
1006 base::CommandLine::ForCurrentProcess()->HasSwitch(kSwitchInPlace); | |
1007 | 1000 |
1008 if (dry_run) { | 1001 if (dry_run) { |
1009 // --dry-run only works with an actual file to compare to. | 1002 // --dry-run only works with an actual file to compare to. |
1010 from_stdin = false; | 1003 from_stdin = false; |
1011 in_place = true; | |
1012 } | 1004 } |
1013 | 1005 |
1014 if (from_stdin) { | 1006 if (from_stdin) { |
1015 if (args.size() != 0) { | 1007 if (args.size() != 0) { |
1016 Err(Location(), "Expecting no arguments when reading from stdin.\n") | 1008 Err(Location(), "Expecting no arguments when reading from stdin.\n") |
1017 .PrintToStdout(); | 1009 .PrintToStdout(); |
1018 return 1; | 1010 return 1; |
1019 } | 1011 } |
1020 std::string input = ReadStdin(); | 1012 std::string input = ReadStdin(); |
1021 std::string output; | 1013 std::string output; |
(...skipping 18 matching lines...) Expand all Loading... | |
1040 Err err; | 1032 Err err; |
1041 SourceFile file = source_dir.ResolveRelativeFile(Value(nullptr, args[0]), | 1033 SourceFile file = source_dir.ResolveRelativeFile(Value(nullptr, args[0]), |
1042 &err); | 1034 &err); |
1043 if (err.has_error()) { | 1035 if (err.has_error()) { |
1044 err.PrintToStdout(); | 1036 err.PrintToStdout(); |
1045 return 1; | 1037 return 1; |
1046 } | 1038 } |
1047 | 1039 |
1048 std::string output_string; | 1040 std::string output_string; |
1049 if (FormatFileToString(&setup, file, dump_tree, &output_string)) { | 1041 if (FormatFileToString(&setup, file, dump_tree, &output_string)) { |
1050 if (in_place) { | 1042 if (dump_tree) { |
scottmg
2016/08/05 17:31:48
It's a bit weird that dump_tree means that it does
| |
1043 // Print nothing else (the tree was already printed). | |
1044 } else if (from_stdin) { | |
scottmg
2016/08/05 17:31:48
I don't think this is ever reached. If it's from_s
| |
1045 // Write formatted output to stdout. | |
1046 printf("%s", output_string.c_str()); | |
1047 } else { | |
1048 // Update the file in-place. | |
1051 base::FilePath to_write = setup.build_settings().GetFullPath(file); | 1049 base::FilePath to_write = setup.build_settings().GetFullPath(file); |
1052 std::string original_contents; | 1050 std::string original_contents; |
1053 if (!base::ReadFileToString(to_write, &original_contents)) { | 1051 if (!base::ReadFileToString(to_write, &original_contents)) { |
1054 Err(Location(), std::string("Couldn't read \"") + | 1052 Err(Location(), std::string("Couldn't read \"") + |
1055 to_write.AsUTF8Unsafe() + | 1053 to_write.AsUTF8Unsafe() + |
1056 std::string("\" for comparison.")).PrintToStdout(); | 1054 std::string("\" for comparison.")).PrintToStdout(); |
1057 return 1; | 1055 return 1; |
1058 } | 1056 } |
1059 if (dry_run) | 1057 if (dry_run) |
1060 return original_contents == output_string ? 0 : 2; | 1058 return original_contents == output_string ? 0 : 2; |
1061 if (original_contents != output_string) { | 1059 if (original_contents != output_string) { |
1062 if (base::WriteFile(to_write, | 1060 if (base::WriteFile(to_write, |
1063 output_string.data(), | 1061 output_string.data(), |
1064 static_cast<int>(output_string.size())) == -1) { | 1062 static_cast<int>(output_string.size())) == -1) { |
1065 Err(Location(), | 1063 Err(Location(), |
1066 std::string("Failed to write formatted output back to \"") + | 1064 std::string("Failed to write formatted output back to \"") + |
1067 to_write.AsUTF8Unsafe() + std::string("\".")).PrintToStdout(); | 1065 to_write.AsUTF8Unsafe() + std::string("\".")).PrintToStdout(); |
1068 return 1; | 1066 return 1; |
1069 } | 1067 } |
1070 printf("Wrote formatted to '%s'.\n", to_write.AsUTF8Unsafe().c_str()); | 1068 printf("Wrote formatted to '%s'.\n", to_write.AsUTF8Unsafe().c_str()); |
1071 } | 1069 } |
1072 } else { | |
1073 printf("%s", output_string.c_str()); | |
1074 } | 1070 } |
1075 } | 1071 } |
1076 | 1072 |
1077 return 0; | 1073 return 0; |
1078 } | 1074 } |
1079 | 1075 |
1080 } // namespace commands | 1076 } // namespace commands |
OLD | NEW |