Permalink
Browse files

move logic out of depgraph and into SchedulableActionCollector

  • Loading branch information...
1 parent 0bf1459 commit 9bc54cbd3bdb0f6670be0f4327fcda748ad94148 Lucas Meijer committed Apr 15, 2012
Showing with 141 additions and 52 deletions.
  1. +22 −0 ActionScheduler.cs
  2. +15 −52 DependencyGraph.cs
  3. +71 −0 SchedulableActionCollector.cs
  4. +3 −0 Tests/GeneratedHeader.cs
  5. +28 −0 Tests/SchedulableActionCollectorTest.cs
  6. +2 −0 cake.csproj
View
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.IO;
using System.Linq;
namespace cake
@@ -8,6 +9,11 @@ public class ActionScheduler
{
private readonly Dictionary<TargetGenerateSettings, HashSet<string>> _scheduledActions = new Dictionary<TargetGenerateSettings, HashSet<string>>();
+ public bool AnyJobsLeft
+ {
+ get { return _scheduledActions.Any(); }
+ }
+
public void Add(SchedulableAction schedulableAction)
{
_scheduledActions.Add(schedulableAction.Settings, new HashSet<string>(schedulableAction.InputFilesRequiringGeneration));
@@ -18,6 +24,7 @@ public TargetGenerateSettings FindJobToRun()
var findJobToRun = _scheduledActions.Where(kvp => kvp.Value.Count == 0).Select(kvp=>kvp.Key).FirstOrDefault();
if (findJobToRun!=null)
_scheduledActions.Remove(findJobToRun);
+
return findJobToRun;
}
@@ -29,5 +36,20 @@ public void JobFinished(TargetGenerateSettings finishedJob)
deps.Remove(outputFile);
}
}
+
+ public void VerifyAllInputFilesArePresentOrWillBeGenerated()
+ {
+ foreach(var scheduledAction in _scheduledActions.Keys)
+ {
+ foreach(var inputFile in scheduledAction.InputFiles)
+ {
+ if (File.Exists(inputFile))
+ continue;
+ if (_scheduledActions.Keys.Any(sa=>sa.OutputFiles.Contains(inputFile)))
+ continue;
+ throw new MissingDependencyException();
+ }
+ }
+ }
}
}
View
@@ -7,9 +7,9 @@ namespace cake
{
public class DependencyGraph
{
- readonly Dictionary<string, TargetGenerateSettings> _graph = new Dictionary<string, TargetGenerateSettings>();
+ public readonly Dictionary<string, TargetGenerateSettings> _graph = new Dictionary<string, TargetGenerateSettings>();
public Action<TargetGenerateSettings> GenerateCallback = s => { };
- private readonly BuildHistory _buildHistory;
+ public readonly BuildHistory _buildHistory;
public DependencyGraph() : this(new BuildHistory())
{
@@ -23,63 +23,26 @@ public DependencyGraph(BuildHistory history)
public void RequestTarget(string targetFile)
{
var actionScheduler = new ActionScheduler();
-
- var action = ActionRequiredToGetTargetUpdated(targetFile);
- if (action == null)
- return;
-
- actionScheduler.Add(action);
- var job = actionScheduler.FindJobToRun();
+ var c = new SchedulableActionCollector(this);
+ var actions = c.CollectActionsToGenerate(targetFile);
- Generate(job);
- }
+ foreach(var action in actions)
+ actionScheduler.Add(action);
- SchedulableAction ActionRequiredToGetTargetUpdated(string target)
- {
- TargetGenerateSettings generateSettings;
- if (!_graph.TryGetValue(target, out generateSettings))
+ actionScheduler.VerifyAllInputFilesArePresentOrWillBeGenerated();
+
+ while (actionScheduler.AnyJobsLeft)
{
- if (File.Exists(target))
- return null;
- throw new MissingDependencyException();
+ var job = actionScheduler.FindJobToRun();
+ if (job==null)
+ throw new InvalidOperationException("No job is available to run, while there are still scheduled jobs left.");
+ Generate(job);
+ actionScheduler.JobFinished(job);
}
-
- var inputFilesRequiringGeneration = generateSettings.InputFiles.Where(inputfile => ActionRequiredToGetTargetUpdated(inputfile) != null);
-
- if (inputFilesRequiringGeneration.Any())
- return new SchedulableAction(generateSettings, inputFilesRequiringGeneration);
-
- if (NeedToGenerate(target))
- return new SchedulableAction(generateSettings);
-
- return null;
- }
-
- private bool NeedToGenerate(string targetFile)
- {
- TargetGenerateSettings generateSettings = _graph[targetFile];
-
- var recordOfLastBuild = _buildHistory.FindRecordFor(targetFile);
-
- if (recordOfLastBuild == null)
- return true;
-
- if (!File.Exists(targetFile))
- return true;
-
- if (!generateSettings.Equals(recordOfLastBuild.Settings))
- return true;
-
- if (File.GetLastWriteTimeUtc(targetFile) < recordOfLastBuild.ModificationTimeOfTargetFile())
- return true;
-
- if (generateSettings.InputFiles.Any(inputFile => File.GetLastWriteTimeUtc(inputFile) > recordOfLastBuild.ModificationTimeOf(inputFile)))
- return true;
-
- return false;
}
+
private void Generate(TargetGenerateSettings settings)
{
GenerateCallback(settings);
@@ -0,0 +1,71 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+
+namespace cake
+{
+ public class SchedulableActionCollector
+ {
+ private readonly DependencyGraph _dependencyGraph;
+
+ public SchedulableActionCollector(DependencyGraph dependencyGraph)
+ {
+ _dependencyGraph = dependencyGraph;
+ }
+
+ public IEnumerable<SchedulableAction> CollectActionsToGenerate(string targetFile)
+ {
+ var result = ActionRequiredToGetTargetUpdated(targetFile);
+ if (result != null)
+ yield return result;
+ }
+
+ SchedulableAction ActionRequiredToGetTargetUpdated(string target)
+ {
+ TargetGenerateSettings generateSettings;
+ if (!_dependencyGraph._graph.TryGetValue(target, out generateSettings))
+ {
+ return null;
+ //if (File.Exists(target))
+ // return null;
+ //throw new MissingDependencyException();
+ }
+
+ var inputFilesRequiringGeneration = generateSettings.InputFiles.Where(inputfile => ActionRequiredToGetTargetUpdated(inputfile) != null).ToArray();
+
+ if (inputFilesRequiringGeneration.Any())
+ return new SchedulableAction(generateSettings, inputFilesRequiringGeneration);
+
+ if (NeedToGenerate(target))
+ return new SchedulableAction(generateSettings);
+
+ return null;
+ }
+
+ private bool NeedToGenerate(string targetFile)
+ {
+ TargetGenerateSettings generateSettings = _dependencyGraph._graph[targetFile];
+
+ var recordOfLastBuild = _dependencyGraph._buildHistory.FindRecordFor(targetFile);
+
+ if (recordOfLastBuild == null)
+ return true;
+
+ if (!File.Exists(targetFile))
+ return true;
+
+ if (!generateSettings.Equals(recordOfLastBuild.Settings))
+ return true;
+
+ if (File.GetLastWriteTimeUtc(targetFile) < recordOfLastBuild.ModificationTimeOfTargetFile())
+ return true;
+
+ if (generateSettings.InputFiles.Any(inputFile => File.GetLastWriteTimeUtc(inputFile) > recordOfLastBuild.ModificationTimeOf(inputFile)))
+ return true;
+
+ return false;
+ }
+
+ }
+}
View
@@ -19,6 +19,9 @@ public void Test()
File.WriteAllText("file1","//theboss");
File.WriteAllText("test.c","#include <myheader.h>");
+
+ //temp:
+ File.WriteAllText("myheader.h","doesalreadyexisttemporary" );
var compilecppfile = new CCompilerTask("test.o", "test.c", new string[] {});
_depGraph.RegisterTarget(generateHeaderSettings);
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using cake;
+using cake.Tests;
+using NUnit.Framework;
+
+namespace bs.Tests
+{
+ [TestFixture]
+ class SchedulableActionCollectorTest
+ {
+ [Test]
+ public void CanCollectSingleAction()
+ {
+ var depGraph = new DependencyGraph();
+ var a = new SchedulableActionCollector(depGraph);
+
+ var settings = new TargetGenerateSettings(new SimpleAction(s=> { }), new[] {"input"}, "output");
+ depGraph.RegisterTarget(settings);
+ var result = a.CollectActionsToGenerate("output").ToArray();
+
+ Assert.AreEqual(1, result.Length);
+ Assert.AreEqual(settings,result[0].Settings);
+ }
+ }
+}
View
@@ -58,6 +58,7 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RecursiveIncludeScanner.cs" />
<Compile Include="SchedulableAction.cs" />
+ <Compile Include="SchedulableActionCollector.cs" />
<Compile Include="TargetGenerateSettings.cs" />
<Compile Include="CCompilerTask.cs" />
<Compile Include="GenerationReason.cs" />
@@ -71,6 +72,7 @@
<Compile Include="IncludeScanner.cs" />
<Compile Include="Tests\GeneratedHeader.cs" />
<Compile Include="Tests\IncludeScannerTest.cs" />
+ <Compile Include="Tests\SchedulableActionCollectorTest.cs" />
<Compile Include="Tests\SimpleAction.cs" />
<Compile Include="Tests\SimpleCopyDepGraph.cs" />
<Compile Include="ITargetGeneratingAction.cs" />

0 comments on commit 9bc54cb

Please sign in to comment.