Beispiel #1
0
        public async Task LoadProjectAsync(Path recipeFilePath)
        {
            var loadResult = await RecipeExtensions.TryLoadRecipeFromFileAsync(recipeFilePath);

            if (loadResult.IsSuccess)
            {
                var packageDirectory = recipeFilePath.GetParent();
                var targetPath       = await GetTargetPathAsync(packageDirectory);

                var soupTargetDirectory = targetPath + new Path(".soup/");

                var evaluateGraphFile = soupTargetDirectory + BuildConstants.GenerateEvaluateOperationGraphFileName;
                var fileSystemState   = new FileSystemState();
                if (!OperationGraphManager.TryLoadState(evaluateGraphFile, fileSystemState, out var evaluateGraph))
                {
                    NotifyError($"Failed to load Operation Graph: {evaluateGraphFile}");
                    return;
                }

                Graph = BuildGraph(fileSystemState, evaluateGraph);
            }
            else
            {
                NotifyError($"Failed to load Recipe file: {recipeFilePath}");
            }
        }
Beispiel #2
0
        /// <summary>
        /// Execute the entire operation graph that is referenced by this build generate engine.
        /// </summary>
        public async Task GenerateAsync(Path soupTargetDirectory)
        {
            // Run all build operations in the correct order with incremental build checks
            Log.Diag("Build generate start");

            // Load the parameters file
            var parametersFile = soupTargetDirectory + BuildConstants.GenerateParametersFileName;

            if (!ValueTableManager.TryLoadState(parametersFile, out var parametersState))
            {
                Log.Error("Failed to load the parameter file: " + parametersFile.ToString());
                throw new InvalidOperationException("Failed to load parameter file.");
            }

            // Load the read access file
            var readAccessFile = soupTargetDirectory + BuildConstants.GenerateReadAccessFileName;
            var readAccessList = new List <Path>();

            if (!await PathListManager.TryLoadFileAsync(readAccessFile, readAccessList))
            {
                Log.Error("Failed to load the read access file: " + readAccessFile.ToString());
                throw new InvalidOperationException("Failed to load read access file.");
            }

            // Load the write access file
            var writeAccessFile = soupTargetDirectory + BuildConstants.GenerateWriteAccessFileName;
            var writeAccessList = new List <Path>();

            if (!await PathListManager.TryLoadFileAsync(writeAccessFile, writeAccessList))
            {
                Log.Error("Failed to load the write access file: " + writeAccessFile.ToString());
                throw new InvalidOperationException("Failed to load write access file.");
            }

            // Get the required input state from the parameters
            var targetDirectory  = new Path(parametersState["TargetDirectory"].AsString().ToString());
            var packageDirectory = new Path(parametersState["PackageDirectory"].AsString().ToString());

            // Load the recipe file
            var recipeFile = packageDirectory + BuildConstants.RecipeFileName;

            var(isSuccess, recipe) = await RecipeExtensions.TryLoadRecipeFromFileAsync(recipeFile);

            if (!isSuccess)
            {
                Log.Error("Failed to load the recipe: " + recipeFile.ToString());
                throw new InvalidOperationException("Failed to load recipe.");
            }

            // Combine all the dependencies shared state
            var dependenciesSharedState = LoadDependenciesSharedState(parametersState);

            // Generate the set of build extension libraries
            var buildExtensionLibraries = GenerateBuildExtensionSet(recipe, dependenciesSharedState);

            // Start a new active state that is initialized to the recipe itself
            var activeState = new ValueTable();

            // Initialize the Recipe Root Table
            var recipeState = recipe.Table;

            activeState.Add("Recipe", new Value(recipeState));

            // Initialize the Parameters Root Table
            activeState.Add("Parameters", new Value(parametersState));

            // Initialize the Dependencies Root Table
            activeState.Add("Dependencies", new Value(dependenciesSharedState));

            // Keep the extension libraries open while running the build system
            // to ensure their memory is kept alive
            var         evaluateGraph = new OperationGraph();
            IValueTable sharedState   = new ValueTable();

            {
                // Create a new build system for the requested build
                var buildTaskManager = new BuildTaskManager();

                // Run all build extension register callbacks
                foreach (var buildExtension in buildExtensionLibraries)
                {
                    var library = LoadPlugin(buildExtension);
                    FindAllCommands(library, buildTaskManager);
                }

                // Run the build
                var buildState = new BuildState(
                    activeState,
                    _fileSystemState,
                    readAccessList,
                    writeAccessList);
                buildTaskManager.Execute(buildState, soupTargetDirectory);

                // Grab the build results so the dependency libraries can be released asap
                evaluateGraph = buildState.BuildOperationGraph();
                sharedState   = buildState.SharedState;
            }

            // Save the operation graph so the evaluate phase can load it
            var evaluateGraphFile = soupTargetDirectory + BuildConstants.GenerateEvaluateOperationGraphFileName;

            OperationGraphManager.SaveState(evaluateGraphFile, evaluateGraph, _fileSystemState);

            // Save the shared state that is to be passed to the downstream builds
            var sharedStateFile = soupTargetDirectory + BuildConstants.GenerateSharedStateFileName;

            ValueTableManager.SaveState(sharedStateFile, sharedState);
            Log.Diag("Build generate end");
        }