Skip to content

Commit

Permalink
Support for XBuild and command-line parsing
Browse files Browse the repository at this point in the history
 - XBuild is now supported on win32 by default (see #314)
 - msbuild or xbuild can be specified in descriptor files (see #313)
 - arguments to msbuild can be passed on the command line (closes #312)
  • Loading branch information
serialseb committed Apr 6, 2012
1 parent 0fb9ae2 commit e28e68e
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 17 deletions.
25 changes: 18 additions & 7 deletions src/OpenWrap.Commands/Wrap/BuildWrapCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
namespace OpenWrap.Commands.Wrap
{
[Command(Noun = "wrap", Verb = "build")]
public class BuildWrapCommand : AbstractCommand
public class BuildWrapCommand : AbstractCommand, ICommandWithWildcards
{
readonly IDirectory _currentDirectory;
readonly IFileSystem _fileSystem;
Expand All @@ -30,6 +30,7 @@ public class BuildWrapCommand : AbstractCommand
IEnvironment _environment;
SemanticVersion _generatedVersion;
IFile _sharedAssemblyInfoFile;
ILookup<string, string> _wildcards;

public BuildWrapCommand()
: this(ServiceLocator.GetService<IFileSystem>(), ServiceLocator.GetService<IEnvironment>())
Expand All @@ -41,6 +42,7 @@ public BuildWrapCommand(IFileSystem fileSystem, IEnvironment environment)
_fileSystem = fileSystem;
_environment = environment;
_currentDirectory = environment.CurrentDirectory;
_wildcards = new string[0].ToLookup(_ => _, _ => default(string));
}

[CommandInput]
Expand Down Expand Up @@ -206,7 +208,7 @@ static IPackageBuilder AssignProperties(IPackageBuilder builder, IEnumerable<IGr
var propertiesPi = builderType.GetProperty("Properties", BindingFlags.Instance | BindingFlags.Public);
if (propertiesPi != null && typeof(IEnumerable<IGrouping<string, string>>).IsAssignableFrom(propertiesPi.PropertyType))
{
var unknownLookup = unknown.ToLookup(x => x.Key, x => x.Value);
var unknownLookup = unknown.ToLookup(x => x.Key, x => x.Value, StringComparer.OrdinalIgnoreCase);
propertiesPi.SetValue(builder, unknownLookup, null);
}
return builder;
Expand Down Expand Up @@ -240,17 +242,22 @@ IEnumerable<ICommandOutput> Package()
IPackageBuilder ChooseBuilderInstance(string commandLine)
{
commandLine = commandLine.Trim();
if (commandLine.StartsWithNoCase("msbuild"))
var isMsBuild = commandLine.StartsWithNoCase("msbuild");
var isDefault = commandLine.StartsWithNoCase("default");
var isxbuild = commandLine.StartsWithNoCase("xbuild");
if (isMsBuild || isDefault || isxbuild)
{
var configValue = isDefault ? "default" : (isMsBuild ? "msbuild" : "xbuild");
var builder = new MSBuildPackageBuilder(_fileSystem, _environment, new DefaultFileBuildResultParser())
{
Incremental = Incremental
Incremental = Incremental,
BuildEngine = configValue
};
return builder;
}
if (commandLine.StartsWithNoCase("files"))
return new FilePackageBuilder();
if (commandLine.StartsWithNoCase("command"))
if (commandLine.StartsWithNoCase("command") || commandLine.StartsWithNoCase("process"))
return new CommandLinePackageBuilder(_fileSystem, _environment, new DefaultFileBuildResultParser());
if (commandLine.StartsWithNoCase("custom"))
return CreateCustomBuilder(commandLine);
Expand All @@ -273,7 +280,7 @@ IPackageBuilder CreateCustomBuilder(string commandLine)
IEnumerable<ICommandOutput> CreateBuilder()
{
_builders = (
from commandLine in _environment.Descriptor.Build.DefaultIfEmpty("msbuild")
from commandLine in _environment.Descriptor.Build.DefaultIfEmpty("default")
let builder = ChooseBuilderInstance(commandLine)
let parameters = ParseBuilderProperties(commandLine)
select AssignProperties(builder, OverrideWithInputs(parameters))
Expand Down Expand Up @@ -303,7 +310,7 @@ IEnumerable<IGrouping<string, string>> OverrideWithInputs(IEnumerable<IGrouping<
if (_sharedAssemblyInfoFile != null)
overrides.Add("OpenWrap-SharedAssemblyInfoFile", _sharedAssemblyInfoFile.Path.FullPath);

return overrides.GroupBy(x => x.Key, x => x.Value).Concat(parameters.Where(param => !overrides.ContainsKey(param.Key)));
return overrides.GroupBy(x => x.Key, x => x.Value).Concat(_wildcards.Concat(parameters).Where(param => !overrides.ContainsKey(param.Key)));

}

Expand Down Expand Up @@ -418,5 +425,9 @@ IEnumerable<ICommandOutput> Build()
_buildResults = _buildResults.Distinct().ToList();
}

public void Wildcards(ILookup<string, string> values)
{
_wildcards = values;
}
}
}
59 changes: 49 additions & 10 deletions src/OpenWrap/Build/PackageBuilders/MSBuildPackageBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.IO;
using System.Linq;
using System.Text;
using Microsoft.Win32;
using OpenFileSystem.IO;
using OpenWrap.Collections;
using OpenWrap.IO;
Expand All @@ -25,9 +26,11 @@ public MSBuildPackageBuilder(IFileSystem fileSystem, IEnvironment environment, I
Project = new List<string>();
Configuration = new List<string>();
ProjectFiles = new List<IFile>();

Properties = new string[0].ToLookup(_ => _);
}

static string[] ReservedProperties = new[] { "BuildEngine" };
public ILookup<string, string> Properties { get; set; }

public IEnumerable<string> Platform { get; set; }
Expand All @@ -36,10 +39,10 @@ public MSBuildPackageBuilder(IFileSystem fileSystem, IEnvironment environment, I
public IEnumerable<string> Configuration { get; set; }
public ICollection<IFile> ProjectFiles { get; set; }


public string BuildEngine { get; set; }
protected override string ExecutablePath
{
get { return GetMSBuildExecutablePath(); }
get { return GetExecutablePath(); }
}

public bool Incremental { get; set; }
Expand Down Expand Up @@ -127,15 +130,51 @@ IEnumerable<IFile> GetWildcardFile(string pathSpec)
catch { }
return specFiles ?? Enumerable.Empty<IFile>();
}
string GetExecutablePath()
{
var build = Properties.Contains("BuildEngine") && Properties["BuildEngine"].Any() ? Properties["BuildEngine"].First() : BuildEngine;

string path = null;
if (build == "default" || build == "msbuild")
path = GetMSBuildExecutionPath();
if (build == "xbuild" || (build == "default" && path == null))
path = IsUnix ? "xbuild.exe" : GetWinXbuildPath();
return path;
}

static bool IsUnix
{
get
{
int p = (int)Environment.OSVersion.Platform;
return (p == 4) || (p == 6) || (p == 128);
}
}

static string GetWinXbuildPath()
{
const string monoRegKey = @"SOFTWARE\Novell\Mono";
const string monoRegKeyx64 = @"SOFTWARE\Wow6432Node\Novell\Mono";
var installKey = Registry.LocalMachine.OpenSubKey(monoRegKey) ??
Registry.LocalMachine.OpenSubKey(monoRegKeyx64);
if (installKey == null) return null;
var defaultValue = installKey.GetValue("DefaultCLR");

var versionedKey = installKey.OpenSubKey(defaultValue.ToString());
if (versionedKey == null) return null;

var libPath = versionedKey.GetValue("FrameworkAssemblyDirectory").ToString();
return Path.Combine(libPath, "mono\\4.0\\xbuild.exe");
}

static string GetMSBuildExecutablePath()
static string GetMSBuildExecutionPath()
{
var versionedFolders = from version in Directory.GetDirectories(Environment.ExpandEnvironmentVariables(@"%windir%\Microsoft.NET\Framework\"), "v*")
orderby version descending
let msbuildPath = Path.Combine(version, "msbuild.exe")
where File.Exists(msbuildPath)
select msbuildPath;
return versionedFolders.FirstOrDefault();
return (from versionFolder in Directory.GetDirectories(Environment.ExpandEnvironmentVariables(@"%windir%\Microsoft.NET\Framework\"), "v*")
let version = new Version(Path.GetFileName(versionFolder).Substring(1))
orderby version descending
let file = Path.Combine(versionFolder, "msbuild.exe")
where File.Exists(file)
select file).FirstOrDefault();
}

IProcess CreateMSBuildProcess(IFile responseFile, IFile project, string platform, string profile, string msbuildTargets)
Expand Down Expand Up @@ -172,7 +211,7 @@ IProcess CreateMSBuildProcess(IFile responseFile, IFile project, string platform
writer.WriteLine("/p:OpenWrap-EmitOutputInstructions=true");
writer.WriteLine("/p:OpenWrap-CurrentProjectFile=\"" + project.Path.FullPath + "\"");

foreach (var kv in Properties)
foreach (var kv in Properties.Where(_=>ReservedProperties.Contains(_.Key) == false))
{
var value = kv.LastOrDefault();
if (value != null)
Expand Down

0 comments on commit e28e68e

Please sign in to comment.