예제 #1
0
        public int Execute(Execution execution)
        {
            var url = execution.PackageUrl;
            var module = ModuleInfo.Load(Path.Combine("Build", "Module.xml"));

            if (module.Packages == null)
            {
                module.Packages = new List<PackageRef>();
            }

            var package = _packageUrlParser.Parse(url);

            if (Directory.Exists(package.Folder))
            {
                throw new InvalidOperationException(package.Folder + " already exists");
            }

            if (module.Packages.Any(x => x.Uri == package.Uri))
            {
                Console.WriteLine("WARNING: Package with URI " + package.Uri + " is already present; ignoring request to add package.");
                return 0;
            }

            Console.WriteLine("Adding " + url + " as " + package.Folder + "...");
            module.Packages.Add(package);
            module.Save(Path.Combine("Build", "Module.xml"));

            return 0;
        }
예제 #2
0
        public int Execute(Execution execution)
        {
            if (!File.Exists(Path.Combine("Build", "Module.xml")))
            {
                throw new InvalidOperationException("No module present.");
            }

            var platform = execution.Platform ?? this.m_HostPlatformDetector.DetectPlatform();
            var module = ModuleInfo.Load(Path.Combine("Build", "Module.xml"));

            var done = false;
            foreach (var submodule in module.Packages)
            {
                if (submodule.Uri == execution.PackageUrl)
                {
                    Console.WriteLine("Switching to binary: " + submodule.Uri);
                    this.m_PackageManager.Resolve(module, submodule, platform, null, false);
                    done = true;
                    break;
                }
            }

            if (!done)
            {
                Console.WriteLine("No package registered with URL " + execution.PackageUrl);
                return 1;
            }

            return 0;
        }
예제 #3
0
        public int Execute(Execution execution)
        {
            var url = execution.PackageUrl;
            var module = ModuleInfo.Load(Path.Combine("Build", "Module.xml"));

            if (module.Packages == null)
            {
                throw new InvalidOperationException("No such package has been added");
            }

            var branch = "master";
            if (url.LastIndexOf('@') > url.LastIndexOf('/'))
            {
                // A branch / commit ref is specified.
                branch = url.Substring(url.LastIndexOf('@') + 1);
                url = url.Substring(0, url.LastIndexOf('@'));
            }

            var packageRef = _packageNameLookup.LookupPackageByName(module, url);

            _packageManager.Resolve(
                module,
                packageRef,
                execution.Platform ?? _hostPlatformDetector.DetectPlatform(),
                null,
                null,
                true);

            return 0;
        }
예제 #4
0
        public void Encounter(Execution pendingExecution, string[] args)
        {
            pendingExecution.SetCommandToExecuteIfNotDefault(this);

            if (args.Length < 5 || args[0] == null || args[1] == null || args[2] == null || args[3] == null || args[4] == null)
            {
                throw new InvalidOperationException("You must provide all arguments to -push except for the branch name.");
            }

            if (File.Exists(args[0]))
            {
                using (var reader = new StreamReader(args[0]))
                {
                    pendingExecution.PackagePushApiKey = reader.ReadToEnd().Trim();
                }
            }
            else
            {
                pendingExecution.PackagePushApiKey = args[0];
            }

            pendingExecution.PackagePushFile = new FileInfo(args[1]).FullName;
            pendingExecution.PackagePushUrl = args[2].TrimEnd('/');
            pendingExecution.PackagePushVersion = args[3];
            pendingExecution.PackagePushPlatform = args[4];
            pendingExecution.PackagePushBranchToUpdate = args.Length >= 6 ? args[5] : null;
        }
예제 #5
0
 public int Execute(Execution execution)
 {
     Console.WriteLine("query-features");
     Console.WriteLine("no-resolve");
     Console.WriteLine("list-packages");
     return 0;
 }
예제 #6
0
        public void Encounter(Execution pendingExecution, string[] args)
        {
            if (args.Length == 0 || args[0] == null)
            {
                throw new InvalidOperationException("You must provide an argument to the -enable option");
            }

            pendingExecution.EnabledServices.Add(args[0]);
        }
