Merge "Clone repo if it is not on disk"
diff --git a/doc/source/conf.py b/doc/source/conf.py
index d7142ad..422f03c 100644
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -25,7 +25,7 @@
 
 # Add any Sphinx extension module names here, as strings. They can be extensions
 # coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
-extensions = []
+extensions = [ 'sphinxcontrib.blockdiag' ]
 #extensions = ['sphinx.ext.intersphinx']
 #intersphinx_mapping = {'python': ('http://docs.python.org/2.7', None)}
 
diff --git a/doc/source/gating.rst b/doc/source/gating.rst
index cf5964c..f3f2d3c 100644
--- a/doc/source/gating.rst
+++ b/doc/source/gating.rst
@@ -58,9 +58,15 @@
   A, B, C, D, E
 
 Zuul queues those changes in the order they were approved, and notes
-that each subsequent change depends on the one ahead of it merging::
+that each subsequent change depends on the one ahead of it merging:
 
-  A <-- B <-- C <-- D <-- E
+.. blockdiag::
+
+  blockdiag foo {
+    node_width = 40;
+    span_width = 40;
+    A <- B <- C <- D <- E;
+  }
 
 Zuul then starts immediately testing all of the changes in parallel.
 But in the case of changes that depend on others, it instructs the
@@ -74,23 +80,131 @@
   Jobs for D: merge changes A, B, C and D, then test
   Jobs for E: merge changes A, B, C, D and E, then test
 
-If changes *A* and *B* pass tests, and *C*, *D*, and *E* fail::
+Hence jobs triggered to tests A will only test A and ignore B, C, D:
 
-  A[pass] <-- B[pass] <-- C[fail] <-- D[fail] <-- E[fail]
+.. blockdiag::
 
-Zuul will merge change *A* followed by change *B*, leaving this queue::
+  blockdiag foo {
+    node_width = 40;
+    span_width = 40;
+    master -> A -> B -> C -> D -> E;
+    group jobs_for_A {
+        label = "Merged changes for A";
+        master -> A;
+    }
+    group ignored_to_test_A {
+        label = "Ignored changes";
+        color = "lightgray";
+        B -> C -> D -> E;
+    }
+  }
 
-  C[fail] <-- D[fail] <-- E[fail]
+The jobs for E would include the whole dependency chain: A, B, C, D, and E.
+E will be tested assuming A, B, C, and D passed:
+
+.. blockdiag::
+
+  blockdiag foo {
+    node_width = 40;
+    span_width = 40;
+    group jobs_for_E {
+        label = "Merged changes for E";
+        master -> A -> B -> C -> D -> E;
+    }
+  }
+
+If changes *A* and *B* pass tests (green), and *C*, *D*, and *E* fail (red):
+
+.. blockdiag::
+
+  blockdiag foo {
+    node_width = 40;
+    span_width = 40;
+
+    A [color = lightgreen];
+    B [color = lightgreen];
+    C [color = pink];
+    D [color = pink];
+    E [color = pink];
+
+    master <- A <- B <- C <- D <- E;
+  }
+
+Zuul will merge change *A* followed by change *B*, leaving this queue:
+
+.. blockdiag::
+
+  blockdiag foo {
+    node_width = 40;
+    span_width = 40;
+
+    C [color = pink];
+    D [color = pink];
+    E [color = pink];
+
+    C <- D <- E;
+  }
 
 Since *D* was dependent on *C*, it is not clear whether *D*'s failure is the
-result of a defect in *D* or *C*::
+result of a defect in *D* or *C*:
 
-  C[fail] <-- D[unknown] <-- E[unknown]
+.. blockdiag::
 
-Since *C* failed, it will report the failure and drop *C* from the queue::
+  blockdiag foo {
+    node_width = 40;
+    span_width = 40;
 
-  D[unknown] <-- E[unknown]
+    C [color = pink];
+    D [label = "D\n?"];
+    E [label = "E\n?"];
+
+    C <- D <- E;
+  }
+
+Since *C* failed, Zuul will report its failure and drop *C* from the queue,
+keeping D and E:
+
+.. blockdiag::
+
+  blockdiag foo {
+    node_width = 40;
+    span_width = 40;
+
+    D [label = "D\n?"];
+    E [label = "E\n?"];
+
+    D <- E;
+  }
 
 This queue is the same as if two new changes had just arrived, so Zuul
 starts the process again testing *D* against the tip of the branch, and
