예제 #1
0
        private void ShowSupportedPlatformsError(ModuleInfo module, string requestedPlatform)
        {
            RedirectableConsole.ErrorWriteLine("The platform '" + requestedPlatform + "' is not supported.");
            RedirectableConsole.ErrorWriteLine("The following platforms are supported by this module:");
            foreach (
                var supportedPlatform in
                module.SupportedPlatforms.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
                .Select(x => x.Trim())
                .Where(x => !string.IsNullOrWhiteSpace(x)))
            {
                RedirectableConsole.ErrorWriteLine("  * " + supportedPlatform);
            }

            ExecEnvironment.Exit(1);
        }
예제 #2
0
        public int Execute(Execution execution)
        {
            if (!File.Exists(Path.Combine("Build", "Module.xml")))
            {
                Directory.CreateDirectory("Build");
                ResourceExtractor.ExtractAll(Path.Combine(Environment.CurrentDirectory, "Build"), "MyProject");
                Console.WriteLine("Build" + Path.DirectorySeparatorChar + "Module.xml has been created.");
                ExecEnvironment.Exit(0);
            }

            return(this.m_ActionDispatch.DefaultAction(
                       ModuleInfo.Load(Path.Combine("Build", "Module.xml")),
                       enabledServices: execution.EnabledServices.ToArray(),
                       disabledServices: execution.DisabledServices.ToArray(),
                       serviceSpecPath: execution.ServiceSpecificationPath) ? 0 : 1);
        }
