dry run flag
authorEvan Martin <martine@danga.com>
Mon, 13 Dec 2010 16:36:57 +0000 (08:36 -0800)
committerEvan Martin <martine@danga.com>
Mon, 13 Dec 2010 16:37:05 +0000 (08:37 -0800)
src/build.cc
src/build.h
src/ninja.cc
todo

index 262fee5..0666f8e 100644 (file)
@@ -212,6 +212,29 @@ Edge* RealCommandRunner::NextFinishedCommand(bool* success) {
   return edge;
 }
 
+struct DryRunCommandRunner : public CommandRunner {
+  virtual ~DryRunCommandRunner() {}
+  virtual bool CanRunMore() {
+    return true;
+  }
+  virtual bool StartCommand(Edge* edge) {
+    finished_.push(edge);
+    return true;
+  }
+  virtual void WaitForCommands() {
+  }
+  virtual Edge* NextFinishedCommand(bool* success) {
+    if (finished_.empty())
+      return NULL;
+    *success = true;
+    Edge* edge = finished_.front();
+    finished_.pop();
+    return edge;
+  }
+
+  queue<Edge*> finished_;
+};
+
 Builder::Builder(State* state)
     : state_(state) {
   disk_interface_ = new RealDiskInterface;
@@ -223,6 +246,11 @@ void Builder::SetVerbose(bool verbose) {
   log_->verbose_ = verbose;
 }
 
+void Builder::SetDryRun(bool on) {
+  if (on)
+    command_runner_ = new DryRunCommandRunner;
+}
+
 Node* Builder::AddTarget(const string& name, string* err) {
   Node* node = state_->LookupNode(name);
   if (!node) {
index e362226..caadb85 100644 (file)
@@ -61,6 +61,7 @@ struct Builder {
   Builder(State* state);
 
   void SetVerbose(bool verbose);
+  void SetDryRun(bool on);
 
   Node* AddTarget(const string& name, string* err);
   bool Build(string* err);
index fab3f3a..0b2af68 100644 (file)
@@ -20,6 +20,7 @@ void usage() {
 "options:\n"
 "  -g       output graphviz dot file for targets and exit\n"
 "  -i FILE  specify input build file [default=build.ninja]\n"
+"  -n       dry run (don't run commands but pretend they succeeded)\n"
 "  -v       show all command lines\n"
           );
 }
@@ -34,8 +35,8 @@ int main(int argc, char** argv) {
   const char* input_file = "build.ninja";
 
   int opt;
-  bool graph = false, verbose = false;
-  while ((opt = getopt_long(argc, argv, "ghi:v", options, NULL)) != -1) {
+  bool dry_run = false, graph = false, verbose = false;
+  while ((opt = getopt_long(argc, argv, "ghi:nv", options, NULL)) != -1) {
     switch (opt) {
       case 'g':
         graph = true;
@@ -43,6 +44,9 @@ int main(int argc, char** argv) {
       case 'i':
         input_file = optarg;
         break;
+      case 'n':
+        dry_run = true;
+        break;
       case 'v':
         verbose = true;
         break;
@@ -87,6 +91,7 @@ int main(int argc, char** argv) {
 
   Builder builder(&state);
   builder.SetVerbose(verbose);
+  builder.SetDryRun(dry_run);
   for (int i = 0; i < argc; ++i) {
     if (!builder.AddTarget(argv[i], &err)) {
       if (!err.empty()) {
diff --git a/todo b/todo
index 94a03ee..ad1b3c7 100644 (file)
--- a/todo
+++ b/todo
@@ -2,7 +2,6 @@ save command lines
   or use mtimes on build files?
 "explain" mode that shows why we're building a file
 "one file" mode that builds only outputs of a single file
-"dry run" mode that shows command lines but doesn't build
 adjust to system load dynamically
 
 progress bar rather than printing commands in series