public void Autopackage(
            FileFilter fileFilter,
            Execution execution,
            ModuleInfo module,
            string rootPath,
            string platform)
        {
            var definitions    = module.GetDefinitionsRecursively(platform).ToArray();
            var loadedProjects = new List <XmlDocument>();

            foreach (var definition in definitions)
            {
                Console.WriteLine("Loading: " + definition.Name);
                loadedProjects.Add(
                    this.m_ProjectLoader.Load(
                        Path.Combine(
                            definition.ModulePath,
                            "Build",
                            "Projects",
                            definition.Name + ".definition"),
                        platform,
                        module.Path,
                        definition.ModulePath));
            }

            var            serviceManager = new ServiceManager(platform);
            List <Service> services;

            serviceManager.SetRootDefinitions(module.GetDefinitions());

            var enabledServices  = execution.EnabledServices.ToArray();
            var disabledServices = execution.DisabledServices.ToArray();

            foreach (var service in enabledServices)
            {
                serviceManager.EnableService(service);
            }

            foreach (var service in disabledServices)
            {
                serviceManager.DisableService(service);
            }

            services = serviceManager.CalculateDependencyGraph(loadedProjects);

            foreach (var service in services)
            {
                if (service.ServiceName != null)
                {
                    Console.WriteLine("Enabled service: " + service.FullName);
                }
            }

            foreach (var definition in definitions)
            {
                if (definition.SkipAutopackage)
                {
                    Console.WriteLine("Skipping: " + definition.Name);
                    continue;
                }

                switch (definition.Type)
                {
                case "External":
                    Console.WriteLine("Packaging: " + definition.Name);
                    this.AutomaticallyPackageExternalProject(definitions, services, fileFilter, rootPath, platform, definition);
                    break;

                case "Content":
                    Console.WriteLine("Content project definition skipped: " + definition.Name);
                    break;

                default:
                    Console.WriteLine("Packaging: " + definition.Name);
                    this.AutomaticallyPackageNormalProject(definitions, services, fileFilter, rootPath, platform, definition);
                    break;
                }
            }

            // If there is no Module.xml in the source mappings already, then copy the current module.
            var filterDictionary = fileFilter.ToDictionary(k => k.Key, v => v.Value);

            if (!filterDictionary.ContainsValue("Build/Module.xml"))
            {
                fileFilter.AddManualMapping(Path.Combine(module.Path, "Build", "Module.xml"), "Build/Module.xml");
            }
        }