-*E* against *D*.
+*E* against *D*:
+
+.. blockdiag::
+
+  blockdiag foo {
+    node_width = 40;
+    span_width = 40;
+    master -> D -> E;
+    group jobs_for_D {
+        label = "Merged changes for D";
+        master -> D;
+    }
+    group ignored_to_test_D {
+        label = "Skip";
+        color = "lightgray";
+        E;
+    }
+  }
+
+.. blockdiag::
+
+  blockdiag foo {
+    node_width = 40;
+    span_width = 40;
+    group jobs_for_E {
+        label = "Merged changes for E";
+        master -> D -> E;
+    }
+  }
+
diff --git a/doc/source/launchers.rst b/doc/source/launchers.rst
index d8145ab..5e74bf6 100644
--- a/doc/source/launchers.rst
+++ b/doc/source/launchers.rst
@@ -49,7 +49,7 @@
 ``zuul.conf``.  Be sure that the host allows connections from Zuul and
 any workers (e.g., Jenkins masters) on TCP port 4730, and nowhere else
 (as the Gearman protocol does not include any provision for
-authentication.
+authentication).
 
 Gearman Jenkins Plugin
 ----------------------
diff --git a/doc/source/reporters.rst b/doc/source/reporters.rst
index 18d35a1..63a86c4 100644
--- a/doc/source/reporters.rst
+++ b/doc/source/reporters.rst
@@ -5,11 +5,11 @@
 
 Zuul can communicate results and progress back to configurable
 protocols. For example, after succeeding in a build a pipeline can be
-configured to post a positive review back to gerrit.
+configured to post a positive review back to Gerrit.
 
 There are three stages when a report can be handled. That is on:
 Start, Success or Failure. Each stage can have multiple reports.
-For example, you can set verified on gerrit and send an email.
+For example, you can set verified on Gerrit and send an email.
 
 Gerrit
 ------
@@ -18,7 +18,7 @@
 ``gerrit`` command over an SSH connection.  It reports back to
 Gerrit using SSH.
 
-The dictionary passed to the gerrit reporter is used for ``gerrit
+The dictionary passed to the Gerrit reporter is used for ``gerrit
 review`` arguments, with the boolean value of ``true`` simply
 indicating that the argument should be present without following it
 with a value. For example, ``verified: 1`` becomes ``gerrit review
@@ -28,7 +28,7 @@
 Gerrit Configuration
 ~~~~~~~~~~~~~~~~~~~~
 
-The configuration for posting back to gerrit is shared with the gerrit
+The configuration for posting back to Gerrit is shared with the Gerrit
 trigger in zuul.conf as described in :ref:`zuulconf`.
 
 SMTP
@@ -39,7 +39,7 @@
 SMTP Configuration
 ~~~~~~~~~~~~~~~~~~
 
-zuul.conf contains the smtp server and default to/from as describe
+zuul.conf contains the SMTP server and default to/from as describe
 in :ref:`zuulconf`.
 
 Each pipeline can overwrite the to or from address by providing
diff --git a/doc/source/statsd.rst b/doc/source/statsd.rst
index 7c9dfe2..d657fb2 100644
--- a/doc/source/statsd.rst
+++ b/doc/source/statsd.rst
@@ -4,7 +4,7 @@
 ================
 
 Zuul comes with support for the statsd protocol, when enabled and configured
-(see below), the Zuul scheduler will emit raw metrics to a Statsd receiver
+(see below), the Zuul scheduler will emit raw metrics to a statsd receiver
 which let you in turn generate nice graphics. An example is OpenStack Zuul
 status page: http://status.openstack.org/zuul/
 
@@ -14,9 +14,9 @@
 Statsd support uses the statsd python module. Note that Zuul will start without
 the statsd python module, so an existing Zuul installation may be missing it.
 
