Exemplo n.º 1
0
        public void ResolveAll(ModuleInfo module, string platform)
        {
            if (!_featureManager.IsFeatureEnabled(Feature.PackageManagement))
            {
                return;
            }

            Console.WriteLine("Starting resolution of packages for " + platform + "...");

            if (module.Packages != null && module.Packages.Count > 0)
            {
                foreach (var submodule in module.Packages)
                {
                    if (submodule.IsActiveForPlatform(platform))
                    {
                        Console.WriteLine("Resolving: " + submodule.Uri);
                        this.Resolve(module, submodule, platform, null, null);
                    }
                    else
                    {
                        Console.WriteLine("Skipping resolution for " + submodule.Uri + " because it is not active for this target platform");
                    }
                }
            }

            foreach (var submodule in module.GetSubmodules(platform))
            {
                if (submodule.Packages.Count == 0 && submodule.GetSubmodules(platform).Length == 0)
                {
                    if (_featureManager.IsFeatureEnabledInSubmodule(module, submodule, Feature.OptimizationSkipResolutionOnNoPackagesOrSubmodules))
                    {
                        Console.WriteLine(
                            "Skipping package resolution in submodule for " + submodule.Name + " (there are no submodule or packages)");
                        continue;
                    }
                }

                Console.WriteLine(
                    "Invoking package resolution in submodule for " + submodule.Name);
                _moduleExecution.RunProtobuild(
                    submodule,
                    _featureManager.GetFeatureArgumentToPassToSubmodule(module, submodule) +
                    "-resolve " + platform + " " + packageRedirector.GetRedirectionArguments());
                Console.WriteLine(
                    "Finished submodule package resolution for " + submodule.Name);
            }

            Console.WriteLine("Package resolution complete.");
        }
Exemplo n.º 2
0
        /// <summary>
        /// Normalizes the platform string from user input, automatically correcting case
        /// and validating against a list of supported platforms.
        /// </summary>
        /// <returns>The platform string.</returns>
        /// <param name="platform">The normalized platform string.</param>
        public string NormalizePlatform(ModuleInfo module, string platform)
        {
            var supportedPlatforms = ModuleInfo.GetSupportedPlatformsDefault();
            var defaultPlatforms   = true;

            if (!string.IsNullOrEmpty(module.SupportedPlatforms))
            {
                supportedPlatforms = module.SupportedPlatforms;
                defaultPlatforms   = false;
            }

            var supportedPlatformsArray = supportedPlatforms.Split(new[] { ',' })
                                          .Select(x => x.Trim())
                                          .Where(x => !string.IsNullOrWhiteSpace(x))
                                          .ToArray();

            var allowWeb = _featureManager.IsFeatureEnabled(Feature.PackageManagement);

            // Search the array to find a platform that matches case insensitively
            // to the specified platform.  If we are using the default list, then we allow
            // other platforms to be specified (in case the developer has modified the XSLT to
            // support others but is not using <SupportedPlatforms>).  If the developer has
            // explicitly set the supported platforms, then we return null if the user passes
            // an unknown platform (the caller is expected to exit at this point).
            foreach (var supportedPlatform in supportedPlatformsArray)
            {
                if (string.Compare(supportedPlatform, platform, StringComparison.InvariantCultureIgnoreCase) == 0)
                {
                    if (supportedPlatform == "Web" && !allowWeb)
                    {
                        // We don't permit the web platform when package management
                        // is disabled, as we can't install JSIL properly.
                        return(null);
                    }

                    return(supportedPlatform);
                }
            }

            if (defaultPlatforms)
            {
                if (string.Compare("Web", platform, StringComparison.InvariantCultureIgnoreCase) == 0 && !allowWeb)
                {
                    // We don't permit the web platform when package management
                    // is disabled, as we can't install JSIL properly.
                    return(null);
                }

                return(platform);
            }
            else
            {
                return(null);
            }
        }
Exemplo n.º 3
0
 public bool IsRecognised()
 {
     return(_featureManager.IsFeatureEnabled(Feature.PackageManagement));
 }
Exemplo n.º 4
0
 public bool IsIgnored()
 {
     return(!_featureManager.IsFeatureEnabled(Feature.PackageManagement));
 }
Exemplo n.º 5
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);
        }
