#develop (short for SharpDevelop) is a free IDE for .NET programming languages.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

338 lines
12 KiB

// SharpDevelop samples
// Copyright (c) 2007, AlphaSierraPapa
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// - Redistributions of source code must retain the above copyright notice, this list
// of conditions and the following disclaimer.
//
// - Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
//
// - Neither the name of the SharpDevelop team nor the names of its contributors may be used to
// endorse or promote products derived from this software without specific prior written
// permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS &AS IS& AND ANY EXPRESS
// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using System;
using System.ComponentModel;
using System.IO;
using ICSharpCode.Core;
using ICSharpCode.NAnt.Gui;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.SharpDevelop.Util;
namespace ICSharpCode.NAnt.Commands
{
/// <summary>
/// The base class for all commands that run NAnt.
/// </summary>
public abstract class AbstractRunNAntCommand : AbstractMenuCommand
{
/// <summary>
/// The default NAnt build filename.
/// </summary>
public static readonly string DefaultBuildFileName = "default.build";
/// <summary>
/// The default NAnt build file extension.
/// </summary>
public static readonly string NAntBuildFileExtension = ".build";
const int Win32FileNotFoundErrorCode = 2;
const int Win32PathNotFoundErrorCode = 3;
static MessageViewCategory category;
static NAntRunner runner;
public AbstractRunNAntCommand()
{
if (runner == null) {
runner = NAntRunnerSingleton.Runner;
runner.NAntExited += new NAntExitEventHandler(NAntExited);
runner.OutputLineReceived += new LineReceivedEventHandler(OutputLineReceived);
}
}
public override void Run()
{
}
public static bool IsActiveConfigurationDebug {
get {
bool isDebug = false;
IProject project = ProjectService.CurrentProject;
if (project != null) {
if (String.Compare(project.ActiveConfiguration, "debug", true) == 0) {
isDebug = true;
}
}
return isDebug;
}
}
/// <summary>
/// Gets the NAnt build filename from the selected project.
/// </summary>
/// <remarks>
/// <para>The basic logic is:</para>
/// <para>Look for a file called "default.build".</para>
/// <para>Look for a file named after the project
/// "<projectName>.build".</para>
/// <para>Look for the first ".build" file in the project.</para>
/// <para>If multiple ".build" files exist then, like NAnt,
/// this is an error, but currently we ignore this.</para>
/// <para>Note that this does not look in the project folder
/// for a .build file that is not added to the project.
/// </para>
/// </remarks>
/// <returns>The build filename for the project.</returns>
protected string GetProjectBuildFileName()
{
string fileName = String.Empty;
IProject project = ProjectService.CurrentProject;
// Look for "default.build".
string projectFileName = project.FileName;
string buildFileName = Path.Combine(Path.GetDirectoryName(projectFileName), DefaultBuildFileName);
if (project.IsFileInProject(buildFileName)) {
fileName = buildFileName;
} else {
// Look for <projectname>.build
buildFileName = Path.ChangeExtension(projectFileName, NAntBuildFileExtension);
if (project.IsFileInProject(buildFileName)) {
fileName = buildFileName;
} else {
// Look for the first matching .build file.
ProjectItem projectItem = GetFirstMatchingFile(project, NAntBuildFileExtension);
if (projectItem != null) {
fileName = projectItem.FileName;
} else {
throw new NAntAddInException("Project does not contain a '.build' file.");
}
}
}
return fileName;
}
/// <summary>
/// Runs any pre-build steps such as saving changed files.
/// </summary>
protected void RunPreBuildSteps()
{
//ProjectService.DoBeforeCompileAction();
TaskService.ClearExceptCommentTasks();
}
/// <summary>
/// Runs the default target in the NAnt build.
/// </summary>
/// <param name="buildFileName">The build file to run.</param>
/// <param name="workingDirectory">The working folder for NAnt.</param>
/// <param name="debug">Flag indicating whether to set the NAnt debug property.</param>
protected void RunBuild(string buildFileName, string workingDirectory, bool debug)
{
RunBuild(buildFileName, workingDirectory, debug, String.Empty, String.Empty);
}
protected void RunBuild(string buildFileName, string workingDirectory, bool debug, string target)
{
RunBuild(buildFileName, workingDirectory, debug, target, String.Empty);
}
/// <summary>
/// Runs the specified target in the NAnt build.
/// </summary>
/// <param name="buildFileName">The build file to run.</param>
/// <param name="workingDirectory">The working folder for NAnt.</param>
/// <param name="debug">Flag indicating whether to set the NAnt debug property.</param>
/// <param name="target">The NAnt target to run.</param>
/// <param name="args">Command line arguments to pass to NAnt.</param>
protected void RunBuild(string buildFileName, string workingDirectory, bool debug, string target, string args)
{
if (IsBuildRunning) {
throw new NAntAddInException("A NAnt build is currently running.");
}
Category.ClearText();
ShowOutputPad();
runner.BuildFileName = buildFileName;
runner.NAntFileName = AddInOptions.NAntFileName;
runner.Verbose = AddInOptions.Verbose;
runner.WorkingDirectory = workingDirectory;
runner.Quiet = AddInOptions.Quiet;
runner.ShowLogo = AddInOptions.ShowLogo;
runner.DebugMode = AddInOptions.DebugMode;
if (debug) {
runner.Arguments = String.Concat("-D:debug=true ", AddInOptions.NAntArguments, " ", args, " ", target);
} else {
runner.Arguments = String.Concat(AddInOptions.NAntArguments, " ", args, " ", target);
}
CategoryWriteLine(StringParser.Parse("Running NAnt."));
CategoryWriteLine(runner.CommandLine);
try {
runner.Start();
} catch (Win32Exception ex) {
if (ex.NativeErrorCode == Win32FileNotFoundErrorCode || ex.NativeErrorCode == Win32PathNotFoundErrorCode) {
throw new NAntAddInException(GetNAntNotFoundErrorMessage(AddInOptions.NAntFileName), ex);
} else {
throw;
}
}
}
/// <summary>
/// Gets any extra arguments from the NAnt pad's text box.
/// </summary>
protected string GetPadTextBoxArguments()
{
string arguments = String.Empty;
IWorkbench Workbench = ICSharpCode.SharpDevelop.Gui.WorkbenchSingleton.Workbench;
PadDescriptor padDescriptor = Workbench.GetPad(typeof(NAntPadContent));
if (padDescriptor != null && padDescriptor.PadContent != null) {
arguments = ((NAntPadContent)padDescriptor.PadContent).Arguments;
}
return arguments;
}
/// <summary>
/// Stops the currently running build.
/// </summary>
protected void StopBuild()
{
if (IsBuildRunning) {
if (MessageService.AskQuestion(StringParser.Parse("This will terminate the NAnt process. Are you sure?"))) {
runner.Stop();
CategoryWriteLine(StringParser.Parse("NAnt build stopped."));
}
}
}
protected bool IsBuildRunning {
get {
return runner.IsRunning;
}
}
/// <summary>
/// Gets the NAnt message view output window.
/// </summary>
MessageViewCategory Category {
get {
if (category == null) {
category = new MessageViewCategory("NAnt");
CompilerMessageView cmv = (CompilerMessageView)WorkbenchSingleton.Workbench.GetPad(typeof(CompilerMessageView)).PadContent;
cmv.AddCategory(category);
}
return category;
}
}
/// <summary>
/// Writes a line of text to the output window.
/// </summary>
void CategoryWriteLine(string message)
{
Category.AppendText(String.Concat(message, Environment.NewLine));
}
/// <summary>
/// Brings output pad to the front.
/// </summary>
void ShowOutputPad()
{
WorkbenchSingleton.Workbench.GetPad(typeof(CompilerMessageView)).BringPadToFront();
}
/// <summary>
/// Looks for the first file that matches the specified
/// file extension.
/// </summary>
/// <param name="extension">A filename extension.</param>
/// <returns>A ProjectItem that has the specified extension,
/// or null.</returns>
ProjectItem GetFirstMatchingFile(IProject project, string extension)
{
foreach (ProjectItem projectItem in project.Items) {
string projectFileNameExtension = Path.GetExtension(projectItem.FileName);
if (String.Compare(projectFileNameExtension, extension, true) == 0) {
return projectItem;
}
}
return null;
}
/// <summary>
/// Displays the output from NAnt after it has exited.
/// </summary>
/// <param name="sender">The event source.</param>
/// <param name="e">The NAnt exit event arguments.</param>
void NAntExited(object sender, NAntExitEventArgs e)
{
// Update output window.
string outputText = String.Empty;
System.Diagnostics.Debug.Assert(e.Error.Length == 0);
outputText = String.Concat(outputText, e.Output);
// Update task list.
TaskCollection tasks = NAntOutputParser.Parse(outputText);
foreach (Task task in tasks) {
WorkbenchSingleton.SafeThreadAsyncCall(TaskService.Add, task);
}
// Bring task list to front.
if (tasks.Count > 0 && ErrorListPad.ShowAfterBuild) {
IWorkbench workbench = ICSharpCode.SharpDevelop.Gui.WorkbenchSingleton.Workbench;
PadDescriptor padDescriptor = workbench.GetPad(typeof(ErrorListPad));
if (padDescriptor != null) {
WorkbenchSingleton.SafeThreadAsyncCall(padDescriptor.BringPadToFront);
}
}
}
void OutputLineReceived(object sender, LineReceivedEventArgs e)
{
CategoryWriteLine(e.Line);
}
string GetNAntNotFoundErrorMessage(string fileName)
{
string formatString = "Unable to find NAnt '{0}'.\r\n\r\n" +
"Please configure the NAnt executable's location in the SharpDevelop Options.";
return String.Format(formatString, fileName);
}
}
}