예제 #3
0
        /// <summary>
        /// Performs a resynchronisation, synchronisation, generation or clean on the specified module.
        /// </summary>
        /// <returns><c>true</c>, if the action succeeded, <c>false</c> otherwise.</returns>
        /// <param name="module">The module to perform the action on.</param>
        /// <param name="action">The action to perform, either "resync", "sync", "generate" or "clean".</param>
        /// <param name="platform">The platform to perform the action for.</param>
        /// <param name="enabledServices">A list of enabled services.</param>
        /// <param name="disabledServices">A list of disabled services.</param>
        /// <param name="serviceSpecPath">The service specification path.</param>
        /// <param name="debugServiceResolution">Whether to enable debugging information during service resolution.</param>
        /// <param name="disablePackageResolution">Whether to disable package resolution.</param>
        /// <param name="disableHostPlatformGeneration">Whether to disable generation of the host platform projects.</param>
        /// <param name="taskParallelisation">Whether to enable or disable task generation, or null for the default behaviour.</param>
        public bool PerformAction(
            string workingDirectory,
            ModuleInfo module,
            string action,
            string platform,
            string[] enabledServices,
            string[] disabledServices,
            string serviceSpecPath,
            bool debugServiceResolution,
            bool disablePackageResolution,
            bool disableHostPlatformGeneration,
            bool?taskParallelisation,
            bool?safeResolve,
            bool debugProjectGeneration)
        {
            var platformSupplied = !string.IsNullOrWhiteSpace(platform);

            var hostPlatform = this.m_HostPlatformDetector.DetectPlatform();

            if (string.IsNullOrWhiteSpace(platform))
            {
                platform = hostPlatform;
            }

            var    originalPlatform  = platform;
            string primaryPlatform   = null;
            string multiplePlatforms = null;

            if (platform.Contains(","))
            {
                // The user requested multiple platforms; the first one
                // is the primary platform.
                var platforms = platform.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                if (platforms.Length == 0)
                {
                    RedirectableConsole.ErrorWriteLine("You supplied only commas where a list of platforms was expected.");
                    ExecEnvironment.Exit(1);
                    return(false);
                }
                else
                {
                    for (var i = 0; i < platforms.Length; i++)
                    {
                        var newPlatform = _moduleUtilities.NormalizePlatform(module, platforms[i]);
                        if (newPlatform == null)
                        {
                            ShowSupportedPlatformsError(module, platforms[i]);
                            return(false);
                        }
                        platforms[i] = newPlatform;
                    }

                    primaryPlatform   = platforms[0];
                    multiplePlatforms = platforms.Aggregate((a, b) => a + "," + b);
                }
            }
            else
            {
                platform = _moduleUtilities.NormalizePlatform(module, platform);

                if (platform == null && !platformSupplied)
                {
                    // The current host platform isn't supported, so we shouldn't try to
                    // operate on it.
                    string firstPlatform = null;
                    switch (this.m_HostPlatformDetector.DetectPlatform())
                    {
                    case "Windows":
                        firstPlatform = module.DefaultWindowsPlatforms.Split(',').FirstOrDefault();
                        break;

                    case "MacOS":
                        firstPlatform = module.DefaultMacOSPlatforms.Split(',').FirstOrDefault();
                        break;

                    case "Linux":
                        firstPlatform = module.DefaultLinuxPlatforms.Split(',').FirstOrDefault();
                        break;
                    }

                    if (firstPlatform != null)
                    {
                        // This will end up null if the first platform isn't supported
                        // either and hence throw the right message.
                        platform = _moduleUtilities.NormalizePlatform(module, firstPlatform);
                    }
                }

                if (platform == null)
                {
                    ShowSupportedPlatformsError(module, originalPlatform);
                    return(false);
                }

                primaryPlatform = platform;
            }

            // You can generate multiple targets by default by setting the <DefaultWindowsPlatforms>
            // <DefaultMacOSPlatforms> and <DefaultLinuxPlatforms> tags in Module.xml.  Note that
            // synchronisation will only be done for the primary platform, as there is no correct
            // synchronisation behaviour when dealing with multiple C# projects.
            //
            // We only trigger this behaviour when the platform is omitted; if you explicitly
            // specify "Windows" on the command line, we'll only generate / resync / sync
            // the Windows platform.
            if (!platformSupplied)
            {
                switch (platform)
                {
                case "Windows":
                    multiplePlatforms = module.DefaultWindowsPlatforms;
                    break;

                case "MacOS":
                    multiplePlatforms = module.DefaultMacOSPlatforms;
                    break;

                case "Linux":
                    multiplePlatforms = module.DefaultLinuxPlatforms;
                    break;
                }
            }

            // If no overrides are set, just use the current platform.
            if (string.IsNullOrEmpty(multiplePlatforms))
            {
                multiplePlatforms = platform;
            }

            // If running pure synchronisation or a project clean, we don't need to perform
            // package resolution.
            if (action.ToLower() == "sync" || action.ToLower() == "clean")
            {
                disablePackageResolution = true;
            }

            // Resolve submodules as needed.
            if (!disablePackageResolution)
            {
                this.m_PackageManager.ResolveAll(workingDirectory, module, primaryPlatform, taskParallelisation, false, safeResolve);
            }

            // Create the list of multiple platforms.
            var multiplePlatformsList =
                multiplePlatforms.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()).ToList();

            // Remember whether or not we need to implicitly generate the host
            // platform.
            var    implicitlyGenerateHostPlatform = false;
            Action requiresHostPlatform           = () => implicitlyGenerateHostPlatform = true;

            // If we are already generating the host platform, then requiring the
            // host platform is already satisifed.
            if (platform == hostPlatform || multiplePlatformsList.Contains(hostPlatform))
            {
                requiresHostPlatform = () => {};
            }
            else if (!_featureManager.IsFeatureEnabled(Feature.HostPlatformGeneration))
            {
                requiresHostPlatform = () =>
                {
                    RedirectableConsole.ErrorWriteLine(
                        "WARNING: One or more projects requires host platforms to be generated, " +
                        "but the HostPlatformGeneration feature is not enabled.  Expect your " +
                        "build to fail.");
                };
            }

            // You can configure the default action for Protobuild in their project
            // with the <DefaultAction> tag in Module.xml.  If omitted, default to a resync.
            // Valid options for this tag are either "Generate", "Resync" or "Sync".

            // If the actions are "Resync" or "Sync", then we need to perform an initial
            // step against the primary platform.
            switch (action.ToLower())
            {
            case "generate":
                if (!this.GenerateProjectsForPlatform(
                        workingDirectory,
                        module,
                        primaryPlatform,
                        enabledServices,
                        disabledServices,
                        serviceSpecPath,
                        debugServiceResolution,
                        disablePackageResolution,
                        disableHostPlatformGeneration,
                        requiresHostPlatform,
                        debugProjectGeneration))
                {
                    return(false);
                }

                break;

            case "resync":
                if (!this.ResyncProjectsForPlatform(
                        workingDirectory,
                        module,
                        primaryPlatform,
                        enabledServices,
                        disabledServices,
                        serviceSpecPath,
                        debugServiceResolution,
                        disablePackageResolution,
                        disableHostPlatformGeneration,
                        requiresHostPlatform,
                        debugProjectGeneration))
                {
                    return(false);
                }

                break;

            case "sync":
                return(this.SyncProjectsForPlatform(module, primaryPlatform));

            case "clean":
                if (!this.CleanProjectsForPlatform(module, primaryPlatform))
                {
                    return(false);
                }

                break;

            default:
                RedirectableConsole.ErrorWriteLine("Unknown option in <DefaultAction> tag of Module.xml.  Defaulting to resync!");
                return(this.ResyncProjectsForPlatform(
                           workingDirectory,
                           module,
                           primaryPlatform,
                           enabledServices,
                           disabledServices,
                           serviceSpecPath,
                           debugServiceResolution,
                           disablePackageResolution,
                           disableHostPlatformGeneration,
                           requiresHostPlatform,
                           debugProjectGeneration));
            }

            // Now iterate through the multiple platforms specified.
            foreach (var platformIter in multiplePlatformsList.Distinct())
            {
                if (platformIter == primaryPlatform)
                {
                    // Already handled above.
                    continue;
                }

                // Resolve submodules as needed.
                if (!disablePackageResolution)
                {
                    this.m_PackageManager.ResolveAll(workingDirectory, module, platformIter, taskParallelisation, false, safeResolve);
                }

                switch (action.ToLower())
                {
                case "generate":
                case "resync":
                    // We do a generate under resync mode since we only want the primary platform
                    // to have synchronisation done (and it has had above).
                    if (!this.GenerateProjectsForPlatform(
                            workingDirectory,
                            module,
                            platformIter,
                            enabledServices,
                            disabledServices,
                            serviceSpecPath,
                            debugServiceResolution,
                            disablePackageResolution,
                            disableHostPlatformGeneration,
                            requiresHostPlatform,
                            debugProjectGeneration))
                    {
                        return(false);
                    }

                    break;

                case "clean":
                    if (!this.CleanProjectsForPlatform(module, platformIter))
                    {
                        return(false);
                    }

                    break;

                default:
                    throw new InvalidOperationException("Code should never reach this point");
                }
            }

            // If we implicitly require the host platform, generate that now (this variable can
            // only ever be set to true if the host platform is not already in the list of
            // platforms generated previously).
            if (implicitlyGenerateHostPlatform)
            {
                // Check to see if the host platform is supported.
                var hostPlatformNormalized = _moduleUtilities.NormalizePlatform(module, hostPlatform);
                if (hostPlatformNormalized == null)
                {
                    RedirectableConsole.WriteLine(
                        "WARNING: The current host platform is not a supported platform for the solution.  IDE editor " +
                        "projects and post-build hooks will not be available, and this may cause the project to be " +
                        "built incorrectly!");
                    return(true);
                }

                RedirectableConsole.WriteLine(
                    "One or more projects required the presence of host platform " +
                    "projects, implicitly starting generation for " + hostPlatform + "...");

                // Resolve submodules as needed.
                if (!disablePackageResolution)
                {
                    this.m_PackageManager.ResolveAll(workingDirectory, module, hostPlatform, taskParallelisation, false, safeResolve);
                }

                switch (action.ToLower())
                {
                case "generate":
                case "resync":
                    // We do a generate under resync mode since we only want the primary platform
                    // to have synchronisation done (and it has had above).
                    if (!this.GenerateProjectsForPlatform(
                            workingDirectory,
                            module,
                            hostPlatform,
                            enabledServices,
                            disabledServices,
                            serviceSpecPath,
                            debugServiceResolution,
                            disablePackageResolution,
                            disableHostPlatformGeneration,
                            requiresHostPlatform,
                            debugProjectGeneration))
                    {
                        return(false);
                    }

                    break;

                case "clean":
                    if (!this.CleanProjectsForPlatform(module, hostPlatform))
                    {
                        return(false);
                    }

                    break;

                default:
                    throw new InvalidOperationException("Code should never reach this point");
                }
            }

            // All the steps succeeded, so return true.
            return(true);
        }