-The configuration is done via environnement variables STATSD_HOST and
+The configuration is done via environment variables STATSD_HOST and
 STATSD_PORT. They are interpreted by the statsd module directly and there is no
-such paremeter in zuul.conf yet. Your init script will have to initialize both
+such parameter in zuul.conf yet. Your init script will have to initialize both
 of them before launching Zuul.
 
 Your init script most probably loads a configuration file named
diff --git a/doc/source/zuul.rst b/doc/source/zuul.rst
index 6adfa30..6b5d7c9 100644
--- a/doc/source/zuul.rst
+++ b/doc/source/zuul.rst
@@ -314,7 +314,7 @@
 
     *email_filter*
     This is used for any event.  It takes a regex applied on the performer
-    email, i.e Gerrit account email address.  If you want to specify
+    email, i.e. Gerrit account email address.  If you want to specify
     several email filters, you must use a YAML list.  Make sure to use non
     greedy matchers and to escapes dots!
     Example: ``email_filter: ^.*?@example\.org$``.
@@ -453,7 +453,7 @@
 .. note::
   The ``change-merged`` event does not include the commit sha1 which can be
   hazardous, it would let you report back to Gerrit though.  If you were to
-  build a tarball for a specific commit, you should consider insteading using
+  build a tarball for a specific commit, you should consider instead using
   the ``ref-updated`` event which does include the commit sha1 (but lack the
   Gerrit change number).
 
@@ -601,11 +601,11 @@
 Project Templates
 """""""""""""""""
 
-Whenever you have lot of similiar projects (such as plugins for a project) you
+Whenever you have lot of similar projects (such as plugins for a project) you
 will most probably want to use the same pipeline configurations.  The
 project templates let you define pipelines and job name templates to trigger.
 One can then just apply the template on its project which make it easier to
-update several similiar projects. As an example::
+update several similar projects. As an example::
 
   project-templates:
     # Name of the template
@@ -672,7 +672,7 @@
 save these events prior to exiting. When Zuul starts again it will
 read these saved events and act on them.
 
-If you need to abort zuul and intend to manually requeue changes for
+If you need to abort Zuul and intend to manually requeue changes for
 jobs which were running in its pipelines, prior to terminating you can
 use the zuul-changes.py tool script to simplify the process. For
 example, this would give you a list of Gerrit commands to reverify or
diff --git a/requirements.txt b/requirements.txt
index 7b43b96..170b5152 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -12,6 +12,6 @@
 python-daemon
 extras
 statsd>=1.0.0,<3.0
-voluptuous>=0.6,<0.7
+voluptuous>=0.7
 gear>=0.4.0,<1.0.0
 apscheduler>=2.1.1,<3.0
diff --git a/test-requirements.txt b/test-requirements.txt
index b220203..90d4934 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -2,6 +2,7 @@
 
 coverage>=3.6
 sphinx>=1.1.2
+sphinxcontrib-blockdiag>=0.5.5
 docutils==0.9.1
 discover
 fixtures>=0.3.14
diff --git a/zuul/cmd/server.py b/zuul/cmd/server.py
index 6a699d3..710f35d 100755
--- a/zuul/cmd/server.py
+++ b/zuul/cmd/server.py
@@ -119,6 +119,8 @@
 
         logging.basicConfig(level=logging.DEBUG)
         self.sched = zuul.scheduler.Scheduler()
+        self.sched.registerReporter(None, 'gerrit')
+        self.sched.registerReporter(None, 'smtp')
         self.sched.registerTrigger(None, 'gerrit')
         self.sched.registerTrigger(None, 'timer')
         layout = self.sched.testConfig(self.config.get('zuul',
diff --git a/zuul/layoutvalidator.py b/zuul/layoutvalidator.py
index 0d08f1b..70c7101 100644
--- a/zuul/layoutvalidator.py
+++ b/zuul/layoutvalidator.py
@@ -97,7 +97,7 @@
             for k, v in value.items():
                 self.validateJob(v, path + [k])
         else:
-            self.job_name.validate(path, self.job_name.schema, value)
+            self.job_name.schema(value)
 
     def validateTemplateCalls(self, calls):
         """ Verify a project pass the parameters required