// NAnt - A .NET build tool
// Copyright (C) 2001-2003 Gerry Shaw
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// Matthew Mastracci (matt@aclaro.com)
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Globalization;
using System.IO;
using System.Xml;
using NAnt.Core;
using NAnt.Core.Util;
namespace NAnt.VSNet {
public class ProjectSettings {
#region Public Instance Constructors
public ProjectSettings(XmlElement elemRoot, XmlElement elemSettings, ManagedProjectBase project) {
_project = project;
_settings = new ArrayList();
// check whether build file is valid
if (elemRoot.FirstChild == null) {
throw new BuildException(string.Format(CultureInfo.InvariantCulture,
"Project file '{0}' is not valid.", Project.ProjectPath),
Location.UnknownLocation);
}
_guid = ProjectSettings.GetProjectGuid(project.ProjectPath,
elemRoot);
// determine output type of this project
_outputType = GetOutputType(elemSettings);
// initialize hashtable for holding string settings
Hashtable htStringSettings = new Hashtable();
switch (_outputType) {
case ManagedOutputType.Library:
_settings.Add("/target:library");
break;
case ManagedOutputType.Executable:
_settings.Add("/target:exe");
// startup object only makes sense for executable assemblies
htStringSettings["StartupObject"] = @"/main:""{0}""";
break;
case ManagedOutputType.WindowsExecutable:
_settings.Add("/target:winexe");
// startup object only makes sense for executable assemblies
htStringSettings["StartupObject"] = @"/main:""{0}""";
break;
}
// suppresses display of Microsoft startup banner
_settings.Add("/nologo");
_assemblyName = elemSettings.Attributes["AssemblyName"].Value;
// the key file to use to sign ActiveX/COM wrappers
_assemblyOriginatorKeyFile = StringUtils.ConvertEmptyToNull(
elemSettings.Attributes["AssemblyOriginatorKeyFile"].Value);
// the key container to use to sign ActiveX/COM wrappers
_assemblyKeyContainerName = StringUtils.ConvertEmptyToNull(
elemSettings.Attributes["AssemblyKeyContainerName"].Value);
// pre and post build events are VS .NET 2003 specific, so do not
// assume they are there
if (elemSettings.Attributes["RunPostBuildEvent"] != null) {
_runPostBuildEvent = StringUtils.ConvertEmptyToNull(
elemSettings.Attributes["RunPostBuildEvent"].Value);
}
if (elemSettings.Attributes["PreBuildEvent"] != null) {
_preBuildEvent = StringUtils.ConvertEmptyToNull(
elemSettings.Attributes["PreBuildEvent"].Value);
}
if (elemSettings.Attributes["PostBuildEvent"] != null) {
_postBuildEvent = StringUtils.ConvertEmptyToNull(
elemSettings.Attributes["PostBuildEvent"].Value);
}
if (elemSettings.Attributes["RootNamespace"] != null) {
_rootNamespace = StringUtils.ConvertEmptyToNull(
elemSettings.Attributes["RootNamespace"].Value);
if (RootNamespace != null && Project.Type == ProjectType.VB) {
_settings.Add("/rootnamespace:" + _rootNamespace);
}
}
if (elemSettings.Attributes["ApplicationIcon"] != null) {
string value = StringUtils.ConvertEmptyToNull(
elemSettings.Attributes["ApplicationIcon"].Value);
if (value != null) {
_applicationIcon = new FileInfo(FileUtils.CombinePaths(
Project.ProjectDirectory.FullName, value));
}
}
// process VB.NET specific project settings
if (Project.Type == ProjectType.VB) {
if (elemSettings.Attributes["OptionExplicit"] != null) {
if (elemSettings.Attributes ["OptionExplicit"].Value == "Off") {
_settings.Add("/optionexplicit-");
} else {
_settings.Add("/optionexplicit+");
}
}
if (elemSettings.Attributes["OptionStrict"] != null) {
if (elemSettings.Attributes ["OptionStrict"].Value == "Off") {
_settings.Add("/optionstrict-");
} else {
_settings.Add("/optionstrict+");
}
}
if (elemSettings.Attributes["OptionCompare"] != null) {
if (elemSettings.Attributes ["OptionCompare"].Value == "Text") {
_settings.Add("/optioncompare:text");
} else {
_settings.Add("/optioncompare:binary");
}
}
}
foreach (DictionaryEntry de in htStringSettings) {
string value = elemSettings.GetAttribute(de.Key.ToString());
if (StringUtils.IsNullOrEmpty(value)) {
// skip empty values
continue;
}
_settings.Add(string.Format(de.Value.ToString(), value));
}
}
#endregion Public Instance Constructors
#region Public Instance Properties
public string[] Settings {
get { return (string[]) _settings.ToArray(typeof(string)); }
}
///
/// Gets the .ico file to use as application icon.
///
///
/// The .ico file to use as application icon, or
/// if no application icon should be used.
///
public FileInfo ApplicationIcon {
get { return _applicationIcon; }
}
public string AssemblyName {
get { return _assemblyName; }
}
///
/// Gets the key file to use to sign ActiveX/COM wrappers.
///
///
/// The path of the key file to use to sign ActiveX/COM wrappers,
/// relative to the project root directory, or
/// if the wrapper assembly should not be signed using a key file.
///
public string AssemblyOriginatorKeyFile {
get { return _assemblyOriginatorKeyFile; }
}
///
/// Gets the key name to use to sign ActiveX/COM wrappers.
///
///
/// The name of the key container to use to sign ActiveX/COM wrappers,
/// or if the wrapper assembly should not be
/// signed using a key container.
///
public string AssemblyKeyContainerName {
get { return _assemblyKeyContainerName; }
}
public TempFileCollection TemporaryFiles {
get { return Project.TemporaryFiles; }
}
public string OutputFileName {
get { return string.Concat(AssemblyName, OutputExtension); }
}
///
/// Gets the output type of this project.
///
public ManagedOutputType OutputType {
get { return _outputType; }
}
public string OutputExtension {
get {
switch (OutputType) {
case ManagedOutputType.Library:
return ".dll";
case ManagedOutputType.Executable:
case ManagedOutputType.WindowsExecutable:
default:
return ".exe";
}
}
}
public string RootNamespace {
get { return _rootNamespace; }
}
public string Guid {
get { return _guid; }
}
///
/// Designates when the command line should
/// be run. Possible values are "OnBuildSuccess", "Always" or
/// "OnOutputUpdated".
///
public string RunPostBuildEvent {
get { return _runPostBuildEvent; }
}
///
/// Contains commands to be run before a build takes place.
///
///
/// Valid commands are those in a .bat file. For more info see MSDN.
///
public string PreBuildEvent {
get { return _preBuildEvent; }
}
///
/// Contains commands to be ran after a build has taken place.
///
///
/// Valid commands are those in a .bat file. For more info see MSDN.
///
public string PostBuildEvent {
get { return _postBuildEvent; }
}
#endregion Public Instance Properties
#region Private Instance Properties
private ManagedProjectBase Project {
get { return _project; }
}
#endregion Private Instance Properties
#region Protected Instance Methods
///
/// Determines the output type of the project from its XML definition.
///
/// The XML definition of the project settings.
///
/// The output type of the project.
///
///
///
/// The output type of the project is not set in the specified XML
/// definition.
///
/// -or-
///
/// The output type of the project is not supported.
///
///
protected virtual ManagedOutputType GetOutputType(XmlElement settingsXml) {
XmlAttribute outputTypeAttribute = settingsXml.Attributes["OutputType"];
if (outputTypeAttribute == null) {
throw new BuildException(string.Format(CultureInfo.InvariantCulture,
"Project \"{0}\" is invalid: the output type is not set.",
Project.Name), Location.UnknownLocation);
}
switch (outputTypeAttribute.Value.ToLower(CultureInfo.InvariantCulture)) {
case "library":
return ManagedOutputType.Library;
case "exe":
return ManagedOutputType.Executable;
case "winexe":
return ManagedOutputType.WindowsExecutable;
default:
throw new BuildException(string.Format(CultureInfo.InvariantCulture,
"Output type \"{0}\" of project \"{1}\" is not supported.",
outputTypeAttribute.Value, Project.Name), Location.UnknownLocation);
}
}
#endregion Protected Instance Methods
#region Public Static Methods
///
/// Gets the project GUID from the given
/// holding a <VisualStudioProject> node.
///
/// The path of the project file.
/// The <VisualStudioProject> node from which the project GUID should be retrieved.
///
/// The project GUID from specified <VisualStudioProject> node.
///
public static string GetProjectGuid(string projectFile, XmlElement elemRoot) {
XmlAttribute projectGuid = (XmlAttribute) elemRoot.FirstChild.
Attributes["ProjectGuid"];
if (projectGuid == null) {
throw new BuildException(string.Format(CultureInfo.InvariantCulture,
"Project file '{0}' is not valid. There's no \"ProjectGuid\""
+ " attribute on the <{1} ... /> node.", projectFile,
elemRoot.FirstChild.Name), Location.UnknownLocation);
}
return projectGuid.Value.ToUpper(CultureInfo.InvariantCulture);
}
#endregion Public Static Methods
#region Public Instance Methods
public string GetTemporaryFilename(string fileName) {
return FileUtils.CombinePaths(TemporaryFiles.BasePath, fileName);
}
#endregion Public Instance Methods
#region Private Instance Fields
private readonly ArrayList _settings;
private readonly FileInfo _applicationIcon;
private readonly ManagedProjectBase _project;
private readonly string _assemblyName;
private readonly string _assemblyOriginatorKeyFile;
private readonly string _assemblyKeyContainerName;
private readonly string _rootNamespace;
private readonly string _guid;
private readonly string _runPostBuildEvent;
private readonly string _preBuildEvent;
private readonly string _postBuildEvent;
private readonly ManagedOutputType _outputType;
#endregion Private Instance Fields
}
}