예제 #7
0
        public void Encounter(Execution pendingExecution, string[] args)
        {
            pendingExecution.SetCommandToExecuteIfNotDefault(this);

            if (args.Length > 0)
            {
                pendingExecution.Platform = args[0];
            }
        }
        public void Encounter(Execution pendingExecution, string[] args)
        {
            pendingExecution.SetCommandToExecuteIfNotDefault(this);

            if (args.Length > 0)
            {
                pendingExecution.AutomatedBuildScriptPath = args[0];
            }
        }
예제 #9
0
        public void Encounter(Execution pendingExecution, string[] args)
        {
            if (args.Length < 2 || args[0] == null || args[1] == null)
            {
                throw new InvalidOperationException("You must provide both the original and target URLs to the -redirect option");
            }

            this.m_PackageRedirector.RegisterLocalRedirect(args[0], args[1]);
        }
예제 #10
0
        public int Execute(Execution execution)
        {
            if (File.Exists(Path.Combine("Build", "Module.xml")))
            {
                throw new InvalidOperationException("This directory already has a module setup.");
            }

            var url = execution.StartProjectTemplateURL;
            var branch = "master";
            if (url.LastIndexOf('@') > url.LastIndexOf('/'))
            {
                // A branch / commit ref is specified.
                branch = url.Substring(url.LastIndexOf('@') + 1);
                url = url.Substring(0, url.LastIndexOf('@'));
            }

            var packageRef = new PackageRef
            {
                Uri = url,
                GitRef = branch,
                Folder = string.Empty
            };

            // If no project name is specified, use the name of the current directory.
            if (string.IsNullOrWhiteSpace(execution.StartProjectName))
            {
                var dir = new DirectoryInfo(Environment.CurrentDirectory);
                execution.StartProjectName = dir.Name;
                Console.WriteLine("Using current directory name '" + dir.Name + "' as name of new module.");
            }

            // The module can not be loaded before this point because it doesn't
            // yet exist.
            this.m_PackageManager.Resolve(null, packageRef, "Template", execution.StartProjectName, false);

            if (execution.DisableProjectGeneration)
            {
                Console.WriteLine("Module has been initialized.");
                return 0;
            }

            Console.WriteLine("Module has been initialized.  Performing --generate to create projects.");

            var module = ModuleInfo.Load(Path.Combine("Build", "Module.xml"));
            return this.m_ActionDispatch.PerformAction(
                module,
                "generate",
                execution.Platform,
                execution.EnabledServices.ToArray(),
                execution.DisabledServices.ToArray(),
                execution.ServiceSpecificationPath,
                execution.DebugServiceResolution,
                execution.DisablePackageResolution,
                execution.DisableHostProjectGeneration)
                ? 0 : 1;
        }
예제 #11
0
        public int Execute(Execution execution)
        {
            if (Directory.Exists("Build"))
            {
                using (var writer = new StreamWriter(Path.Combine("Build", "GenerateProject.CSharp.xslt")))
                {
                    ResourceExtractor.GetTransparentDecompressionStream(
                        Assembly.GetExecutingAssembly()
                        .GetManifestResourceStream("GenerateProject.CSharp.xslt.lzma"))
                        .CopyTo(writer.BaseStream);
                    writer.Flush();
                }
                using (var writer = new StreamWriter(Path.Combine("Build", "GenerateProject.CPlusPlus.VisualStudio.xslt")))
                {
                    ResourceExtractor.GetTransparentDecompressionStream(
                        Assembly.GetExecutingAssembly()
                        .GetManifestResourceStream("GenerateProject.CPlusPlus.VisualStudio.xslt.lzma"))
                        .CopyTo(writer.BaseStream);
                    writer.Flush();
                }
                using (var writer = new StreamWriter(Path.Combine("Build", "GenerateProject.CPlusPlus.MonoDevelop.xslt")))
                {
                    ResourceExtractor.GetTransparentDecompressionStream(
                        Assembly.GetExecutingAssembly()
                        .GetManifestResourceStream("GenerateProject.CPlusPlus.MonoDevelop.xslt.lzma"))
                        .CopyTo(writer.BaseStream);
                    writer.Flush();
                }
                using (var writer = new StreamWriter(Path.Combine("Build", "GenerateSolution.xslt")))
                {
                    ResourceExtractor.GetTransparentDecompressionStream(
                        Assembly.GetExecutingAssembly()
                        .GetManifestResourceStream("GenerateSolution.xslt.lzma"))
                        .CopyTo(writer.BaseStream);
                    writer.Flush();
                }
                using (var writer = new StreamWriter(Path.Combine("Build", "GenerationFunctions.cs")))
                {
                    ResourceExtractor.GetTransparentDecompressionStream(
                        Assembly.GetExecutingAssembly()
                        .GetManifestResourceStream("GenerationFunctions.cs.lzma"))
                        .CopyTo(writer.BaseStream);
                    writer.Flush();
                }
                using (var writer = new StreamWriter(Path.Combine("Build", "SelectSolution.xslt")))
                {
                    ResourceExtractor.GetTransparentDecompressionStream(
                        Assembly.GetExecutingAssembly()
                        .GetManifestResourceStream("SelectSolution.xslt.lzma"))
                        .CopyTo(writer.BaseStream);
                    writer.Flush();
                }
            }

            return 0;
        }