예제 #4
0
        public byte[] Transform(string workingDirectory, string url, string gitReference, string platform, string format)
        {
            var urlAndPackageName = url.Split(new[] { '|' }, 2);

            if (urlAndPackageName.Length != 2)
            {
                RedirectableConsole.ErrorWriteLine(
                    "ERROR: Malformed NuGet package reference '" + url +
                    "'.  Make sure you split the NuGet server URL and the package name with a pipe character (|).");
                ExecEnvironment.Exit(1);
            }

            var repoUrl     = urlAndPackageName[0];
            var packageName = urlAndPackageName[1];

            var originalFolder = DownloadOrUseExistingNuGetPackage(repoUrl.TrimEnd('/'), packageName, gitReference);

            if (Directory.Exists(Path.Combine(originalFolder, "protobuild")))
            {
                // This is a Protobuild-aware NuGet package.  In this case, we just use the contents of the
                // "protobuild" folder as the content of our package, and ignore everything else.
                RedirectableConsole.WriteLine("Detected Protobuild-aware package...");

                RedirectableConsole.WriteLine("Converting to a Protobuild package...");

                var target = new MemoryStream();
                var filter = new FileFilter(_getRecursiveUtilitiesInPath.GetRecursiveFilesInPath(originalFolder));

                filter.ApplyInclude("protobuild/(.*)");
                filter.ApplyRewrite("protobuild/(.*)", "$1");

                filter.ImplyDirectories();

                _packageCreator.Create(
                    target,
                    filter,
                    originalFolder,
                    format,
                    platform);

                RedirectableConsole.WriteLine("Package conversion complete.");
                var bytes2 = new byte[target.Position];
                target.Seek(0, SeekOrigin.Begin);
                target.Read(bytes2, 0, bytes2.Length);
                return(bytes2);
            }

            var folder = Path.GetTempFileName();

            File.Delete(folder);
            Directory.CreateDirectory(folder);

            byte[] bytes;
            try
            {
                RedirectableConsole.WriteLine("Copying directory for package transformation...");
                CopyFolder(new DirectoryInfo(originalFolder), new DirectoryInfo(folder));

                RedirectableConsole.WriteLine("Auto-detecting libraries to reference from NuGet package...");

                var packagePath         = new DirectoryInfo(folder).GetFiles("*.nuspec").First().FullName;
                var libraryReferences   = new Dictionary <string, string>();
                var packageDependencies = new Dictionary <string, string>();

                // Use the nuspec file if it exists.
                List <string> references = new List <string>();
                if (File.Exists(packagePath))
                {
                    var packageDoc = new XmlDocument();
                    packageDoc.Load(packagePath);

                    // If the references are explicitly provided in the nuspec, use
                    // those as to what files should be referenced by the projects.
                    if (
                        packageDoc.DocumentElement.FirstChild.ChildNodes.OfType <XmlElement>()
                        .Count(x => x.Name == "references") > 0)
                    {
                        references =
                            packageDoc.DocumentElement.FirstChild.ChildNodes.OfType <XmlElement>()
                            .First(x => x.Name == "references")
                            .ChildNodes.OfType <XmlElement>()
                            .Where(x => x.Name == "reference")
                            .Select(x => x.Attributes["file"].Value)
                            .ToList();
                    }

                    // If there are dependencies specified, store them and convert them to
                    // Protobuild references, and reference them in the Module.xml file.
                    if (
                        packageDoc.DocumentElement.FirstChild.ChildNodes.OfType <XmlElement>()
                        .Count(x => x.Name == "dependencies") > 0)
                    {
                        packageDependencies =
                            packageDoc.DocumentElement.FirstChild.ChildNodes.OfType <XmlElement>()
                            .First(x => x.Name == "dependencies")
                            .ChildNodes.OfType <XmlElement>()
                            .Where(x => x.Name == "dependency")
                            .ToDictionarySafe(
                                k => k.Attributes["id"].Value,
                                v => v.Attributes["version"].Value,
                                (dict, c) =>
                                RedirectableConsole.WriteLine("WARNING: More than one dependency on " + c +
                                                              " in NuGet package."));
                    }
                }

                // Determine the priority of the frameworks that we want to target
                // out of the available versions.
                string[] clrNames = _nuGetPlatformMapping.GetFrameworkNamesForRead(workingDirectory, platform);

                var referenceDirectories = new string[] { "ref", "lib" };

                foreach (var directory in referenceDirectories)
                {
                    // Determine the base path for all references; that is, the lib/ folder.
                    var referenceBasePath = Path.Combine(
                        folder,
                        directory);

                    if (Directory.Exists(referenceBasePath))
                    {
                        // If no references are in nuspec, reference all of the libraries that
                        // are on disk.
                        if (references.Count == 0)
                        {
                            // Search through all of the target frameworks until we find one that
                            // has at least one file in it.
                            foreach (var clrNameOriginal in clrNames)
                            {
                                var clrName  = clrNameOriginal;
                                var foundClr = false;

                                if (clrName[0] == '=')
                                {
                                    // Exact match (strip the equals).
                                    clrName = clrName.Substring(1);

                                    // If this target framework doesn't exist for this library, skip it.
                                    var dirPath = Path.Combine(
                                        referenceBasePath,
                                        clrName);
                                    if (!Directory.Exists(dirPath))
                                    {
                                        continue;
                                    }
                                }
                                else if (clrName[0] == '?')
                                {
                                    // Substring, search the reference base path for any folders
                                    // with a matching substring.
                                    clrName = clrName.Substring(1);

                                    var baseDirPath = referenceBasePath;
                                    var found       = false;
                                    foreach (var subdir in new DirectoryInfo(baseDirPath).GetDirectories())
                                    {
                                        if (subdir.Name.Contains(clrName))
                                        {
                                            clrName = subdir.Name;
                                            found   = true;
                                            break;
                                        }
                                    }

                                    if (!found)
                                    {
                                        continue;
                                    }
                                }
                                else
                                {
                                    throw new InvalidOperationException("Unknown CLR name match type with '" + clrName +
                                                                        "'");
                                }

                                // Otherwise enumerate through all of the libraries in this folder.
                                foreach (var dll in Directory.EnumerateFiles(
                                             Path.Combine(
                                                 referenceBasePath, clrName),
                                             "*.dll"))
                                {
                                    // Determine the relative path to the library.
                                    var packageDll = Path.Combine(
                                        referenceBasePath,
                                        clrName,
                                        Path.GetFileName(dll));

                                    // Confirm again that the file actually exists on disk when
                                    // combined with the root path.
                                    if (File.Exists(
                                            Path.Combine(
                                                packageDll)))
                                    {
                                        // Create the library reference.
                                        if (!libraryReferences.ContainsKey(Path.GetFileNameWithoutExtension(dll)))
                                        {
                                            libraryReferences.Add(
                                                Path.GetFileNameWithoutExtension(dll),
                                                packageDll);
                                        }

                                        // Mark this target framework as having provided at least
                                        // one reference.
                                        foundClr = true;
                                    }
                                }

                                // Break if we have found at least one reference.
                                if (foundClr)
                                {
                                    break;
                                }
                            }
                        }

                        // For all of the references that were found in the original nuspec file,
                        // add those references.
                        foreach (var reference in references)
                        {
                            // Search through all of the target frameworks until we find the one
                            // that has the reference in it.
                            foreach (var clrName in clrNames)
                            {
                                // If this target framework doesn't exist for this library, skip it.
                                var packageDll = Path.Combine(
                                    referenceBasePath,
                                    clrName,
                                    reference);

                                if (File.Exists(
                                        Path.Combine(
                                            packageDll)))
                                {
                                    if (!libraryReferences.ContainsKey(Path.GetFileNameWithoutExtension(packageDll)))
                                    {
                                        libraryReferences.Add(
                                            Path.GetFileNameWithoutExtension(packageDll),
                                            packageDll);
                                    }
                                    break;
                                }
                            }
                        }
                    }
                }

                foreach (var kv in libraryReferences)
                {
                    RedirectableConsole.WriteLine("Found library to reference: " + kv.Key + " (at " + kv.Value + ")");
                }

                RedirectableConsole.WriteLine("Generating external project reference...");
                var document        = new XmlDocument();
                var externalProject = document.CreateElement("ExternalProject");
                externalProject.SetAttribute("Name", packageName);
                document.AppendChild(externalProject);
                foreach (var kv in libraryReferences)
                {
                    var binaryReference = document.CreateElement("Binary");
                    binaryReference.SetAttribute("Name", kv.Key);
                    binaryReference.SetAttribute("Path",
                                                 kv.Value.Substring(folder.Length).TrimStart(new[] { '/', '\\' }).Replace("%2B", "-"));
                    externalProject.AppendChild(binaryReference);
                }
                foreach (var package in packageDependencies)
                {
                    var externalReference = document.CreateElement("Reference");
                    externalReference.SetAttribute("Include", package.Key);
                    externalProject.AppendChild(externalReference);
                }
                document.Save(Path.Combine(folder, "_ProtobuildExternalProject.xml"));

                RedirectableConsole.WriteLine("Generating module...");
                var generatedModule = new ModuleInfo();
                generatedModule.Name     = packageName;
                generatedModule.Packages = new List <PackageRef>();

                foreach (var package in packageDependencies)
                {
                    generatedModule.Packages.Add(new PackageRef
                    {
                        Uri =
                            repoUrl.Replace("http://", "http-nuget://").Replace("https://", "https-nuget://") + "|" +
                            package.Key,
                        GitRef = package.Value.TrimStart('[').TrimEnd(']'),
                        Folder = package.Key
                    });
                }

                generatedModule.Save(Path.Combine(folder, "_ProtobuildModule.xml"));

                RedirectableConsole.WriteLine("Converting to a Protobuild package...");

                var target = new MemoryStream();
                var filter = new FileFilter(_getRecursiveUtilitiesInPath.GetRecursiveFilesInPath(folder));

                foreach (var kv in libraryReferences)
                {
                    filter.ApplyInclude(
                        Regex.Escape(kv.Value.Substring(folder.Length).Replace('\\', '/').TrimStart('/')));
                    filter.ApplyRewrite(
                        Regex.Escape(kv.Value.Substring(folder.Length).Replace('\\', '/').TrimStart('/')),
                        kv.Value.Substring(folder.Length).Replace('\\', '/').TrimStart('/').Replace("%2B", "-"));
                }

                filter.ApplyInclude("_ProtobuildExternalProject\\.xml");
                filter.ApplyRewrite("_ProtobuildExternalProject\\.xml", "Build/Projects/" + packageName + ".definition");
                filter.ApplyInclude("_ProtobuildModule\\.xml");
                filter.ApplyRewrite("_ProtobuildModule\\.xml", "Build/Module.xml");

                filter.ImplyDirectories();

                _packageCreator.Create(
                    target,
                    filter,
                    folder,
                    format,
                    platform);

                RedirectableConsole.WriteLine("Package conversion complete.");
                bytes = new byte[target.Position];
                target.Seek(0, SeekOrigin.Begin);
                target.Read(bytes, 0, bytes.Length);
            }
            finally
            {
                RedirectableConsole.WriteLine("Cleaning up temporary data...");
                PathUtils.AggressiveDirectoryDelete(folder);
            }

            return(bytes);
        }
