internal static void AddTargets(this MSBuildSettings settings, PublishBehaviour behaviour) { foreach (var target in GetTargets(behaviour)) { settings.WithTarget(target); } }
public static List <string> ToTargets(this PublishBehaviour behaviour) { var targets = new List <string>() { "PrepareForBuild" }; switch (behaviour) { case PublishBehaviour.None: targets.Add("Build", "Publish"); break; case PublishBehaviour.CleanFirst: targets.Add("Clean", "Build", "Publish"); break; case PublishBehaviour.DoNotBuild: targets.Add("Publish"); break; default: throw new ArgumentOutOfRangeException(nameof(behaviour), behaviour, null); } return(targets); }
/// <summary> /// Publishes the app to the given folder /// </summary> /// <param name="targetPath">Folder to publsh the project too</param> /// <param name="behaviour">Preferred treatment of previous builds</param> /// <returns>The collection of results from the output handlers</returns> public List <HandlerResponse> PublishApp(string targetPath, PublishBehaviour behaviour = PublishBehaviour.CleanFirst) { var results = InputHandlers.ProcessHandlers( new FilePath(ProjectFilePath).GetDirectory().MakeAbsolute(Environment).FullPath, s => Log(s)); Log( $"Completed processing input handlers: {results.Count(r => r.Result == HandlerResult.OK)} OK, {results.Count(r => r.Result == HandlerResult.Error)} errors, {results.Count(r => r.Result == HandlerResult.NotRun)} not run"); if (results.Any(r => r.Result == HandlerResult.Error)) { throw new HandlerProcessingException(InputHandlers, results); } string outputPath; if (behaviour == PublishBehaviour.DoNotBuild) { outputPath = Path.Combine(new FileInfo(ProjectFilePath).Directory.FullName, "bin", Configuration); BuildAction = null; } else { outputPath = System.IO.Path.Combine(System.IO.Path.GetTempPath(), Guid.NewGuid().ToString("N")); if (!FileSystem.Exist((DirectoryPath)outputPath)) { FileSystem.GetDirectory(outputPath).Create(); } } var props = new Dictionary <string, string> { { "Configuration", Configuration }, { "Platform", Platform }, { "OutputPath", outputPath }, { "PublishDir", Path.Combine(outputPath, "app.publish") + "\\" } }; BuildSettings = new MSBuildSettings { Configuration = Configuration, MSBuildPlatform = GetMSBuildPlatform(Platform), Verbosity = Verbosity.Quiet }; BuildSettings.AddTargets(behaviour); BuildSettings.AddProperties(props, AdditionalProperties); BuildAction?.Invoke(this); var publishDir = new DirectoryPath( new DirectoryInfo(props["OutputPath"]).GetDirectories() .FirstOrDefault(d => d.Name == "app.publish") .FullName); if (GenerateManifest) { PrepareManifestManager(publishDir, InformationSource.Both); ManifestManager.DeployManifest(ManifestManager.CreateAppManifest()); } Log("Processing output handlers"); var output = OutputHandlers.ProcessHandlers(publishDir.FullPath, s => Log(s)); Log( $"Completed processing output handlers: {output.Count(r => r.Result == HandlerResult.OK)} OK, {output.Count(r => r.Result == HandlerResult.Error)} errors, {output.Count(r => r.Result == HandlerResult.NotRun)} not run"); if (output.Any(o => o.Result == HandlerResult.Error) && ErrorAction != null) { Log("Error encountered while processing output handlers. Aborting!"); ErrorAction?.Invoke(output); //throw new HandlerProcessingException(OutputHandlers, output); // in case something goes real wrong } if (string.IsNullOrWhiteSpace(targetPath)) { return(output); } Log("Copying publish results to target directory"); new DirectoryInfo(publishDir.MakeAbsolute(Environment).FullPath).Copy(destDirPath: targetPath, copySubDirs: true); return(output); }
/// <exception cref="HandlerProcessingException">Thrown when input or output handlers encounter an exception.</exception> /// <exception cref="OperationInProgressException">Thrown when a build or publish operation is already in progress.</exception> /// <exception cref="ArgumentOutOfRangeException">Invalid behaviour type provided.</exception> /// <exception cref="SecurityException">The caller does not have the required permission. </exception> /// <exception cref="BuildFailedException">Thrown when the build fails.</exception> public virtual List <HandlerResponse> PublishApp(string targetPath, PublishBehaviour behaviour = PublishBehaviour.CleanFirst) { var path = Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), "ClickTwice", Guid.NewGuid().ToString("N") + "\\")); if (!File.Exists(ProjectFilePath)) { throw new FileNotFoundException( $"Project file not found at path {ProjectFilePath}! Please ensure you have provided a valid csproj file.", ProjectFilePath); } Log("Configuring build environment"); var props = new Dictionary <string, string> { { "Configuration", Configuration }, { "Platform", Platform }, { "OutputPath", path.FullName } }; props = props.Concat(AdditionalProperties.Where(p => !props.ContainsKey(p.Key))) .ToDictionary(k => k.Key, v => v.Value); Log("Processing input handlers"); var results = ProcessInputHandlers(); Log($"Completed processing input handlers: {results.Count(r => r.Result == HandlerResult.OK)} OK, {results.Count(r => r.Result == HandlerResult.Error)} errors, {results.Count(r => r.Result == HandlerResult.NotRun)} not run"); if (results.All(r => r.Result != HandlerResult.Error)) { var targets = behaviour.ToTargets(); Log("Running additional configurators"); var configurators = RunConfigurators(props, targets); props = configurators.Key; targets = configurators.Value; Log($"Build configured for targets: {string.Join(", ", targets)}"); List <HandlerResponse> outResults = new List <HandlerResponse>(); var success = BuildProject(props, targets); if (success) { var publishDir = path.GetDirectories().FirstOrDefault(d => d.Name == "app.publish"); PostBuild(publishDir); Log("Processing output handlers"); outResults = ProcessOutputHandlers(publishDir); Log( $"Completed processing output handlers: {outResults.Count(r => r.Result == HandlerResult.OK)} OK, {outResults.Count(r => r.Result == HandlerResult.Error)} errors, {outResults.Count(r => r.Result == HandlerResult.NotRun)} not run"); if (outResults.Any(o => o.Result == HandlerResult.Error)) { Log("Error encountered while processing output handlers. Aborting!"); throw new HandlerProcessingException(OutputHandlers, outResults); } if (!string.IsNullOrWhiteSpace(targetPath)) { Log("Copying publish results to target directory"); publishDir.Copy(destDirPath: targetPath, copySubDirs: true); } } else { throw new BuildFailedException(); } CloseLoggers(targetPath); if (!CleanOutputOnCompletion) { return(outResults); } Log("Cleaning build output directory"); Directory.Delete(path.FullName, true); return(outResults); } Log("Error encountered while processing input handlers. Aborting!"); throw new HandlerProcessingException(InputHandlers, results); }