예제 #12
0
        public void Encounter(Execution pendingExecution, string[] args)
        {
            if (args.Length < 1)
            {
                throw new InvalidOperationException(
                    "You must provide the name of the build target if you use --build-target.");
            }

            pendingExecution.BuildTarget = args[0];
        }
예제 #13
0
        public void Encounter(Execution pendingExecution, string[] args)
        {
            if (args.Length < 1)
            {
                throw new InvalidOperationException(
                    "You must provide the name of the build property if you use --build-property.");
            }

            pendingExecution.BuildProperties.Add(args[0], args.Length >= 2 ? args[1] : null);
        }
        public void Encounter(Execution pendingExecution, string[] args)
        {
            if (args.Length < 1)
            {
                throw new InvalidOperationException(
                    "You must provide the name of the build process architecture if you use the --build-process-arch property.");
            }

            pendingExecution.BuildProcessArchitecture = args[0];
        }
예제 #15
0
        public void Encounter(Execution pendingExecution, string[] args)
        {
            pendingExecution.SetCommandToExecuteIfNotDefault(this);

            if (args.Length < 1 || args[0] == null)
            {
                throw new InvalidOperationException("You must provide the URL of the package to swap to binary.");
            }

            pendingExecution.PackageUrl = args[0];
        }
예제 #16
0
        public int Execute(Execution execution)
        {
            var scriptPath = execution.AutomatedBuildScriptPath ?? "automated.build";

            if (!File.Exists(scriptPath))
            {
                Console.Error.WriteLine("ERROR: Automated build script not found at " + scriptPath + ".");
            }

            return _automatedBuildController.Execute(scriptPath);
        }
예제 #17
0
 public void Encounter(Execution pendingExecution, string[] args)
 {
     if (args.Length > 0)
     {
         _featureManager.LoadFeaturesFromCommandLine(args[0]);
     }
     else
     {
         _featureManager.LoadFeaturesFromCommandLine(string.Empty);
     }
 }
예제 #18
0
        public void Encounter(Execution pendingExecution, string[] args)
        {
            pendingExecution.SetCommandToExecuteIfNotDefault(this);

            if (args.Length == 0 || args[0] == null)
            {
                throw new InvalidOperationException("You must provide an argument to the -install option");
            }

            pendingExecution.PackageUrl = args[0];
        }
예제 #19
0
        public int Execute(Execution execution)
        {
            if (!File.Exists(Path.Combine("Build", "Module.xml")))
            {
                throw new InvalidOperationException("No module present.");
            }

            var platform = execution.Platform ?? this.m_HostPlatformDetector.DetectPlatform();
            var module = ModuleInfo.Load(Path.Combine("Build", "Module.xml"));
            this.m_PackageManager.ResolveAll(module, platform);
            return 0;
        }
예제 #20
0
        public void Encounter(Execution pendingExecution, string[] args)
        {
            pendingExecution.SetCommandToExecuteIfNotDefault(this);

            if (args.Length < 1 || args[0] == null)
            {
                throw new InvalidOperationException("You must provide the template's URL.");
            }

            pendingExecution.StartProjectTemplateURL = args[0];
            pendingExecution.StartProjectName = args.Length >= 2 ? args[1] : null;
        }
