5
// Michael Hutchinson <mhutchinson@novell.com>
7
// Copyright (c) 2010 Novell, Inc.
9
// Permission is hereby granted, free of charge, to any person obtaining a copy
10
// of this software and associated documentation files (the "Software"), to deal
11
// in the Software without restriction, including without limitation the rights
12
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
// copies of the Software, and to permit persons to whom the Software is
14
// furnished to do so, subject to the following conditions:
16
// The above copyright notice and this permission notice shall be included in
17
// all copies or substantial portions of the Software.
19
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28
using System.Collections.Generic;
29
using MonoDevelop.Projects;
30
using MonoDevelop.Core;
31
using MonoDevelop.Core.Execution;
32
using System.Diagnostics;
33
using MonoDevelop.MacDev.Plist;
36
using MonoDevelop.Core.ProgressMonitoring;
39
namespace MonoDevelop.MacDev
41
public static class MacBuildUtilities
43
public static bool NeedsBuilding (FilePair fp)
45
return fp.NeedsBuilding ();
48
public static int ExecuteBuildCommand (IProgressMonitor monitor, System.Diagnostics.ProcessStartInfo startInfo)
50
return ExecuteBuildCommand (monitor, startInfo, null, null);
53
/// <summary>Executes a build command, writing output to the monitor.</summary>
54
/// <returns>Whether the command executed successfully.</returns>
55
/// <param name='monitor'>Progress monitor for writing output and handling cancellation.</param>
56
/// <param name='startInfo'>Process start info. Redirection will be enabled if necessary.</param>
57
/// <param name='stdout'>Text writer for stdout. May be null.</param>
58
/// <param name='stderr'>Text writer for stderr. May be null.</param>
59
public static int ExecuteBuildCommand (IProgressMonitor monitor, ProcessStartInfo startInfo,
60
TextWriter stdout, TextWriter stderr)
62
monitor.Log.WriteLine (startInfo.FileName + " " + startInfo.Arguments);
64
startInfo.UseShellExecute = false;
65
startInfo.RedirectStandardError = true;
66
startInfo.RedirectStandardOutput = true;
70
TextWriter outWriter = monitor.Log, errWriter = monitor.Log;
71
LogTextWriter chainedOut = null, chainedErr = null;
74
chainedOut = new LogTextWriter ();
75
chainedOut.ChainWriter (outWriter);
76
chainedOut.ChainWriter (stdout);
77
outWriter = chainedOut;
81
chainedErr = new LogTextWriter ();
82
chainedErr.ChainWriter (errWriter);
83
chainedErr.ChainWriter (stderr);
84
errWriter = chainedErr;
87
var operationMonitor = new AggregatedOperationMonitor (monitor);
89
IProcessAsyncOperation p = null;
91
p = Runtime.ProcessService.StartProcess (startInfo, outWriter, errWriter, null);
92
operationMonitor.AddOperation (p); //handles cancellation
93
p.WaitForCompleted ();
94
exitCode = p.ExitCode;
96
if (chainedErr != null)
97
chainedErr.Dispose ();
98
if (chainedOut != null)
99
chainedOut.Dispose ();
102
operationMonitor.Dispose ();
106
monitor.Log.WriteLine ("{0} exited with code {1}", Path.GetFileName (startInfo.FileName), exitCode);
111
public static BuildResult CreateMergedPlist (IProgressMonitor monitor,
112
ProjectFile template, string outPath,
113
Func<PlistDocument,BuildResult> merge)
115
var result = new BuildResult ();
117
var doc = new PlistDocument ();
118
if (template != null) {
120
doc.LoadFromXmlFile (template.FilePath);
121
} catch (Exception ex) {
122
if (ex is XmlException)
123
result.AddError (template.FilePath, ((XmlException)ex).LineNumber,
124
((XmlException)ex).LinePosition, null, ex.Message);
126
result.AddError (template.FilePath, 0, 0, null, ex.Message);
127
monitor.ReportError (GettextCatalog.GetString ("Could not load file '{0}': {1}",
128
template.FilePath, ex.Message), null);
134
if (result.Append (merge (doc)).ErrorCount > 0)
136
} catch (Exception ex) {
137
result.AddError ("Error merging Info.plist: " + ex.Message);
138
LoggingService.LogError ("Error merging Info.plist", ex);
143
EnsureDirectoryForFile (outPath);
144
doc.WriteToFile (outPath);
145
} catch (Exception ex) {
146
result.AddError (outPath, 0, 0, null, ex.Message);
147
monitor.ReportError (GettextCatalog.GetString ("Could not write file '{0}'", outPath), ex);
152
public static void EnsureDirectoryForFile (string filename)
154
string dir = Path.GetDirectoryName (filename);
155
if (!Directory.Exists (dir))
156
Directory.CreateDirectory (dir);
159
public static ProcessStartInfo GetTool (string tool, DotNetProject project, IProgressMonitor monitor,
160
out BuildResult error)
162
var toolPath = project.TargetRuntime.GetToolPath (project.TargetFramework, tool);
163
if (String.IsNullOrEmpty (toolPath)) {
164
var err = GettextCatalog.GetString ("Error: Unable to find '{0}' tool.", tool);
165
monitor.ReportError (err, null);
166
error = new BuildResult ();
167
error.AddError (null, 0, 0, null, err);
172
return new ProcessStartInfo (toolPath) {
173
UseShellExecute = false,
174
RedirectStandardError = true,
175
RedirectStandardOutput = true,
180
public struct FilePair
182
public FilePair (FilePath input, FilePath output)
185
this.Output = output;
188
public FilePath Input, Output;
190
public bool NeedsBuilding ()
192
var output = new FileInfo (Output);
196
var input = new FileInfo (Input);
197
return input.LastWriteTimeUtc > output.LastWriteTimeUtc;
200
public void EnsureOutputDirectory ()
202
if (!Directory.Exists (Output.ParentDirectory))
203
Directory.CreateDirectory (Output.ParentDirectory);
b'\\ No newline at end of file'