Example #2
0
        public override bool Execute()
        {
            if (string.Compare(this.Platform, "Web", StringComparison.InvariantCultureIgnoreCase) == 0)
            {
                // Trigger JSIL provider download if needed.
                string jsilDirectory, jsilCompilerFile;
                if (!this.m_JSILProvider.GetJSIL(out jsilDirectory, out jsilCompilerFile))
                {
                    return(false);
                }
            }

            var module = ModuleInfo.Load(Path.Combine(this.RootPath, "Build", "Module.xml"));

            // Resolve packages in submodules first (so that services are available).
            foreach (var submodule in module.GetSubmodules(this.Platform))
            {
                this.LogMessage(
                    "Invoking package resolution in submodule for " + submodule.Name);
                submodule.RunProtobuild("-resolve " + this.Platform + " " + this.m_PackageRedirector.GetRedirectionArguments());
                this.LogMessage(
                    "Finished submodule package resolution for " + submodule.Name);
            }

            this.LogMessage(
                "Starting generation of projects for " + this.Platform);

            var definitions    = module.GetDefinitionsRecursively(this.Platform).ToArray();
            var loadedProjects = new List <XmlDocument>();

            foreach (var definition in definitions)
            {
                this.LogMessage("Loading: " + definition.Name);
                loadedProjects.Add(
                    this.m_ProjectLoader.Load(
                        Path.Combine(
                            definition.ModulePath,
                            "Build",
                            "Projects",
                            definition.Name + ".definition"),
                        this.Platform,
                        module.Path,
                        definition.ModulePath));
            }

            var            serviceManager = new ServiceManager(this.Platform);
            List <Service> services;
            string         serviceSpecPath;

            if (this.ServiceSpecPath == null)
            {
                serviceManager.SetRootDefinitions(module.GetDefinitions());

                if (this.EnableServices == null)
                {
                    this.EnableServices = new string[0];
                }

                if (this.DisableServices == null)
                {
                    this.DisableServices = new string[0];
                }

                foreach (var service in this.EnableServices)
                {
                    serviceManager.EnableService(service);
                }

                foreach (var service in this.DisableServices)
                {
                    serviceManager.DisableService(service);
                }

                try
                {
                    services = serviceManager.CalculateDependencyGraph(loadedProjects);
                }
                catch (InvalidOperationException ex)
                {
                    Console.WriteLine("Error during service resolution: " + ex.Message);
                    return(false);
                }

                serviceSpecPath = serviceManager.SaveServiceSpec(services);

                foreach (var service in services)
                {
                    if (service.ServiceName != null)
                    {
                        this.LogMessage("Enabled service: " + service.FullName);
                    }
                }
            }
            else
            {
                services        = serviceManager.LoadServiceSpec(this.ServiceSpecPath);
                serviceSpecPath = this.ServiceSpecPath;
            }

            // Run Protobuild in batch mode in each of the submodules
            // where it is present.
            foreach (var submodule in module.GetSubmodules(this.Platform))
            {
                this.LogMessage(
                    "Invoking submodule generation for " + submodule.Name);
                submodule.RunProtobuild("-generate " + this.Platform + " -spec " + serviceSpecPath + " " + this.m_PackageRedirector.GetRedirectionArguments());
                this.LogMessage(
                    "Finished submodule generation for " + submodule.Name);
            }

            var repositoryPaths = new List <string>();

            foreach (var definition in definitions.Where(x => x.ModulePath == module.Path))
            {
                string repositoryPath;
                var    definitionCopy = definition;
                this.m_ProjectGenerator.Generate(
                    loadedProjects,
                    this.RootPath,
                    definition.Name,
                    this.Platform,
                    services,
                    out repositoryPath,
                    () => this.LogMessage("Generating: " + definitionCopy.Name));

                // Only add repository paths if they should be generated.
                if (module.GenerateNuGetRepositories && !string.IsNullOrEmpty(repositoryPath))
                {
                    repositoryPaths.Add(repositoryPath);
                }
            }

            var solution = Path.Combine(
                this.RootPath,
                this.ModuleName + "." + this.Platform + ".sln");

            this.LogMessage("Generating: (solution)");
            this.m_SolutionGenerator.Generate(
                module,
                loadedProjects,
                this.Platform,
                solution,
                services,
                repositoryPaths);

            // Only save the specification cache if we allow synchronisation
            if (module.DisableSynchronisation == null || !module.DisableSynchronisation.Value)
            {
                var serviceCache = Path.Combine(this.RootPath, this.ModuleName + "." + this.Platform + ".speccache");
                this.LogMessage("Saving service specification");
                File.Copy(serviceSpecPath, serviceCache, true);
            }

            this.LogMessage(
                "Generation complete.");

            return(true);
        }
        public void Autopackage(
            string workingDirectory,
            FileFilter fileFilter,
            Execution execution,
            ModuleInfo module,
            string rootPath,
            string platform,
            string packageFormat,
            List <string> temporaryFiles)
        {
            var definitions    = module.GetDefinitionsRecursively(platform).ToArray();
            var loadedProjects = new List <LoadedDefinitionInfo>();

            foreach (var definition in definitions)
            {
                RedirectableConsole.WriteLine("Loading: " + definition.Name);
                loadedProjects.Add(
                    this.m_ProjectLoader.Load(
                        platform,
                        module,
                        definition));
            }

            var            serviceManager = new ServiceManager(platform);
            List <Service> services;

            serviceManager.SetRootDefinitions(module.GetDefinitions());

            var enabledServices  = execution.EnabledServices.ToArray();
            var disabledServices = execution.DisabledServices.ToArray();

            foreach (var service in enabledServices)
            {
                serviceManager.EnableService(service);
            }

            foreach (var service in disabledServices)
            {
                serviceManager.DisableService(service);
            }

            if (execution.DebugServiceResolution)
            {
                serviceManager.EnableDebugInformation();
            }

            services = serviceManager.CalculateDependencyGraph(loadedProjects.Select(x => x.Project).ToList());

            foreach (var service in services)
            {
                if (service.ServiceName != null)
                {
                    RedirectableConsole.WriteLine("Enabled service: " + service.FullName);
                }
            }

            var packagePaths = module.Packages
                               .Select(x => new DirectoryInfo(System.IO.Path.Combine(module.Path, x.Folder)).FullName)
                               .ToArray();

            foreach (var definition in definitions)
            {
                if (definition.SkipAutopackage)
                {
                    RedirectableConsole.WriteLine("Skipping: " + definition.Name);
                    continue;
                }

                var definitionNormalizedPath = new FileInfo(definition.AbsolutePath).FullName;
                if (packagePaths.Any(definitionNormalizedPath.StartsWith))
                {
                    RedirectableConsole.WriteLine("Skipping: " + definition.Name + " (part of another package)");
                    continue;
                }

                switch (definition.Type)
                {
                case "External":
                    RedirectableConsole.WriteLine("Packaging: " + definition.Name);
                    this.AutomaticallyPackageExternalProject(definitions, services, fileFilter, rootPath, platform, definition, temporaryFiles);
                    break;

                case "Include":
                    RedirectableConsole.WriteLine("Packaging: " + definition.Name);
                    this.AutomaticallyPackageIncludeProject(definitions, services, fileFilter, rootPath, platform, definition);
                    break;

                case "Content":
                    RedirectableConsole.WriteLine("Content project definition skipped: " + definition.Name);
                    break;

                default:
                    RedirectableConsole.WriteLine("Packaging: " + definition.Name);
                    this.AutomaticallyPackageNormalProject(definitions, services, fileFilter, rootPath, platform, definition, temporaryFiles);
                    break;
                }
            }

            // If there is no Module.xml in the source mappings already, then copy the current module.
            if (!fileFilter.ContainsTargetPath("Build/Module.xml"))
            {
                fileFilter.AddManualMapping(Path.Combine(module.Path, "Build", "Module.xml"), "Build/Module.xml");
            }
        }
        public override bool Execute()
        {
            if (string.Compare(Platform, "Web", StringComparison.InvariantCultureIgnoreCase) == 0)
            {
                // Trigger JSIL provider download if needed.
                string jsilDirectory, jsilCompilerFile;
                if (!m_JSILProvider.GetJSIL(out jsilDirectory, out jsilCompilerFile))
                {
                    return(false);
                }
            }

            var module = ModuleInfo.Load(Path.Combine(RootPath, "Build", "Module.xml"));

            LogMessage(
                "Starting generation of projects for " + Platform);

            var definitions    = module.GetDefinitionsRecursively(Platform).ToArray();
            var loadedProjects = new List <LoadedDefinitionInfo>();

            if (_hostPlatformDetector.DetectPlatform() == "Windows")
            {
                var concurrentProjects = new ConcurrentBag <LoadedDefinitionInfo>();

                Parallel.ForEach(definitions, definition =>
                {
                    LogMessage("Loading: " + definition.Name);
                    concurrentProjects.Add(
                        m_ProjectLoader.Load(
                            Platform,
                            module,
                            definition));
                });

                // Do this so we maintain order with the original definitions list.
                foreach (var definition in definitions)
                {
                    var loadedProject = concurrentProjects.FirstOrDefault(x => x.Definition == definition);
                    if (loadedProject != null)
                    {
                        loadedProjects.Add(loadedProject);
                    }
                }
            }
            else
            {
                foreach (var definition in definitions)
                {
                    LogMessage("Loading: " + definition.Name);
                    loadedProjects.Add(
                        m_ProjectLoader.Load(
                            Platform,
                            module,
                            definition));
                }
            }

            var                  serviceManager = new ServiceManager(Platform);
            List <Service>       services;
            TemporaryServiceSpec serviceSpecPath;

            if (ServiceSpecPath == null)
            {
                serviceManager.SetRootDefinitions(module.GetDefinitions());

                if (EnableServices == null)
                {
                    EnableServices = new string[0];
                }

                if (DisableServices == null)
                {
                    DisableServices = new string[0];
                }

                foreach (var service in EnableServices)
                {
                    serviceManager.EnableService(service);
                }

                foreach (var service in DisableServices)
                {
                    serviceManager.DisableService(service);
                }

                if (DebugServiceResolution)
                {
                    serviceManager.EnableDebugInformation();
                }

                try
                {
                    services = serviceManager.CalculateDependencyGraph(loadedProjects.Select(x => x.Project).ToList());
                }
                catch (InvalidOperationException ex)
                {
                    RedirectableConsole.WriteLine("Error during service resolution: " + ex.Message);
                    return(false);
                }

                serviceSpecPath = serviceManager.SaveServiceSpec(services);

                foreach (var service in services)
                {
                    if (service.ServiceName != null)
                    {
                        LogMessage("Enabled service: " + service.FullName);
                    }
                }
            }
            else
            {
                services        = serviceManager.LoadServiceSpec(ServiceSpecPath);
                serviceSpecPath = new TemporaryServiceSpec(ServiceSpecPath, true);
            }

            using (serviceSpecPath)
            {
                var submodulesToProcess = new List <ModuleInfo>();
                var allSubmodules       = module.GetSubmodules(Platform);

                if (_hostPlatformDetector.DetectPlatform() == "Windows")
                {
                    var concurrentSubmodulesToProcess = new ConcurrentBag <ModuleInfo>();

                    Parallel.ForEach(allSubmodules, submodule =>
                    {
                        if (_featureManager.IsFeatureEnabledInSubmodule(module, submodule,
                                                                        Feature.OptimizationSkipInvocationOnNoStandardProjects))
                        {
                            if (submodule.GetDefinitionsRecursively(Platform).All(x => !x.IsStandardProject))
                            {
                                // Do not invoke this submodule.
                                LogMessage(
                                    "Skipping submodule generation for " + submodule.Name +
                                    " (there are no projects to generate)");
                            }
                            else
                            {
                                concurrentSubmodulesToProcess.Add(submodule);
                            }
                        }
                    });

                    // Do this so we maintain order with the original GetSubmodules list.
                    foreach (var submodule in allSubmodules)
                    {
                        if (concurrentSubmodulesToProcess.Contains(submodule))
                        {
                            submodulesToProcess.Add(submodule);
                        }
                    }
                }
                else
                {
                    foreach (var submodule in module.GetSubmodules(Platform))
                    {
                        if (_featureManager.IsFeatureEnabledInSubmodule(module, submodule,
                                                                        Feature.OptimizationSkipInvocationOnNoStandardProjects))
                        {
                            if (submodule.GetDefinitionsRecursively(Platform).All(x => !x.IsStandardProject))
                            {
                                // Do not invoke this submodule.
                                LogMessage(
                                    "Skipping submodule generation for " + submodule.Name +
                                    " (there are no projects to generate)");
                            }
                            else
                            {
                                submodulesToProcess.Add(submodule);
                            }
                        }
                    }
                }

                // Run Protobuild in batch mode in each of the submodules
                // where it is present.
                foreach (var submodule in submodulesToProcess)
                {
                    LogMessage(
                        "Invoking submodule generation for " + submodule.Name);
                    var noResolve = _featureManager.IsFeatureEnabledInSubmodule(module, submodule,
                                                                                Feature.PackageManagementNoResolve)
                        ? " -no-resolve"
                        : string.Empty;
                    var noHostPlatform = DisableHostPlatformGeneration &&
                                         _featureManager.IsFeatureEnabledInSubmodule(module, submodule,
                                                                                     Feature.NoHostGenerate)
                        ? " -no-host-generate"
                        : string.Empty;
                    _moduleExecution.RunProtobuild(
                        submodule,
                        _featureManager.GetFeatureArgumentToPassToSubmodule(module, submodule) +
                        "-generate " + Platform +
                        " -spec " + serviceSpecPath +
                        " " + m_PackageRedirector.GetRedirectionArguments() +
                        noResolve + noHostPlatform);
                    LogMessage(
                        "Finished submodule generation for " + submodule.Name);
                }

                var repositoryPaths = new List <string>();

                if (_hostPlatformDetector.DetectPlatform() == "Windows")
                {
                    var concurrentRepositoryPaths = new ConcurrentBag <string>();

                    Parallel.ForEach(definitions.Where(x => x.ModulePath == module.Path), definition =>
                    {
                        if (definition.PostBuildHook && RequiresHostPlatform != null)
                        {
                            // We require the host platform projects at this point.
                            RequiresHostPlatform();
                        }

                        string repositoryPath;
                        var definitionCopy = definition;
                        m_ProjectGenerator.Generate(
                            definition,
                            loadedProjects,
                            WorkingDirectory,
                            RootPath,
                            definition.Name,
                            Platform,
                            services,
                            out repositoryPath,
                            () => LogMessage("Generating: " + definitionCopy.Name),
                            DebugProjectGeneration);

                        // Only add repository paths if they should be generated.
                        if (module.GenerateNuGetRepositories && !string.IsNullOrEmpty(repositoryPath))
                        {
                            concurrentRepositoryPaths.Add(repositoryPath);
                        }
                    });

                    repositoryPaths = concurrentRepositoryPaths.ToList();
                }
                else
                {
                    foreach (var definition in definitions.Where(x => x.ModulePath == module.Path))
                    {
                        if (definition.PostBuildHook && RequiresHostPlatform != null)
                        {
                            // We require the host platform projects at this point.
                            RequiresHostPlatform();
                        }

                        string repositoryPath;
                        var    definitionCopy = definition;
                        m_ProjectGenerator.Generate(
                            definition,
                            loadedProjects,
                            WorkingDirectory,
                            RootPath,
                            definition.Name,
                            Platform,
                            services,
                            out repositoryPath,
                            () => LogMessage("Generating: " + definitionCopy.Name),
                            DebugProjectGeneration);

                        // Only add repository paths if they should be generated.
                        if (module.GenerateNuGetRepositories && !string.IsNullOrEmpty(repositoryPath))
                        {
                            repositoryPaths.Add(repositoryPath);
                        }
                    }
                }

                var solution = Path.Combine(
                    RootPath,
                    ModuleName + "." + Platform + ".sln");
                LogMessage("Generating: (solution)");
                m_SolutionGenerator.Generate(
                    WorkingDirectory,
                    module,
                    loadedProjects.Select(x => x.Project).ToList(),
                    Platform,
                    solution,
                    services,
                    repositoryPaths,
                    DebugProjectGeneration);

                // Only save the specification cache if we allow synchronisation
                if (module.DisableSynchronisation == null || !module.DisableSynchronisation.Value)
                {
                    var serviceCache = Path.Combine(RootPath, ModuleName + "." + Platform + ".speccache");
                    LogMessage("Saving service specification");
                    File.Copy(serviceSpecPath.Path, serviceCache, true);
                }

                LogMessage(
                    "Generation complete.");
            }

            return(true);
        }