title: Gradle: exclude (not skip) a task when it's up to date
body: <p>I'm looking for a way to avoid running dependencies of a task that is up to date (while still running any tasks that are dependencies of other, not up-to-date tasks).</p>
  
  <p>Take the following structure:</p>
  
  <pre><code>task stopService {}
  task startService {}
  task doUpdateA { // change something about the service }
  task doUpdateB { // change something else about the service }
  
  task updateA {
      inputs.files &lt;some inputs&gt;
      output.upToDateWhen { true }
      // i.e. run whenever inputs changed from previous run
  
      dependsOn stopService
      dependsOn doUpdateA
      dependsOn startService
  
      // ensure the service is stopped while it's being modified
      doUpdateA.mustRunAfter stopService
      startService.mustRunAfter doUpdateA
  }
  
  
  task updateB {
      inputs.files &lt;some inputs&gt;
      output.upToDateWhen { true }
      // i.e. run whenever inputs changed from previous run
  
      dependsOn stopService
      dependsOn doUpdateB
      dependsOn startService
  
      // ensure the service is stopped while it's being modified
      doUpdateB.mustRunAfter stopService
      startService.mustRunAfter doUpdateB
  }
  
  task updateAll {
      dependsOn updateA
      dependsOn updateB
  }
  </code></pre>
  
  <p>The desired execution flow for <code>./gradlew updateAll</code>:</p>
  
  <ul>
  <li>If both updateA and updateB are up to date, do nothing</li>
  <li>If one of them is not up to date, <code>stopService -&gt; doUpdateX -&gt; startService</code></li>
  <li>If both of them are not up to date, <code>stopService -&gt; doUpdateA -&gt; doUpdateB -&gt; startService</code> (or B before A).</li>
  </ul>
  
  <p>Is this possible, perhaps by hooking into the task execution graph and manually running upToDate on all tasks, then excluding them if they are up to date? Assume no task makes another task out of date.</p>
  
  <p>---- Half-solutions:</p>
  
  <p>If I ignore the third requirement, this can be somewhat solved by doing:
      task updateB {
          inputs.files 
          output.upToDateWhen { true }
          // i.e. run whenever inputs changed from previous run</p>
  
  <pre><code>    doLast {
          stopService.execute()
          doUpdateB.execute()
          startService.execute()
      }
  }
  </code></pre>
  
  <p>but that's suboptimal for a couple reasons - dependencies / finalisers (i think?) of stop/startService won't be ran, each update will cause a separate stop/start (making the build much longer), etc.</p>
  
  <p>If you ignore requirement 1, something like:</p>
  
  <pre><code>task updateAll {
      inputs.files &lt;some inputs&gt;
      output.upToDateWhen { true }
      // i.e. run whenever inputs changed from previous run
  
      dependsOn stopService
      dependsOn doUpdateA
      dependsOn doUpdateB
      dependsOn startService
  
      doUpdateB.mustRunAfter stopService
      startService.mustRunAfter doUpdateB
      doUpdateA.mustRunAfter stopService
      startService.mustRunAfter doUpdateA
  }
  </code></pre>
  
  <p>with up-to-date checks moved to doUpdateX works, but again is suboptimal for reasons this margin is too short to contain.</p>
  
  <p>Thanks in advance for any suggestions,</p>