예제 #5
0
        public static void Main(string[] args)
        {
            // Ensure we always use the invariant culture in Protobuild.
            Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;

            // Set our SSL trust policy.  Because Mono doesn't ship with root certificates
            // on most Linux distributions, we have to be a little more insecure here than
            // I'd like.  For protobuild.org we always verify that the root of the certificate
            // chain matches what we expect (so people can't forge a certificate from a
            // *different CA*), but for other domains we just have to implicitly trust them
            // on Linux since we have no root store.
            if (Path.DirectorySeparatorChar == '/' && !Directory.Exists("/Library"))
            {
                ServicePointManager.ServerCertificateValidationCallback = SSLValidationForLinux;
            }

            var kernel = new LightweightKernel();

            kernel.BindCore();
            kernel.BindBuildResources();
            kernel.BindGeneration();
            kernel.BindJSIL();
            kernel.BindTargets();
            kernel.BindFileFilter();
            kernel.BindPackages();
            kernel.BindAutomatedBuild();

            var featureManager = kernel.Get <IFeatureManager>();

            featureManager.LoadFeaturesForCurrentDirectory();

            var commandMappings = new Dictionary <string, ICommand>
            {
                { "sync", kernel.Get <SyncCommand>() },
                { "resync", kernel.Get <ResyncCommand>() },
                { "generate", kernel.Get <GenerateCommand>() },
                { "build", kernel.Get <BuildCommand>() },
                { "build-target", kernel.Get <BuildTargetCommand>() },
                { "build-property", kernel.Get <BuildPropertyCommand>() },
                { "build-process-arch", kernel.Get <BuildProcessArchCommand>() },
                { "clean", kernel.Get <CleanCommand>() },
                { "automated-build", kernel.Get <AutomatedBuildCommand>() },
                { "extract-xslt", kernel.Get <ExtractXSLTCommand>() },
                { "enable", kernel.Get <EnableServiceCommand>() },
                { "disable", kernel.Get <DisableServiceCommand>() },
                { "debug-service-resolution", kernel.Get <DebugServiceResolutionCommand>() },
                { "simulate-host-platform", kernel.Get <SimulateHostPlatformCommand>() },
                { "spec", kernel.Get <ServiceSpecificationCommand>() },
                { "query-features", kernel.Get <QueryFeaturesCommand>() },
                { "features", kernel.Get <FeaturesCommand>() },
                { "add", kernel.Get <AddPackageCommand>() },
                { "list", kernel.Get <ListPackagesCommand>() },
                { "install", kernel.Get <InstallPackageCommand>() },
                { "upgrade", kernel.Get <UpgradePackageCommand>() },
                { "upgrade-all", kernel.Get <UpgradeAllPackagesCommand>() },
                { "pack", kernel.Get <PackPackageCommand>() },
                { "format", kernel.Get <FormatPackageCommand>() },
                { "push", kernel.Get <PushPackageCommand>() },
                { "ignore-on-existing", kernel.Get <IgnoreOnExistingPackageCommand>() },
                { "repush", kernel.Get <RepushPackageCommand>() },
                { "resolve", kernel.Get <ResolveCommand>() },
                { "no-resolve", kernel.Get <NoResolveCommand>() },
                { "redirect", kernel.Get <RedirectPackageCommand>() },
                { "swap-to-source", kernel.Get <SwapToSourceCommand>() },
                { "swap-to-binary", kernel.Get <SwapToBinaryCommand>() },
                { "start", kernel.Get <StartCommand>() },
                { "no-generate", kernel.Get <NoGenerateCommand>() },
                { "no-host-generate", kernel.Get <NoHostGenerateCommand>() },
                { "execute", kernel.Get <ExecuteCommand>() },
                { "execute-configuration", kernel.Get <ExecuteConfigurationCommand>() },
            };

            var execution = new Execution();

            execution.CommandToExecute = kernel.Get <DefaultCommand>();

            var options = new Options();

            foreach (var kv in commandMappings)
            {
                var key   = kv.Key;
                var value = kv.Value;

                Action <string[]> handle = x =>
                {
                    if (value.IsRecognised())
                    {
                        value.Encounter(execution, x);
                    }
                    else if (value.IsIgnored())
                    {
                    }
                    else
                    {
                        throw new InvalidOperationException("Unknown argument '" + key + "'");
                    }
                };

                if (value.GetArgCount() == 0)
                {
                    options[key] = handle;
                }
                else
                {
                    options[key + "@" + value.GetArgCount()] = handle;
                }
            }

            Action <string[]> helpAction = x =>
            {
                PrintHelp(commandMappings);
                ExecEnvironment.Exit(0);
            };

            options["help"] = helpAction;
            options["?"]    = helpAction;

            if (ExecEnvironment.DoNotWrapExecutionInTry)
            {
                options.Parse(args);
            }
            else
            {
                try
                {
                    options.Parse(args);
                }
                catch (InvalidOperationException ex)
                {
                    Console.WriteLine(ex.Message);
                    PrintHelp(commandMappings);
                    ExecEnvironment.Exit(1);
                }
            }

            featureManager.ValidateEnabledFeatures();

            if (ExecEnvironment.DoNotWrapExecutionInTry)
            {
                var exitCode = execution.CommandToExecute.Execute(execution);
                ExecEnvironment.Exit(exitCode);
            }
            else
            {
                try
                {
                    var exitCode = execution.CommandToExecute.Execute(execution);
                    ExecEnvironment.Exit(exitCode);
                }
                catch (ExecEnvironment.SelfInvokeExitException)
                {
                    throw;
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                    ExecEnvironment.Exit(1);
                }
            }
        }