예제 #21
0
        public void Encounter(Execution pendingExecution, string[] args)
        {
            pendingExecution.SetCommandToExecuteIfNotDefault(this);

            pendingExecution.ExecuteProjectName = args[0];

            var newArgs = new string[args.Length - 1];
            for (var i = 1; i < args.Length; i++)
            {
                newArgs[i - 1] = args[i];
            }

            pendingExecution.ExecuteProjectArguments = newArgs;
        }
예제 #22
0
        public void Encounter(Execution pendingExecution, string[] args)
        {
            pendingExecution.SetCommandToExecuteIfNotDefault(this);

            if (args.Length < 3 || args[0] == null || args[1] == null || args[2] == null)
            {
                throw new InvalidOperationException("You must provide the module folder, destination file and platform to -pack.");
            }

            pendingExecution.PackageSourceFolder = new DirectoryInfo(args[0]).FullName;
            pendingExecution.PackageDestinationFile = new FileInfo(args[1]).FullName;
            pendingExecution.PackagePlatform = args.Length >= 3 ? args[2] : this.m_HostPlatformDetector.DetectPlatform();
            pendingExecution.PackageFilterFile = args.Length >= 4 ? args[3] : null;
        }
예제 #23
0
        public void Encounter(Execution pendingExecution, string[] args)
        {
            if (args.Length == 0 || args[0] == null)
            {
                throw new InvalidOperationException("You must provide an argument to the -package-root option");
            }

            if (pendingExecution.ServiceSpecificationPath != null)
            {
                throw new InvalidOperationException("Multiple -package-root options passed.");
            }

            pendingExecution.PackageRoot = args[0];
        }
예제 #24
0
        public int Execute(Execution execution)
        {
            var module = ModuleInfo.Load(Path.Combine("Build", "Module.xml"));

            if (module.Packages == null)
            {
                module.Packages = new List<PackageRef>();
            }

            foreach (var package in module.Packages)
            {
                Console.WriteLine(package.Uri);
            }

            return 0;
        }
예제 #25
0
        public void Encounter(Execution pendingExecution, string[] args)
        {
            if (args.Length < 1 || args[0] == null)
            {
                throw new InvalidOperationException("You must provide the package format to -format.");
            }

            switch (args[0])
            {
                case PackageManager.ARCHIVE_FORMAT_TAR_GZIP:
                case PackageManager.ARCHIVE_FORMAT_TAR_LZMA:
                    pendingExecution.PackageFormat = args[0];
                    break;
                default:
                    throw new InvalidOperationException("Unknown package format " + args[0]);
            }
        }
예제 #26
0
        public int Execute(Execution execution)
        {
            if (Directory.Exists("Build"))
            {
                var module = ModuleInfo.Load(Path.Combine("Build", "Module.xml"));
                return this.m_ActionDispatch.PerformAction(
                    module,
                    "resync",
                    execution.Platform,
                    execution.EnabledServices.ToArray(),
                    execution.DisabledServices.ToArray(),
                    execution.ServiceSpecificationPath)
                    ? 0
                    : 1;
            }

            return 1;
        }
