/// <summary> /// Runs this builder /// </summary> /// <param name="context"> </param> /// <returns>Returns a set of generated files, in suite relative paths</returns> public ISet <TargetRelativePath> Run(IBuildContext context) { var buildKey = new BuildKey(wrappedBuilder.BuilderType, wrappedBuilder.Uid); cache.LockForBuilder(buildKey); try { if (wrappedBuilder.CanRun()) { try { var currentFingerprint = wrappedBuilder.Dependencies.Fingerprint; if (cache.Contains(buildKey, currentFingerprint)) { log.DebugFormat("Restoring cached build outputs for {0}", buildKey); return(cache.Restore(buildKey, targetDir, aggressive, agressiveModeExceptions)); } else { log.DebugFormat("Running builder {0}", buildKey); var files = wrappedBuilder.Run(context); log.DebugFormat("Storing build outputs of {0}", buildKey); cache.Store(buildKey, currentFingerprint, files, targetDir); return(files); } } catch (Exception ex) { log.ErrorFormat("Failed to run builder {0}: {1}", wrappedBuilder.Uid, ex); // Fallback to any cached value if (SupportsFallback && cache.ContainsAny(buildKey)) { log.DebugFormat("Restoring cached build outputs for {0} without fingerprint check", buildKey); return(cache.Restore(buildKey, targetDir, aggressive, agressiveModeExceptions)); } else { throw; } } } else { // Fallback to any cached value if (cache.ContainsAny(buildKey)) { log.DebugFormat("Restoring cached build outputs for {0} without fingerprint check", buildKey); return(cache.Restore(buildKey, targetDir, aggressive, agressiveModeExceptions)); } else { throw new BuilderCantRunException(wrappedBuilder.Uid); } } } finally { cache.UnlockForBuilder(buildKey); } }