예제 #6
0
        public Tuple <int, string, string> RunProtobuild(ModuleInfo module, string args, bool capture = false)
        {
            var invokeInline = false;
            var myHash       = ExecEnvironment.GetProgramHash();
            var targetHash   = ExecEnvironment.GetProgramHash(Path.Combine(module.Path, "Protobuild.exe"));

            if (myHash == targetHash)
            {
                invokeInline = true;
            }

            if ((ExecEnvironment.RunProtobuildInProcess || invokeInline) && !capture)
            {
                var old = Environment.CurrentDirectory;
                try
                {
                    Environment.CurrentDirectory = module.Path;
                    return(new Tuple <int, string, string>(
                               ExecEnvironment.InvokeSelf(args.SplitCommandLine().ToArray()),
                               string.Empty,
                               string.Empty));
                }
                finally
                {
                    Environment.CurrentDirectory = old;
                }
            }

            var protobuildPath = Path.Combine(module.Path, "Protobuild.exe");

            try
            {
                var chmodStartInfo = new ProcessStartInfo
                {
                    FileName         = "chmod",
                    Arguments        = "a+x Protobuild.exe",
                    WorkingDirectory = module.Path,
                    CreateNoWindow   = capture,
                    UseShellExecute  = false
                };
                Process.Start(chmodStartInfo);
            }
            catch (ExecEnvironment.SelfInvokeExitException)
            {
                throw;
            }
            catch
            {
            }

            var stdout = string.Empty;
            var stderr = string.Empty;

            for (var attempt = 0; attempt < 3; attempt++)
            {
                if (File.Exists(protobuildPath))
                {
                    var pi = new ProcessStartInfo
                    {
                        FileName               = protobuildPath,
                        Arguments              = args,
                        WorkingDirectory       = module.Path,
                        CreateNoWindow         = capture,
                        RedirectStandardError  = capture,
                        RedirectStandardInput  = capture,
                        RedirectStandardOutput = capture,
                        UseShellExecute        = false
                    };
                    var p = new Process {
                        StartInfo = pi
                    };
                    if (capture)
                    {
                        p.OutputDataReceived += (sender, eventArgs) =>
                        {
                            if (!string.IsNullOrEmpty(eventArgs.Data))
                            {
                                if (capture)
                                {
                                    stdout += eventArgs.Data + "\n";
                                }
                                else
                                {
                                    Console.WriteLine(eventArgs.Data);
                                }
                            }
                        };
                        p.ErrorDataReceived += (sender, eventArgs) =>
                        {
                            if (!string.IsNullOrEmpty(eventArgs.Data))
                            {
                                if (capture)
                                {
                                    stderr += eventArgs.Data + "\n";
                                }
                                else
                                {
                                    Console.Error.WriteLine(eventArgs.Data);
                                }
                            }
                        };
                    }
                    try
                    {
                        p.Start();
                    }
                    catch (System.ComponentModel.Win32Exception ex)
                    {
                        if (ex.Message.Contains("Cannot find the specified file"))
                        {
                            // Mono sometimes throws this error even though the
                            // file does exist on disk.  The best guess is there's
                            // a race condition between performing chmod on the
                            // file and Mono actually seeing it as an executable file.
                            // Show a warning and sleep for a bit before retrying.
                            if (attempt != 2)
                            {
                                Console.WriteLine("WARNING: Unable to execute Protobuild.exe, will retry again...");
                                System.Threading.Thread.Sleep(2000);
                                continue;
                            }
                            else
                            {
                                Console.WriteLine("ERROR: Still unable to execute Protobuild.exe.");
                                throw;
                            }
                        }
                    }
                    if (capture)
                    {
                        p.BeginOutputReadLine();
                        p.BeginErrorReadLine();
                    }
                    p.WaitForExit();
                    return(new Tuple <int, string, string>(p.ExitCode, stdout, stderr));
                }
            }

            return(new Tuple <int, string, string>(1, string.Empty, string.Empty));
        }