예제 #27
0
        public int Execute(Execution execution)
        {
            var url = execution.PackageUrl;
            var module = ModuleInfo.Load(Path.Combine("Build", "Module.xml"));

            if (module.Packages == null)
            {
                module.Packages = new List<PackageRef>();
            }

            var branch = "master";
            if (url.LastIndexOf('@') > url.LastIndexOf('/'))
            {
                // A branch / commit ref is specified.
                branch = url.Substring(url.LastIndexOf('@') + 1);
                url = url.Substring(0, url.LastIndexOf('@'));
            }

            var uri = new Uri(url);

            var package = new PackageRef
            {
                Uri = url,
                GitRef = branch,
                Folder = uri.AbsolutePath.Trim('/').Split('/').Last()
            };

            if (Directory.Exists(package.Folder))
            {
                throw new InvalidOperationException(package.Folder + " already exists");
            }

            if (module.Packages.Any(x => x.Uri == package.Uri))
            {
                Console.WriteLine("WARNING: Package with URI " + package.Uri + " is already present; ignoring request to add package.");
                return 0;
            }

            Console.WriteLine("Adding " + url + " as " + package.Folder + "...");
            module.Packages.Add(package);
            module.Save(Path.Combine("Build", "Module.xml"));

            return 0;
        }
        public void Encounter(Execution pendingExecution, string[] args)
        {
            if (args.Length < 1 || args[0] == null)
            {
                throw new InvalidOperationException("You must provide the name of the host platform to simulate");
            }

            switch (args[0])
            {
                case "Windows":
                case "MacOS":
                case "Linux":
                    break;
                default:
                    throw new InvalidOperationException("Invalid host platform name for simulation");
                    break;
            }

            HostPlatformDetector.SimulatedHostPlatform = args[0];
        }
예제 #29
0
        public int Execute(Execution execution)
        {
            if (Directory.Exists("Build"))
            {
                var module = ModuleInfo.Load(Path.Combine("Build", "Module.xml"));
                return this.m_ActionDispatch.PerformAction(
                    module,
                    "generate",
                    execution.Platform,
                    execution.EnabledServices.ToArray(),
                    execution.DisabledServices.ToArray(),
                    execution.ServiceSpecificationPath,
                    execution.DebugServiceResolution,
                    execution.DisablePackageResolution,
                    execution.DisableHostProjectGeneration)
                    ? 0
                    : 1;
            }

            return 1;
        }
예제 #30
0
        public int Execute(Execution execution)
        {
            if (!File.Exists(Path.Combine("Build", "Module.xml")))
            {
                _knownToolProvider.GetToolExecutablePath("Protobuild.Manager");

                var subexecution = new Execution();
                subexecution.ExecuteProjectName = "Protobuild.Manager";
                subexecution.ExecuteProjectArguments = new string[0];

                return _executeCommand.Execute(subexecution);
            }

            return this.m_ActionDispatch.DefaultAction(
                ModuleInfo.Load(Path.Combine("Build", "Module.xml")),
                enabledServices: execution.EnabledServices.ToArray(),
                disabledServices: execution.DisabledServices.ToArray(),
                serviceSpecPath: execution.ServiceSpecificationPath,
                debugServiceResolution: execution.DebugServiceResolution,
                disablePackageResolution: execution.DisablePackageResolution,
                disableHostPlatformGeneration: execution.DisableHostProjectGeneration) ? 0 : 1;
        }