Exemplo n.º 6
0
        public void ResolveAll(string workingDirectory, ModuleInfo module, string platform, bool?enableParallelisation, bool forceUpgrade, bool?safeResolve)
        {
            if (!_featureManager.IsFeatureEnabled(Feature.PackageManagement))
            {
                return;
            }

            RedirectableConsole.WriteLine("Starting resolution of packages for " + platform + "...");

            var parallelisation = enableParallelisation ?? _hostPlatformDetector.DetectPlatform() == "Windows";

            if (parallelisation)
            {
                RedirectableConsole.WriteLine("Enabled parallelisation; use --no-parallel to disable...");
            }

            if (module.Packages != null && module.Packages.Count > 0)
            {
                var taskList   = new List <Task <Tuple <string, Action> > >();
                var resultList = new List <Tuple <string, Action> >();
                foreach (var submodule in module.Packages)
                {
                    if (submodule.IsActiveForPlatform(platform))
                    {
                        RedirectableConsole.WriteLine("Querying: " + submodule.Uri);
                        var submodule1 = submodule;
                        if (parallelisation)
                        {
                            var task = new Func <Task <Tuple <string, Action> > >(async() =>
                            {
                                var metadata = await Task.Run(() =>
                                                              Lookup(workingDirectory, module, submodule1, platform, null, null, forceUpgrade, safeResolve));
                                if (metadata == null)
                                {
                                    return(new Tuple <string, Action>(submodule1.Uri, () => { }));
                                }
                                return(new Tuple <string, Action>(submodule1.Uri,
                                                                  () => { this.Resolve(workingDirectory, metadata, submodule1, null, null, forceUpgrade, safeResolve); }));
                            });
                            taskList.Add(task());
                        }
                        else
                        {
                            var metadata = Lookup(workingDirectory, module, submodule1, platform, null, null, forceUpgrade, safeResolve);
                            if (metadata == null)
                            {
                                resultList.Add(new Tuple <string, Action>(submodule1.Uri, () => { }));
                            }
                            else
                            {
                                resultList.Add(new Tuple <string, Action>(submodule1.Uri,
                                                                          () => { this.Resolve(workingDirectory, metadata, submodule1, null, null, forceUpgrade, safeResolve); }));
                            }
                        }
                    }
                    else
                    {
                        RedirectableConsole.WriteLine("Skipping resolution for " + submodule.Uri + " because it is not active for this target platform");
                    }
                }

                if (parallelisation)
                {
                    var taskArray = taskList.ToArray();
                    Task.WaitAll(taskArray);
                    foreach (var tuple in taskArray)
                    {
                        RedirectableConsole.WriteLine("Resolving: " + tuple.Result.Item1);
                        tuple.Result.Item2();
                    }
                }
                else
                {
                    foreach (var tuple in resultList)
                    {
                        RedirectableConsole.WriteLine("Resolving: " + tuple.Item1);
                        tuple.Item2();
                    }
                }
            }

            foreach (var submodule in module.GetSubmodules(platform))
            {
                if (submodule.Packages.Count == 0 && submodule.GetSubmodules(platform).Length == 0)
                {
                    if (_featureManager.IsFeatureEnabledInSubmodule(module, submodule, Feature.OptimizationSkipResolutionOnNoPackagesOrSubmodules))
                    {
                        RedirectableConsole.WriteLine(
                            "Skipping package resolution in submodule for " + submodule.Name + " (there are no submodule or packages)");
                        continue;
                    }
                }

                RedirectableConsole.WriteLine(
                    "Invoking package resolution in submodule for " + submodule.Name);
                string parallelMode = null;
                if (_featureManager.IsFeatureEnabledInSubmodule(module, submodule, Feature.TaskParallelisation))
                {
                    if (parallelisation)
                    {
                        parallelMode += "-parallel ";
                    }
                    else
                    {
                        parallelMode += "-no-parallel ";
                    }
                }
                _moduleExecution.RunProtobuild(
                    submodule,
                    _featureManager.GetFeatureArgumentToPassToSubmodule(module, submodule) + parallelMode +
                    "-resolve " + platform + " " + packageRedirector.GetRedirectionArguments());
                RedirectableConsole.WriteLine(
                    "Finished submodule package resolution for " + submodule.Name);
            }

            RedirectableConsole.WriteLine("Package resolution complete.");
        }