예제 #7
0
        /// <summary>
        /// Generates a project at the target path.
        /// </summary>
        /// <param name="current">The current project to generate.</param>
        /// <param name="definitions">A list of all loaded project definitions.</param>
        /// <param name="workingDirectory"></param>
        /// <param name="rootPath">The module root path, with directory seperator appended.</param>
        /// <param name="projectName">The project name.</param>
        /// <param name="platformName">The platform name.</param>
        /// <param name="services">A list of services.</param>
        /// <param name="packagesFilePath">
        ///     Either the full path to the packages.config for the
        ///     generated project if it exists, or an empty string.
        /// </param>
        /// <param name="onActualGeneration"></param>
        /// <param name="debugProjectGeneration">Whether to emit a .input file for XSLT debugging.</param>
        public void Generate(
            DefinitionInfo current,
            List <LoadedDefinitionInfo> definitions,
            string workingDirectory,
            string rootPath,
            string projectName,
            string platformName,
            List <Service> services,
            out string packagesFilePath,
            Action onActualGeneration,
            bool debugProjectGeneration)
        {
            packagesFilePath = string.Empty;

            // Work out what document this is.
            var projectDoc = definitions.First(
                x => x.Project.DocumentElement.Attributes["Name"].Value == projectName)?.Project;

            // Check to see if we have a Project node; don't process it.
            if (projectDoc?.DocumentElement == null)
            {
                return;
            }

            // If this is a custom project, run any custom generation commands for
            // the current host and target platform.
            if (projectDoc.DocumentElement.Name == "CustomProject")
            {
                onActualGeneration();

                var onGenerateElements = projectDoc.DocumentElement.SelectNodes("OnGenerate");
                if (onGenerateElements != null)
                {
                    foreach (var onGenerateElement in onGenerateElements.OfType <XmlElement>())
                    {
                        var matches    = true;
                        var hostName   = onGenerateElement.GetAttribute("HostName");
                        var targetName = onGenerateElement.GetAttribute("TargetName");

                        if (!string.IsNullOrWhiteSpace(hostName))
                        {
                            if (hostName != _hostPlatformDetector.DetectPlatform())
                            {
                                matches = false;
                            }
                        }

                        if (!string.IsNullOrWhiteSpace(targetName))
                        {
                            if (targetName != platformName)
                            {
                                matches = false;
                            }
                        }

                        if (matches)
                        {
                            var command   = onGenerateElement.SelectSingleNode("Command")?.InnerText.Trim();
                            var arguments = onGenerateElement.SelectSingleNode("Arguments")?.InnerText.Trim() ?? string.Empty;

                            if (!string.IsNullOrWhiteSpace(command))
                            {
                                var workingPath = Path.Combine(
                                    rootPath,
                                    projectDoc.DocumentElement.Attributes["Path"].Value);
                                var resolvedCommandPath = Path.Combine(
                                    workingPath,
                                    command);

                                if (File.Exists(resolvedCommandPath))
                                {
                                    var process =
                                        Process.Start(new ProcessStartInfo(resolvedCommandPath, arguments)
                                    {
                                        WorkingDirectory = workingPath,
                                        UseShellExecute  = false
                                    });
                                    if (process == null)
                                    {
                                        RedirectableConsole.ErrorWriteLine("ERROR: Process did not start when running " + resolvedCommandPath + " " +
                                                                           arguments);
                                        ExecEnvironment.Exit(1);
                                        return;
                                    }
                                    process.WaitForExit();
                                    if (process.ExitCode != 0)
                                    {
                                        RedirectableConsole.ErrorWriteLine(
                                            "ERROR: Non-zero exit code " + process.ExitCode);
                                        ExecEnvironment.Exit(1);
                                        return;
                                    }
                                }
                            }
                        }
                    }
                }
            }

            // If this is not a normal project at this point, don't process it.
            if (projectDoc.DocumentElement.Name != "Project")
            {
                return;
            }

            // Load the appropriate project transformation XSLT.
            var languageAttribute = projectDoc.DocumentElement.Attributes["Language"];
            var languageText      = languageAttribute != null ? languageAttribute.Value : "C#";
            var language          = this.m_LanguageStringProvider.GetLanguageFromConfigurationName(languageText);
            var projectTransform  = this.m_ResourceProvider.LoadXSLT(workingDirectory, ResourceType.GenerateProject, language, platformName);

            // Work out what platforms this project should be generated for.
            var platformAttribute = projectDoc.DocumentElement.Attributes["Platforms"];

            string[] allowedPlatforms = null;
            if (platformAttribute != null)
            {
                allowedPlatforms = platformAttribute.Value
                                   .Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
                                   .Select(x => x.Trim())
                                   .ToArray();
            }

            // Filter on allowed platforms.
            if (allowedPlatforms != null)
            {
                var allowed = false;
                foreach (var platform in allowedPlatforms)
                {
                    if (string.Compare(platformName, platform, StringComparison.InvariantCultureIgnoreCase) == 0)
                    {
                        allowed = true;
                        break;
                    }
                }
                if (!allowed)
                {
                    return;
                }
            }

            // If the project has a <Services> node, but there are no entries in /Input/Services,
            // then nothing depends on this service (if there is a <Reference> to this project, it will
            // use the default service).  So for service-aware projects without any services being
            // referenced, we exclude them from the generation.
            if (this.m_ExcludedServiceAwareProjectDetector.IsExcludedServiceAwareProject(
                    projectDoc.DocumentElement.Attributes["Name"].Value,
                    projectDoc,
                    services))
            {
                return;
            }

            // Inform the user we're generating this project.
            onActualGeneration();

            // Add include projects if they have an AppliesTo tag that matches this project's name.
            this._includeProjectAppliesToUpdater.UpdateProjectReferences(definitions.Select(x => x.Project).ToList(), projectDoc);

            // Add references and properties from include projects.
            _includeProjectMerger.MergeInReferencesAndPropertiesForIncludeProjects(definitions, projectDoc, platformName);

            // Imply external project references from other external projects.  We do
            // this so that external projects can reference other external projects (which
            // we can't reasonably handle at the XSLT level since it's recursive).
            this.m_ExternalProjectReferenceResolver.ResolveExternalProjectReferences(definitions, projectDoc, platformName);

            // Generate Info.plist files if necessary (for Mac / iOS).
            this._mPlatformResourcesGenerator.GenerateInfoPListIfNeeded(definitions, current, projectDoc, platformName);

            // Work out what path to save at.
            var path = Path.Combine(
                rootPath,
                projectDoc.DocumentElement.Attributes["Path"].Value
                .Replace('\\', Path.DirectorySeparatorChar)
                .Replace('/', Path.DirectorySeparatorChar),
                projectDoc.DocumentElement.Attributes["Name"].Value + "." +
                platformName + "." + this.m_LanguageStringProvider.GetProjectExtension(language));

            // Make sure that the directory exists where the file will be stored.
            var targetFile = new FileInfo(path);

            if (!targetFile.Directory.Exists)
            {
                targetFile.Directory.Create();
            }

            path = targetFile.FullName;

            // Handle NuGet packages.config early so that it'll be in place
            // when the generator automatically determined dependencies.
            this.m_NuGetConfigMover.Move(rootPath, platformName, projectDoc);

            // Work out what path the NuGet packages.config might be at.
            var packagesFile = new FileInfo(
                Path.Combine(
                    rootPath,
                    projectDoc.DocumentElement.Attributes["Path"].Value
                    .Replace('\\', Path.DirectorySeparatorChar)
                    .Replace('/', Path.DirectorySeparatorChar),
                    "packages.config"));

            // Generate the input document.
            var input = this.m_ProjectInputGenerator.Generate(
                definitions.Select(x => x.Project).ToList(),
                workingDirectory,
                rootPath,
                projectName,
                platformName,
                packagesFile.FullName,
                projectDoc.DocumentElement.ChildNodes
                .OfType <XmlElement>()
                .Where(x => x.Name.ToLower() == "properties")
                .SelectMany(x => x.ChildNodes
                            .OfType <XmlElement>()),
                services);

            var settings = new XmlWriterSettings();

            settings.Indent = true;

            if (debugProjectGeneration)
            {
                using (var writer = XmlWriter.Create(path + ".input", settings))
                {
                    input.Save(writer);
                }
            }

            // Transform the input document using the XSLT transform.
            using (var writer = XmlWriter.Create(path, settings))
            {
                projectTransform.Transform(input, writer);
            }

            // Also remove any left over .sln or .userprefs files.
            var slnPath = Path.Combine(
                rootPath,
                projectDoc.DocumentElement.Attributes["Path"].Value,
                projectDoc.DocumentElement.Attributes["Name"].Value + "." +
                platformName + ".sln");
            var userprefsPath = Path.Combine(
                rootPath,
                projectDoc.DocumentElement.Attributes["Path"].Value,
                projectDoc.DocumentElement.Attributes["Name"].Value + "." +
                platformName + ".userprefs");

            if (File.Exists(slnPath))
            {
                File.Delete(slnPath);
            }
            if (File.Exists(userprefsPath))
            {
                File.Delete(userprefsPath);
            }

            // Only return the package file path if it exists.
            if (packagesFile.Exists)
            {
                packagesFilePath = packagesFile.FullName;
            }
        }