예제 #31
0
        public int Execute(Execution execution)
        {
            var assemblyPath = Assembly.GetEntryAssembly().Location;
            var fileInfo     = new FileInfo(assemblyPath);
            var modulePath   = fileInfo.DirectoryName;

            if (modulePath == null)
            {
                RedirectableConsole.WriteLine(
                    "Unable to determine the location of Protobuild.");
                return(1);
            }

            if (!File.Exists(Path.Combine(modulePath, "Build", "Module.xml")))
            {
                modulePath = execution.WorkingDirectory;
            }

            string executablePath     = null;
            var    executableIsNative = false;

            if (!File.Exists(Path.Combine(modulePath, "Build", "Module.xml")))
            {
                // We can only run global tools.
                var globalToolPath = this.m_PackageGlobalTool.ResolveGlobalToolIfPresent(execution.ExecuteProjectName);
                if (globalToolPath == null)
                {
                    RedirectableConsole.WriteLine(
                        "There is no global tool registered as '" + execution.ExecuteProjectName + "'");
                    return(1);
                }
                else
                {
                    executablePath     = globalToolPath;
                    executableIsNative = m_HostPlatformDetector.DetectPlatform() == "MacOS" && globalToolPath.EndsWith(".app");
                }
            }
            else
            {
                var platform    = this.m_HostPlatformDetector.DetectPlatform();
                var module      = ModuleInfo.Load(Path.Combine(modulePath, "Build", "Module.xml"));
                var definitions = module.GetDefinitionsRecursively(platform).ToList();
                var target      = definitions.FirstOrDefault(x => x.Name == execution.ExecuteProjectName);
                if (target == null)
                {
                    // Check to see if there is any external project definition that provides the tool.
                    foreach (var definition in definitions)
                    {
                        var document = XDocument.Load(definition.DefinitionPath);
                        if (document.Root.Name.LocalName == "ExternalProject")
                        {
                            foreach (var node in document.Root.Elements().Where(x => x.Name.LocalName == "Tool"))
                            {
                                var name = node.Attribute(XName.Get("Name")).Value;
                                var path = node.Attribute(XName.Get("Path")).Value;

                                if (name == execution.ExecuteProjectName)
                                {
                                    executablePath = Path.Combine(definition.ModulePath, path.Replace('\\', Path.DirectorySeparatorChar).Replace('/', Path.DirectorySeparatorChar));
                                    break;
                                }
                            }
                        }
                    }

                    if (executablePath == null)
                    {
                        var globalToolPath = this.m_PackageGlobalTool.ResolveGlobalToolIfPresent(execution.ExecuteProjectName);
                        if (globalToolPath == null)
                        {
                            RedirectableConsole.WriteLine(
                                "There is no project definition with name '" + execution.ExecuteProjectName + "'");
                            return(1);
                        }
                        else
                        {
                            executablePath     = globalToolPath;
                            executableIsNative = m_HostPlatformDetector.DetectPlatform() == "MacOS" && globalToolPath.EndsWith(".app");
                        }
                    }
                }
                else
                {
                    var document = XDocument.Load(target.DefinitionPath);
                    if (document.Root.Name.LocalName == "Project")
                    {
                        var    assemblyName       = this.m_ProjectOutputPathCalculator.GetProjectAssemblyName(platform, target, document);
                        var    prefixPath         = this.m_ProjectOutputPathCalculator.GetProjectOutputPathPrefix(platform, target, document, false);
                        var    directory          = new DirectoryInfo(Path.Combine(modulePath, prefixPath));
                        var    subdirectories     = directory.GetDirectories();
                        var    preferredName      = (execution.ExecuteProjectConfiguration ?? "Debug").ToLowerInvariant();
                        var    preferredDirectory = subdirectories.FirstOrDefault(x => x.Name.ToLowerInvariant() == preferredName);
                        var    targetName         = assemblyName + ".exe";
                        string targetAppName      = null;
                        if (m_HostPlatformDetector.DetectPlatform() == "MacOS")
                        {
                            targetAppName = assemblyName + ".app/Contents/MacOS/" + assemblyName;
                        }
                        if (preferredDirectory != null && (File.Exists(Path.Combine(preferredDirectory.FullName, targetName)) || (targetAppName != null && File.Exists(Path.Combine(preferredDirectory.FullName, targetAppName)))))
                        {
                            if (targetAppName != null && File.Exists(Path.Combine(preferredDirectory.FullName, targetAppName)))
                            {
                                // We must use the 'defaults' tool on macOS to determine if the target is a
                                // graphical application.  We do this by checking for the presence of NSPrincipalClass
                                // in the Info.plist file, which must be present for graphical applications to
                                // work.  If it does not exist, we assume it is a command-line application and run
                                // it normally like on any other platform.  We have to do this because the native
                                // entry point is the only one that has access to the GUI, while the non-native
                                // entry point is the only one that has the correct working directory set on
                                // startup.
                                if (_graphicalAppDetection.TargetMacOSAppIsGraphical(Path.Combine(preferredDirectory.FullName, assemblyName + ".app")))
                                {
                                    executablePath     = Path.Combine(preferredDirectory.FullName, targetAppName);
                                    executableIsNative = true;
                                }
                            }
                            if (executablePath == null && File.Exists(Path.Combine(preferredDirectory.FullName, targetName)))
                            {
                                executablePath = Path.Combine(preferredDirectory.FullName, targetName);
                            }
                        }
                        else
                        {
                            foreach (var subdirectory in subdirectories)
                            {
                                var    tempPath    = Path.Combine(subdirectory.FullName, assemblyName + ".exe");
                                string tempAppName = null;
                                if (m_HostPlatformDetector.DetectPlatform() == "MacOS")
                                {
                                    tempAppName = Path.Combine(subdirectory.FullName, assemblyName + ".app/Contents/MacOS/" + assemblyName);
                                }

                                if (tempAppName != null && File.Exists(tempAppName))
                                {
                                    // We must use the 'defaults' tool on macOS to determine if the target is a
                                    // graphical application.  We do this by checking for the presence of NSPrincipalClass
                                    // in the Info.plist file, which must be present for graphical applications to
                                    // work.  If it does not exist, we assume it is a command-line application and run
                                    // it normally like on any other platform.  We have to do this because the native
                                    // entry point is the only one that has access to the GUI, while the non-native
                                    // entry point is the only one that has the correct working directory set on
                                    // startup.
                                    if (_graphicalAppDetection.TargetMacOSAppIsGraphical(Path.Combine(subdirectory.FullName, assemblyName + ".app")))
                                    {
                                        executablePath     = tempAppName;
                                        executableIsNative = true;
                                        break;
                                    }
                                }
                                if (File.Exists(tempPath))
                                {
                                    executablePath = tempPath;
                                    break;
                                }
                            }
                        }
                    }
                    else if (document.Root.Name.LocalName == "ExternalProject")
                    {
                        foreach (var node in document.Root.Elements().Where(x => x.Name.LocalName == "Tool"))
                        {
                            var name = node.Attribute(XName.Get("Name")).Value;
                            var path = node.Attribute(XName.Get("Path")).Value;

                            if (name == execution.ExecuteProjectName)
                            {
                                executablePath = Path.Combine(target.ModulePath, path.Replace('\\', Path.DirectorySeparatorChar).Replace('/', Path.DirectorySeparatorChar));
                                break;
                            }
                        }
                    }

                    if (executablePath == null)
                    {
                        var globalToolPath = this.m_PackageGlobalTool.ResolveGlobalToolIfPresent(execution.ExecuteProjectName);
                        if (globalToolPath == null)
                        {
                            RedirectableConsole.WriteLine(
                                "There is no output path for '" + execution.ExecuteProjectName + "'; has the project been built?");
                            return(1);
                        }
                        else
                        {
                            executablePath     = globalToolPath;
                            executableIsNative = m_HostPlatformDetector.DetectPlatform() == "MacOS" && globalToolPath.EndsWith(".app");
                        }
                    }
                }
            }

            if (!(File.Exists(executablePath) || (executablePath.EndsWith(".app") && Directory.Exists(executablePath))))
            {
                RedirectableConsole.WriteLine(
                    "There is no executable for '" + execution.ExecuteProjectName + "'; has the project been built?");
                return(1);
            }

            var arguments = string.Empty;

            if (execution.ExecuteProjectArguments.Length > 0)
            {
                arguments = execution.ExecuteProjectArguments
                            .Select(x => "\"" + x.Replace("\"", "\\\"") + "\"")
                            .Aggregate((a, b) => a + " " + b);
            }

            ProcessStartInfo startInfo;

            if (Path.DirectorySeparatorChar == '/' && !executableIsNative)
            {
                var mono = "mono";
                if (m_HostPlatformDetector.DetectPlatform() == "MacOS" && File.Exists("/usr/local/bin/mono"))
                {
                    // After upgrading to OSX El Capitan, the /usr/local/bin folder is no longer in
                    // the system PATH.  If we can't find Mono with the which tool, manually set the
                    // path here in an attempt to find it.
                    mono = "/usr/local/bin/mono";
                }

                startInfo = new ProcessStartInfo(
                    mono,
                    "--debug \"" + executablePath + "\" " + arguments);
            }
            else
            {
                if (m_HostPlatformDetector.DetectPlatform() == "MacOS" && executablePath.EndsWith(".app"))
                {
                    // We must use 'open -a' to launch this application.
                    arguments      = "-a '" + executablePath.Replace("'", "'\"'\"'") + "' " + arguments;
                    executablePath = "/usr/bin/open";
                }

                startInfo = new ProcessStartInfo(
                    executablePath,
                    arguments);
            }
            startInfo.UseShellExecute = false;

            var process = Process.Start(startInfo);

            process.WaitForExit();
            return(process.ExitCode);
        }