Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(111)

Side by Side Diff: tools/gn/command_format.cc

Issue 2219703003: Format GN files in-place by default. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: comments Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
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, dumps the parse tree to stdout and does not update\n"
59 "\n" 59 " the file or print formatted output.\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" 60 "\n"
65 " --stdin\n" 61 " --stdin\n"
66 " Read input from stdin (and write to stdout). Not compatible with\n" 62 " Read input from stdin and write to stdout rather than update\n"
67 " --in-place of course.\n" 63 " a file in-place.\n"
68 "\n" 64 "\n"
69 "Examples\n" 65 "Examples\n"
70 " gn format //some/BUILD.gn\n" 66 " gn format //some/BUILD.gn\n"
71 " gn format some\\BUILD.gn\n" 67 " gn format some\\BUILD.gn\n"
72 " gn format /abspath/some/BUILD.gn\n" 68 " gn format /abspath/some/BUILD.gn\n"
73 " gn format --stdin\n"; 69 " gn format --stdin\n";
74 70
75 namespace { 71 namespace {
76 72
77 const int kIndentSize = 2; 73 const int kIndentSize = 2;
(...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after
917 return true; 913 return true;
918 } 914 }
919 915
920 return false; 916 return false;
921 } 917 }
922 918
923 void DoFormat(const ParseNode* root, bool dump_tree, std::string* output) { 919 void DoFormat(const ParseNode* root, bool dump_tree, std::string* output) {
924 if (dump_tree) { 920 if (dump_tree) {
925 std::ostringstream os; 921 std::ostringstream os;
926 root->Print(os, 0); 922 root->Print(os, 0);
927 printf("----------------------\n");
928 printf("-- PARSE TREE --------\n");
929 printf("----------------------\n");
930 printf("%s", os.str().c_str()); 923 printf("%s", os.str().c_str());
931 printf("----------------------\n");
932 } 924 }
933 Printer pr; 925 Printer pr;
934 pr.Block(root); 926 pr.Block(root);
935 *output = pr.String(); 927 *output = pr.String();
936 } 928 }
937 929
938 std::string ReadStdin() { 930 std::string ReadStdin() {
939 static const int kBufferSize = 256; 931 static const int kBufferSize = 256;
940 char buffer[kBufferSize]; 932 char buffer[kBufferSize];
941 std::string result; 933 std::string result;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
995 return true; 987 return true;
996 } 988 }
997 989
998 int RunFormat(const std::vector<std::string>& args) { 990 int RunFormat(const std::vector<std::string>& args) {
999 bool dry_run = 991 bool dry_run =
1000 base::CommandLine::ForCurrentProcess()->HasSwitch(kSwitchDryRun); 992 base::CommandLine::ForCurrentProcess()->HasSwitch(kSwitchDryRun);
1001 bool dump_tree = 993 bool dump_tree =
1002 base::CommandLine::ForCurrentProcess()->HasSwitch(kSwitchDumpTree); 994 base::CommandLine::ForCurrentProcess()->HasSwitch(kSwitchDumpTree);
1003 bool from_stdin = 995 bool from_stdin =
1004 base::CommandLine::ForCurrentProcess()->HasSwitch(kSwitchStdin); 996 base::CommandLine::ForCurrentProcess()->HasSwitch(kSwitchStdin);
1005 bool in_place =
1006 base::CommandLine::ForCurrentProcess()->HasSwitch(kSwitchInPlace);
1007 997
1008 if (dry_run) { 998 if (dry_run) {
1009 // --dry-run only works with an actual file to compare to. 999 // --dry-run only works with an actual file to compare to.
1010 from_stdin = false; 1000 from_stdin = false;
1011 in_place = true;
1012 } 1001 }
1013 1002
1014 if (from_stdin) { 1003 if (from_stdin) {
1015 if (args.size() != 0) { 1004 if (args.size() != 0) {
1016 Err(Location(), "Expecting no arguments when reading from stdin.\n") 1005 Err(Location(), "Expecting no arguments when reading from stdin.\n")
1017 .PrintToStdout(); 1006 .PrintToStdout();
1018 return 1; 1007 return 1;
1019 } 1008 }
1020 std::string input = ReadStdin(); 1009 std::string input = ReadStdin();
1021 std::string output; 1010 std::string output;
1022 if (!FormatStringToString(input, dump_tree, &output)) 1011 if (!FormatStringToString(input, dump_tree, &output))
1023 return 1; 1012 return 1;
1024 printf("%s", output.c_str()); 1013 if (!dump_tree)
1014 printf("%s", output.c_str());
1025 return 0; 1015 return 0;
1026 } 1016 }
1027 1017
1028 // TODO(scottmg): Eventually, this should be a list/spec of files, and they 1018 // TODO(scottmg): Eventually, this should be a list/spec of files, and they
1029 // should all be done in parallel. 1019 // should all be done in parallel.
1030 if (args.size() != 1) { 1020 if (args.size() != 1) {
1031 Err(Location(), "Expecting exactly one argument, see `gn help format`.\n") 1021 Err(Location(), "Expecting exactly one argument, see `gn help format`.\n")
1032 .PrintToStdout(); 1022 .PrintToStdout();
1033 return 1; 1023 return 1;
1034 } 1024 }
1035 1025
1036 Setup setup; 1026 Setup setup;
1037 SourceDir source_dir = 1027 SourceDir source_dir =
1038 SourceDirForCurrentDirectory(setup.build_settings().root_path()); 1028 SourceDirForCurrentDirectory(setup.build_settings().root_path());
1039 1029
1040 Err err; 1030 Err err;
1041 SourceFile file = source_dir.ResolveRelativeFile(Value(nullptr, args[0]), 1031 SourceFile file = source_dir.ResolveRelativeFile(Value(nullptr, args[0]),
1042 &err); 1032 &err);
1043 if (err.has_error()) { 1033 if (err.has_error()) {
1044 err.PrintToStdout(); 1034 err.PrintToStdout();
1045 return 1; 1035 return 1;
1046 } 1036 }
1047 1037
1048 std::string output_string; 1038 std::string output_string;
1049 if (FormatFileToString(&setup, file, dump_tree, &output_string)) { 1039 if (FormatFileToString(&setup, file, dump_tree, &output_string)) {
1050 if (in_place) { 1040 if (!dump_tree) {
1041 // Update the file in-place.
1051 base::FilePath to_write = setup.build_settings().GetFullPath(file); 1042 base::FilePath to_write = setup.build_settings().GetFullPath(file);
1052 std::string original_contents; 1043 std::string original_contents;
1053 if (!base::ReadFileToString(to_write, &original_contents)) { 1044 if (!base::ReadFileToString(to_write, &original_contents)) {
1054 Err(Location(), std::string("Couldn't read \"") + 1045 Err(Location(), std::string("Couldn't read \"") +
1055 to_write.AsUTF8Unsafe() + 1046 to_write.AsUTF8Unsafe() +
1056 std::string("\" for comparison.")).PrintToStdout(); 1047 std::string("\" for comparison.")).PrintToStdout();
1057 return 1; 1048 return 1;
1058 } 1049 }
1059 if (dry_run) 1050 if (dry_run)
1060 return original_contents == output_string ? 0 : 2; 1051 return original_contents == output_string ? 0 : 2;
1061 if (original_contents != output_string) { 1052 if (original_contents != output_string) {
1062 if (base::WriteFile(to_write, 1053 if (base::WriteFile(to_write,
1063 output_string.data(), 1054 output_string.data(),
1064 static_cast<int>(output_string.size())) == -1) { 1055 static_cast<int>(output_string.size())) == -1) {
1065 Err(Location(), 1056 Err(Location(),
1066 std::string("Failed to write formatted output back to \"") + 1057 std::string("Failed to write formatted output back to \"") +
1067 to_write.AsUTF8Unsafe() + std::string("\".")).PrintToStdout(); 1058 to_write.AsUTF8Unsafe() + std::string("\".")).PrintToStdout();
1068 return 1; 1059 return 1;
1069 } 1060 }
1070 printf("Wrote formatted to '%s'.\n", to_write.AsUTF8Unsafe().c_str()); 1061 printf("Wrote formatted to '%s'.\n", to_write.AsUTF8Unsafe().c_str());
1071 } 1062 }
1072 } else {
1073 printf("%s", output_string.c_str());
1074 } 1063 }
1075 } 1064 }
1076 1065
1077 return 0; 1066 return 0;
1078 } 1067 }
1079 1068
1080 } // namespace commands 1069 } // namespace commands
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698