예제 #8
0
        public static void Main(string[] args)
        {
            // Ensure we always use the invariant culture in Protobuild.
            Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;

            var kernel = new LightweightKernel();

            kernel.BindCore();
            kernel.BindBuildResources();
            kernel.BindGeneration();
            kernel.BindJSIL();
            kernel.BindTargets();
            kernel.BindFileFilter();
            kernel.BindPackages();

            var commandMappings = new Dictionary <string, ICommand>
            {
                { "sync", kernel.Get <SyncCommand>() },
                { "resync", kernel.Get <ResyncCommand>() },
                { "generate", kernel.Get <GenerateCommand>() },
                { "clean", kernel.Get <CleanCommand>() },
                { "extract-xslt", kernel.Get <ExtractXSLTCommand>() },
                { "enable", kernel.Get <EnableServiceCommand>() },
                { "disable", kernel.Get <DisableServiceCommand>() },
                { "spec", kernel.Get <ServiceSpecificationCommand>() },
                { "add", kernel.Get <AddPackageCommand>() },
                { "upgrade", kernel.Get <UpgradePackageCommand>() },
                { "upgrade-all", kernel.Get <UpgradeAllPackagesCommand>() },
                { "pack", kernel.Get <PackPackageCommand>() },
                { "format", kernel.Get <FormatPackageCommand>() },
                { "push", kernel.Get <PushPackageCommand>() },
                { "resolve", kernel.Get <ResolveCommand>() },
                { "redirect", kernel.Get <RedirectPackageCommand>() },
                { "swap-to-source", kernel.Get <SwapToSourceCommand>() },
                { "swap-to-binary", kernel.Get <SwapToBinaryCommand>() },
                { "start", kernel.Get <StartCommand>() },
            };

            var execution = new Execution();

            execution.CommandToExecute = kernel.Get <DefaultCommand>();

            var options = new Options();

            foreach (var kv in commandMappings)
            {
                var key   = kv.Key;
                var value = kv.Value;

                if (value.GetArgCount() == 0)
                {
                    options[key] = x => { value.Encounter(execution, x); };
                }
                else
                {
                    options[key + "@" + value.GetArgCount()] = x => { value.Encounter(execution, x); };
                }
            }

            Action <string[]> helpAction = x =>
            {
                PrintHelp(commandMappings);
                ExecEnvironment.Exit(0);
            };

            options["help"] = helpAction;
            options["?"]    = helpAction;

            try
            {
                options.Parse(args);
            }
            catch (InvalidOperationException ex)
            {
                Console.WriteLine(ex.Message);
                PrintHelp(commandMappings);
                ExecEnvironment.Exit(1);
            }

            try
            {
                var exitCode = execution.CommandToExecute.Execute(execution);
                ExecEnvironment.Exit(exitCode);
            }
            catch (ExecEnvironment.SelfInvokeExitException)
            {
                throw;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                ExecEnvironment.Exit(1);
            }
        }
