public bool ShouldBuild(BuildInstance instance)
{
// do comparisons in order from cheapest to most expensive to try to early out when a change is obvious
// check 1: see if we have history for this output
HistoryEntry entry;
if (!history.TryGetValue(instance.OutputName.ToLower(), out entry))
return true;
// check 3: make sure the byproducts match
var byproductSet = instance.Byproducts.Select(b => b.ToLower()).ToSet();
if (!byproductSet.SetEquals(entry.Byproducts))
return true;
// check 4: compare number and type of pipeline stages
var node = instance.Pipeline;
for (int i = 0; i < entry.StageTypes.Count; i++)
{
if (node == null || node.GetType() != entry.StageTypes[i])
return true;
node = node.InputNode;
}
// any nodes left over mean that the pipeline was changed
if (node != null)
return true;
// check 5: check for pipeline processor changes
node = instance.Pipeline;
foreach (var stage in entry.StageHashes)
{
if (stage != node.Hash())
return true;
node = node.InputNode;
}
// check 6: changes in inputs
if (instance.Env.InputChangeDetection != ChangeDetection.None)
{
for (int i = 0; i < instance.Inputs.Length; i++)
{
if (CheckChanged(instance.Env.InputChangeDetection, new FileInfo(instance.Inputs[i]), entry.InputCache[i]))
return true;
}
}
// check 7: changes in outputs
if (instance.Env.OutputChangeDetection != ChangeDetection.None)
{
if (CheckChanged(instance.Env.OutputChangeDetection, new FileInfo(instance.OutputPath), entry.OutputCache[0]))
return true;
for (int i = 0; i < instance.Byproducts.Length; i++)
{
if (CheckChanged(instance.Env.OutputChangeDetection, new FileInfo(instance.Byproducts[i]), entry.OutputCache[i + 1]))
return true;
}
}
// check 8: look at any dependent temp builds and see if they have been changed
if (instance.Env.InputChangeDetection != ChangeDetection.None)
{
if (entry.TempDependencies.Any(t => TempInputsHaveChanged(t, instance.Env.InputChangeDetection)))
return true;
}
// at this point, we can safely say that the entire pipeline is the same. no need to do a build
// however, some of our dependencies may have changed, so let them sort themselves out
foreach (var dependency in entry.Dependencies)
context.Start(dependency);
return false;
}