Improve GN clean command.

Previously it would detect a case where the build.ninja file was empty and write a default
one to replace it. This case is rare and the existing code was broken on Windows because
it used printf on a 16-bit file path. It's simpler to just issue an error in this case.

This also adds a small performance improvement by using StringPiece to split the build file
(saves allocating ~16K strings).

Change-Id: I8a4cb31a9e8614d8d14e821ff24434a57da55212
Reviewed-on: https://chromium-review.googlesource.com/602520
Reviewed-by: Bruce Dawson <brucedawson@chromium.org>
Commit-Queue: Brett Wilson <brettw@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#492124}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: f99f80fab8249df24e05e686e7b43e2d4ec574b5
diff --git a/tools/gn/command_clean.cc b/tools/gn/command_clean.cc
index f0348d9..8903986 100644
--- a/tools/gn/command_clean.cc
+++ b/tools/gn/command_clean.cc
@@ -22,21 +22,19 @@
 // On error, returns the empty string.
 std::string ExtractGNBuildCommands(const base::FilePath& build_ninja_file) {
   std::string file_contents;
-  if (!base::ReadFileToString(build_ninja_file, &file_contents)) {
+  if (!base::ReadFileToString(build_ninja_file, &file_contents))
     return std::string();
-  }
 
-  std::vector<std::string> lines = base::SplitString(
+  std::vector<base::StringPiece> lines = base::SplitStringPiece(
       file_contents, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
 
   std::string result;
   int num_blank_lines = 0;
   for (const auto& line : lines) {
-    result += line;
-    result += "\n";
-    if (line.empty()) {
+    line.AppendToString(&result);
+    result.push_back('\n');
+    if (line.empty())
       ++num_blank_lines;
-    }
     if (num_blank_lines == 2)
       break;
   }
@@ -44,15 +42,6 @@
   return result;
 }
 
-const char kDefaultNinjaFile[] =
-    "rule gn\n"
-    "  command = gn -q gen //out/%s/\n"
-    "  description = Regenerating ninja files\n"
-    "\n"
-    "build build.ninja: gn\n"
-    "  generator = 1\n"
-    "  depfile = build.ninja.d\n";
-
 }  // namespace
 
 namespace commands {
@@ -96,6 +85,13 @@
   // will automatically rerun GN the next time Ninja is run.
   base::FilePath build_ninja_file = build_dir.AppendASCII("build.ninja");
   std::string build_commands = ExtractGNBuildCommands(build_ninja_file);
+  if (build_commands.empty()) {
+    // Couldn't parse the build.ninja file.
+    Err(Location(), "Couldn't read build.ninja in this directory.",
+        "Try running \"gn gen\" on it and then re-running \"gn clean\".")
+        .PrintToStdout();
+    return 1;
+  }
 
   // Read the args.gn file, if any. Not all GN builds have one.
   base::FilePath gn_args_file = build_dir.AppendASCII("args.gn");
@@ -115,25 +111,11 @@
   }
 
   // Write the build.ninja file sufficiently to regenerate itself.
-  if (!build_commands.empty()) {
-    if (base::WriteFile(build_ninja_file, build_commands.data(),
-                        static_cast<int>(build_commands.size())) == -1) {
-      Err(Location(), std::string("Failed to write build.ninja."))
-          .PrintToStdout();
-      return 1;
-    }
-  } else {
-    // Couldn't parse the build.ninja file, write a default thing.
-    std::vector<base::FilePath::StringType> components;
-    build_ninja_file.GetComponents(&components);
-    std::string default_build_file = base::StringPrintf(
-        kDefaultNinjaFile, components[components.size() - 2].c_str());
-    if (base::WriteFile(build_ninja_file, default_build_file.data(),
-                        static_cast<int>(default_build_file.size())) == -1) {
-      Err(Location(), std::string("Failed to write build.ninja."))
-          .PrintToStdout();
-      return 1;
-    }
+  if (base::WriteFile(build_ninja_file, build_commands.data(),
+                      static_cast<int>(build_commands.size())) == -1) {
+    Err(Location(), std::string("Failed to write build.ninja."))
+        .PrintToStdout();
+    return 1;
   }
 
   // Write a .d file for the build which references a nonexistant file.