예제 #9
0
        /// <summary>
        /// Performs a resynchronisation, synchronisation, generation or clean on the specified module.
        /// </summary>
        /// <returns><c>true</c>, if the action succeeded, <c>false</c> otherwise.</returns>
        /// <param name="module">The module to perform the action on.</param>
        /// <param name="action">The action to perform, either "resync", "sync", "generate" or "clean".</param>
        /// <param name="platform">The platform to perform the action for.</param>
        /// <param name="enabledServices">A list of enabled services.</param>
        /// <param name="disabledServices">A list of disabled services.</param>
        /// <param name="serviceSpecPath">The service specification path.</param>
        public bool PerformAction(
            ModuleInfo module,
            string action,
            string platform           = null,
            string[] enabledServices  = null,
            string[] disabledServices = null,
            string serviceSpecPath    = null)
        {
            var platformSupplied = !string.IsNullOrWhiteSpace(platform);

            if (string.IsNullOrWhiteSpace(platform))
            {
                platform = this.m_HostPlatformDetector.DetectPlatform();
            }

            var originalPlatform = platform;

            platform = module.NormalizePlatform(platform);

            if (platform == null && !platformSupplied)
            {
                // The current host platform isn't supported, so we shouldn't try to
                // operate on it.
                string firstPlatform = null;
                switch (this.m_HostPlatformDetector.DetectPlatform())
                {
                case "Windows":
                    firstPlatform = module.DefaultWindowsPlatforms.Split(',').FirstOrDefault();
                    break;

                case "MacOS":
                    firstPlatform = module.DefaultMacOSPlatforms.Split(',').FirstOrDefault();
                    break;

                case "Linux":
                    firstPlatform = module.DefaultLinuxPlatforms.Split(',').FirstOrDefault();
                    break;
                }

                if (firstPlatform != null)
                {
                    // This will end up null if the first platform isn't supported
                    // either and hence throw the right message.
                    platform = module.NormalizePlatform(firstPlatform);
                }
            }

            if (platform == null)
            {
                Console.Error.WriteLine("The platform '" + originalPlatform + "' is not supported.");
                Console.Error.WriteLine("The following platforms are supported by this module:");
                foreach (
                    var supportedPlatform in
                    module.SupportedPlatforms.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
                    .Select(x => x.Trim())
                    .Where(x => !string.IsNullOrWhiteSpace(x)))
                {
                    Console.Error.WriteLine("  * " + supportedPlatform);
                }

                ExecEnvironment.Exit(1);
                return(false);
            }

            var primaryPlatform = platform;

            // You can generate multiple targets by default by setting the <DefaultWindowsPlatforms>
            // <DefaultMacOSPlatforms> and <DefaultLinuxPlatforms> tags in Module.xml.  Note that
            // synchronisation will only be done for the primary platform, as there is no correct
            // synchronisation behaviour when dealing with multiple C# projects.
            //
            // We only trigger this behaviour when the platform is omitted; if you explicitly
            // specify "Windows" on the command line, we'll only generate / resync / sync
            // the Windows platform.
            string multiplePlatforms = null;

            if (!platformSupplied)
            {
                switch (platform)
                {
                case "Windows":
                    multiplePlatforms = module.DefaultWindowsPlatforms;
                    break;

                case "MacOS":
                    multiplePlatforms = module.DefaultMacOSPlatforms;
                    break;

                case "Linux":
                    multiplePlatforms = module.DefaultLinuxPlatforms;
                    break;
                }
            }

            // If no overrides are set, just use the current platform.
            if (string.IsNullOrEmpty(multiplePlatforms))
            {
                multiplePlatforms = platform;
            }

            // Resolve submodules as needed.
            this.m_PackageManager.ResolveAll(module, primaryPlatform);

            // You can configure the default action for Protobuild in their project
            // with the <DefaultAction> tag in Module.xml.  If omitted, default to a resync.
            // Valid options for this tag are either "Generate", "Resync" or "Sync".

            // If the actions are "Resync" or "Sync", then we need to perform an initial
            // step against the primary platform.
            switch (action.ToLower())
            {
            case "generate":
                if (!this.GenerateProjectsForPlatform(module, primaryPlatform, enabledServices, disabledServices, serviceSpecPath))
                {
                    return(false);
                }

                break;

            case "resync":
                if (!this.ResyncProjectsForPlatform(module, primaryPlatform, enabledServices, disabledServices, serviceSpecPath))
                {
                    return(false);
                }

                break;

            case "sync":
                return(this.SyncProjectsForPlatform(module, primaryPlatform));

            case "clean":
                if (!this.CleanProjectsForPlatform(module, primaryPlatform))
                {
                    return(false);
                }

                break;

            default:
                Console.Error.WriteLine("Unknown option in <DefaultAction> tag of Module.xml.  Defaulting to resync!");
                return(this.ResyncProjectsForPlatform(module, primaryPlatform, enabledServices, disabledServices, serviceSpecPath));
            }

            // Now iterate through the multiple platforms specified.
            var multiplePlatformsArray =
                multiplePlatforms.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim());

            foreach (var platformIter in multiplePlatformsArray)
            {
                if (platformIter == primaryPlatform)
                {
                    // Already handled above.
                    continue;
                }

                // Resolve submodules as needed.
                this.m_PackageManager.ResolveAll(module, platformIter);

                switch (action.ToLower())
                {
                case "generate":
                case "resync":
                    // We do a generate under resync mode since we only want the primary platform
                    // to have synchronisation done (and it has had above).
                    if (!this.GenerateProjectsForPlatform(module, platformIter, enabledServices, disabledServices, serviceSpecPath))
                    {
                        return(false);
                    }

                    break;

                case "clean":
                    if (!this.CleanProjectsForPlatform(module, platformIter))
                    {
                        return(false);
                    }

                    break;

                default:
                    throw new InvalidOperationException("Code should never reach this point");
                }
            }

            // All the steps succeeded, so return true.
            return(true);
        }
예제 #10
0
        /// <summary>
        /// Runs the instance of Protobuild.exe present in the module.
        /// </summary>
        /// <param name="args">The arguments to pass to Protobuild.</param>
        public void RunProtobuild(string args)
        {
            if (ExecEnvironment.RunProtobuildInProcess)
            {
                var old = Environment.CurrentDirectory;
                try
                {
                    Environment.CurrentDirectory = this.Path;
                    ExecEnvironment.InvokeSelf(args.Split(' '));
                }
                finally
                {
                    Environment.CurrentDirectory = old;
                }
                return;
            }

            var protobuildPath = System.IO.Path.Combine(this.Path, "Protobuild.exe");

            try
            {
                var chmodStartInfo = new ProcessStartInfo
                {
                    FileName         = "chmod",
                    Arguments        = "a+x Protobuild.exe",
                    WorkingDirectory = this.Path,
                    CreateNoWindow   = true,
                    UseShellExecute  = false
                };
                Process.Start(chmodStartInfo);
            }
            catch (ExecEnvironment.SelfInvokeExitException)
            {
                throw;
            }
            catch
            {
            }

            if (File.Exists(protobuildPath))
            {
                var pi = new ProcessStartInfo
                {
                    FileName               = protobuildPath,
                    Arguments              = args,
                    WorkingDirectory       = this.Path,
                    CreateNoWindow         = true,
                    RedirectStandardError  = true,
                    RedirectStandardInput  = true,
                    RedirectStandardOutput = true,
                    UseShellExecute        = false
                };
                var p = new Process {
                    StartInfo = pi
                };
                p.OutputDataReceived += (sender, eventArgs) =>
                {
                    if (!string.IsNullOrEmpty(eventArgs.Data))
                    {
                        Console.WriteLine(eventArgs.Data);
                    }
                };
                p.ErrorDataReceived += (sender, eventArgs) =>
                {
                    if (!string.IsNullOrEmpty(eventArgs.Data))
                    {
                        Console.Error.WriteLine(eventArgs.Data);
                    }
                };
                p.Start();
                p.BeginOutputReadLine();
                p.BeginErrorReadLine();
                p.WaitForExit();
            }
        }