예제 #1
0
        protected override CompilationResult Build(ProjectGraphNode projectNode)
        {
            var result = base.Build(projectNode);

            AfterRootBuild(projectNode, result);
            return(result);
        }
예제 #2
0
        private IncrementalResult InputItemsChanged(ProjectGraphNode graphNode, CompilerIO compilerIO)
        {
            // check empty inputs / outputs
            if (!compilerIO.Inputs.Any())
            {
                return(new IncrementalResult("the project has no inputs"));
            }

            if (!compilerIO.Outputs.Any())
            {
                return(new IncrementalResult("the project has no outputs"));
            }

            // check non existent items
            var result = CheckMissingIO(compilerIO.Inputs, "inputs");

            if (result.NeedsRebuilding)
            {
                return(result);
            }

            result = CheckMissingIO(compilerIO.Outputs, "outputs");
            if (result.NeedsRebuilding)
            {
                return(result);
            }

            return(CheckInputGlobChanges(graphNode, compilerIO));
        }
예제 #3
0
        private IncrementalResult CheckInputGlobChanges(ProjectGraphNode graphNode, CompilerIO compilerIO)
        {
            // check cache against input glob pattern changes
            var incrementalCacheFile = graphNode.ProjectContext.IncrementalCacheFile(_configuration, _buildBasePath, _outputPath);

            if (!File.Exists(incrementalCacheFile))
            {
                // cache is not present (first compilation); can't determine if globs changed; cache will be generated after build processes project
                return(IncrementalResult.DoesNotNeedRebuild);
            }

            var incrementalCache = IncrementalCache.ReadFromFile(incrementalCacheFile);

            var diffResult = compilerIO.DiffInputs(incrementalCache.CompilerIO);

            if (diffResult.Deletions.Any())
            {
                return(new IncrementalResult("Input items removed from last build", diffResult.Deletions));
            }

            if (diffResult.Additions.Any())
            {
                return(new IncrementalResult("Input items added from last build", diffResult.Additions));
            }

            return(IncrementalResult.DoesNotNeedRebuild);
        }
예제 #4
0
        private IncrementalResult CLIChanged(ProjectGraphNode graphNode)
        {
            var currentVersionFile         = DotnetFiles.VersionFile;
            var versionFileFromLastCompile = graphNode.ProjectContext.GetSDKVersionFile(_configuration, _buildBasePath, _outputPath);

            if (!File.Exists(currentVersionFile))
            {
                // this CLI does not have a version file; cannot tell if CLI changed
                return(IncrementalResult.DoesNotNeedRebuild);
            }

            if (!File.Exists(versionFileFromLastCompile))
            {
                // this is the first compilation; cannot tell if CLI changed
                return(IncrementalResult.DoesNotNeedRebuild);
            }

            var currentContent = DotnetFiles.ReadAndInterpretVersionFile();

            var versionsAreEqual = string.Equals(currentContent, File.ReadAllText(versionFileFromLastCompile), StringComparison.OrdinalIgnoreCase);

            return(versionsAreEqual
                ? IncrementalResult.DoesNotNeedRebuild
                : new IncrementalResult("the version or bitness of the CLI changed since the last build"));
        }
예제 #5
0
        private IncrementalResult CLIChanged(ProjectGraphNode graphNode)
        {
            var currentVersionFile = DotnetFiles.VersionFile;
            var versionFileFromLastCompile = graphNode.ProjectContext.GetSDKVersionFile(_configuration, _buildBasePath, _outputPath);

            if (!File.Exists(currentVersionFile))
            {
                // this CLI does not have a version file; cannot tell if CLI changed
                return IncrementalResult.DoesNotNeedRebuild;
            }

            if (!File.Exists(versionFileFromLastCompile))
            {
                // this is the first compilation; cannot tell if CLI changed
                return IncrementalResult.DoesNotNeedRebuild;
            }

            var currentContent = DotnetFiles.ReadAndInterpretVersionFile();

            var versionsAreEqual = string.Equals(currentContent, File.ReadAllText(versionFileFromLastCompile), StringComparison.OrdinalIgnoreCase);

            return versionsAreEqual
                ? IncrementalResult.DoesNotNeedRebuild
                : new IncrementalResult("the version or bitness of the CLI changed since the last build");
        }
예제 #6
0
        protected override bool NeedsRebuilding(ProjectGraphNode graphNode)
        {
            var result = _incrementalManager.NeedsRebuilding(graphNode);

            PrintIncrementalResult(graphNode.ProjectContext.GetDisplayName(), result);

            return(result.NeedsRebuilding);
        }
예제 #7
0
        public void CacheIncrementalState(ProjectGraphNode graphNode)
        {
            var incrementalCacheFile = graphNode.ProjectContext.IncrementalCacheFile(_configuration, _buildBasePath, _outputPath);

            var incrementalCache = new IncrementalCache(_compilerIoManager.GetCompileIO(graphNode));

            incrementalCache.WriteToFile(incrementalCacheFile);
        }
예제 #8
0
        private CompilerIO ComputeIO(ProjectGraphNode graphNode)
        {
            var inputs  = new List <string>();
            var outputs = new List <string>();

            var isRootProject = graphNode.IsRoot;
            var project       = graphNode.ProjectContext;

            var calculator         = project.GetOutputPaths(_configuration, _buildBasePath, _outputPath);
            var binariesOutputPath = calculator.CompilationOutputPath;
            var compilerOptions    = project.ProjectFile.GetCompilerOptions(project.TargetFramework, _configuration);

            // input: project.json
            inputs.Add(project.ProjectFile.ProjectFilePath);

            // input: lock file; find when dependencies change
            AddLockFile(project, inputs);

            // input: source files
            inputs.AddRange(CompilerUtil.GetCompilationSources(project, compilerOptions));

            var allOutputPath = new HashSet <string>(calculator.CompilationFiles.All());

            if (isRootProject && project.ProjectFile.HasRuntimeOutput(_configuration))
            {
                var runtimeContext = _workspace.GetRuntimeContext(project, _runtimes);
                foreach (var path in runtimeContext.GetOutputPaths(_configuration, _buildBasePath, _outputPath).RuntimeFiles.All())
                {
                    allOutputPath.Add(path);
                }
            }
            foreach (var dependency in graphNode.Dependencies)
            {
                var outputFiles = dependency.ProjectContext
                                  .GetOutputPaths(_configuration, _buildBasePath, _outputPath)
                                  .CompilationFiles;

                inputs.Add(outputFiles.Assembly);
            }

            // output: compiler outputs
            foreach (var path in allOutputPath)
            {
                outputs.Add(path);
            }

            // input compilation options files
            AddCompilationOptions(project, _configuration, inputs);

            // input / output: resources with culture
            AddNonCultureResources(project, calculator.IntermediateOutputDirectoryPath, inputs, outputs, compilerOptions);

            // input / output: resources without culture
            AddCultureResources(project, binariesOutputPath, inputs, outputs, compilerOptions);

            return(new CompilerIO(inputs, outputs));
        }
예제 #9
0
 public CompilationResult? GetCompilationResult(ProjectGraphNode projectNode)
 {
     CompilationResult result;
     if (_compilationResults.TryGetValue(projectNode.ProjectContext.Identity, out result))
     {
         return result;
     }
     return null;
 }
예제 #10
0
        private CompilerIO ComputeIO(ProjectGraphNode graphNode)
        {
            var inputs = new List<string>();
            var outputs = new List<string>();

            var isRootProject = graphNode.IsRoot;
            var project = graphNode.ProjectContext;

            var calculator = project.GetOutputPaths(_configuration, _buildBasePath, _outputPath);
            var binariesOutputPath = calculator.CompilationOutputPath;
            var compilerOptions = project.ProjectFile.GetCompilerOptions(project.TargetFramework, _configuration);

            // input: project.json
            inputs.Add(project.ProjectFile.ProjectFilePath);

            // input: lock file; find when dependencies change
            AddLockFile(project, inputs);

            // input: source files
            inputs.AddRange(CompilerUtil.GetCompilationSources(project, compilerOptions));

            var allOutputPath = new HashSet<string>(calculator.CompilationFiles.All());
            if (isRootProject && project.ProjectFile.HasRuntimeOutput(_configuration))
            {
                var runtimeContext = _workspace.GetRuntimeContext(project, _runtimes);
                foreach (var path in runtimeContext.GetOutputPaths(_configuration, _buildBasePath, _outputPath).RuntimeFiles.All())
                {
                    allOutputPath.Add(path);
                }
            }
            foreach (var dependency in graphNode.Dependencies)
            {
                var outputFiles = dependency.ProjectContext
                    .GetOutputPaths(_configuration, _buildBasePath, _outputPath)
                    .CompilationFiles;

                inputs.Add(outputFiles.Assembly);
            }

            // output: compiler outputs
            foreach (var path in allOutputPath)
            {
                outputs.Add(path);
            }

            // input compilation options files
            AddCompilationOptions(project, _configuration, inputs);

            // input / output: resources with culture
            AddNonCultureResources(project, calculator.IntermediateOutputDirectoryPath, inputs, outputs, compilerOptions);

            // input / output: resources without culture
            AddCultureResources(project, binariesOutputPath, inputs, outputs, compilerOptions);

            return new CompilerIO(inputs, outputs);
        }
예제 #11
0
        public CompilationResult?GetCompilationResult(ProjectGraphNode projectNode)
        {
            CompilationResult result;

            if (_compilationResults.TryGetValue(projectNode.ProjectContext.Identity, out result))
            {
                return(result);
            }
            return(null);
        }
예제 #12
0
        private void PrintSummary(ProjectGraphNode projectNode, bool success)
        {
            // todo: Ideally it's the builder's responsibility for adding the time elapsed. That way we avoid cross cutting display concerns between compile and build for printing time elapsed
            if (success)
            {
                var preconditions = _preconditionManager.GetIncrementalPreconditions(projectNode);
                Reporter.Output.Write(" " + preconditions.LogMessage());
                Reporter.Output.WriteLine();
            }

            Reporter.Output.WriteLine();
        }
예제 #13
0
 protected void AfterRootBuild(ProjectGraphNode projectNode, CompilationResult result)
 {
     if (result != CompilationResult.IncrementalSkip && projectNode.IsRoot)
     {
         var success = result == CompilationResult.Success;
         if (success)
         {
             MakeRunnable(projectNode);
         }
         PrintSummary(projectNode, success);
     }
 }
예제 #14
0
        private void PrintSummary(ProjectGraphNode projectNode, bool success)
        {
            // todo: Ideally it's the builder's responsibility for adding the time elapsed. That way we avoid cross cutting display concerns between compile and build for printing time elapsed
            if (success)
            {
                var preconditions = _preconditionManager.GetIncrementalPreconditions(projectNode);
                Reporter.Output.Write(" " + preconditions.LogMessage());
                Reporter.Output.WriteLine();
            }

            Reporter.Output.WriteLine();
        }
예제 #15
0
        protected virtual CompilationResult Build(ProjectGraphNode projectNode)
        {
            CompilationResult result;
            if (_compilationResults.TryGetValue(projectNode.ProjectContext.Identity, out result))
            {
                return result;
            }
            result = CompileWithDependencies(projectNode);

            _compilationResults[projectNode.ProjectContext.Identity] = result;

            return result;
        }
예제 #16
0
        protected virtual CompilationResult Build(ProjectGraphNode projectNode)
        {
            CompilationResult result;

            if (_compilationResults.TryGetValue(projectNode.ProjectContext.Identity, out result))
            {
                return(result);
            }
            result = CompileWithDependencies(projectNode);

            _compilationResults[projectNode.ProjectContext.Identity] = result;

            return(result);
        }
예제 #17
0
        protected override CompilationResult RunCompile(ProjectGraphNode projectNode)
        {
            try
            {
                var managedCompiler = new ManagedCompiler(_scriptRunner, _commandFactory);

                var success = managedCompiler.Compile(projectNode.ProjectContext, _args);
                return(success ? CompilationResult.Success : CompilationResult.Failure);
            }
            finally
            {
                StampProjectWithSDKVersion(projectNode.ProjectContext);
                _incrementalManager.CacheIncrementalState(projectNode);
            }
        }
예제 #18
0
        private CompilationResult CompileWithDependencies(ProjectGraphNode projectNode)
        {
            if (!_skipDependencies)
            {
                foreach (var dependency in projectNode.Dependencies)
                {
                    var result = Build(dependency);
                    if (result == CompilationResult.Failure)
                    {
                        return(CompilationResult.Failure);
                    }
                }
            }

            var context = projectNode.ProjectContext;

            using (PerfTrace.Current.CaptureTiming($"{projectNode.ProjectContext.ProjectName()}", nameof(HasSourceFiles)))
            {
                if (!HasSourceFiles(context))
                {
                    return(CompilationResult.IncrementalSkip);
                }
            }

            bool needsRebuilding;

            using (PerfTrace.Current.CaptureTiming($"{projectNode.ProjectContext.ProjectName()}", nameof(NeedsRebuilding)))
            {
                needsRebuilding = NeedsRebuilding(projectNode);
            }

            if (needsRebuilding)
            {
                using (PerfTrace.Current.CaptureTiming($"{projectNode.ProjectContext.ProjectName()}", nameof(RunCompile)))
                {
                    return(RunCompile(projectNode));
                }
            }
            else
            {
                using (PerfTrace.Current.CaptureTiming($"{projectNode.ProjectContext.ProjectName()}", nameof(ProjectSkiped)))
                {
                    ProjectSkiped(projectNode);
                }
                return(CompilationResult.IncrementalSkip);
            }
        }
예제 #19
0
        private CompilationResult CompileWithDependencies(ProjectGraphNode projectNode)
        {
            if (!_skipDependencies)
            {
                foreach (var dependency in projectNode.Dependencies)
                {
                    var result = Build(dependency);
                    if (result == CompilationResult.Failure)
                    {
                        return CompilationResult.Failure;
                    }
                }
            }

            var context = projectNode.ProjectContext;
            using (PerfTrace.Current.CaptureTiming($"{projectNode.ProjectContext.ProjectName()}", nameof(HasSourceFiles)))
            {
                if (!HasSourceFiles(context))
                {
                    return CompilationResult.IncrementalSkip;
                }
            }

            bool needsRebuilding;
            using (PerfTrace.Current.CaptureTiming($"{projectNode.ProjectContext.ProjectName()}", nameof(NeedsRebuilding)))
            {
                needsRebuilding = NeedsRebuilding(projectNode);
            }

            if (needsRebuilding)
            {
                using (PerfTrace.Current.CaptureTiming($"{projectNode.ProjectContext.ProjectName()}",nameof(RunCompile)))
                {
                    return RunCompile(projectNode);
                }
            }
            else
            {
                using (PerfTrace.Current.CaptureTiming($"{projectNode.ProjectContext.ProjectName()}", nameof(ProjectSkiped)))
                {
                    ProjectSkiped(projectNode);
                }
                return CompilationResult.IncrementalSkip;
            }
        }
예제 #20
0
        private IncrementalResult CheckInputGlobChanges(ProjectGraphNode graphNode, CompilerIO compilerIO)
        {
            // check cache against input glob pattern changes
            var incrementalCacheFile = graphNode.ProjectContext.IncrementalCacheFile(_configuration, _buildBasePath, _outputPath);

            if (!File.Exists(incrementalCacheFile))
            {
                // cache is not present (first compilation); can't determine if globs changed; cache will be generated after build processes project
                return(IncrementalResult.DoesNotNeedRebuild);
            }

            var incrementalCache = IncrementalCache.ReadFromFile(incrementalCacheFile);

            var diffResult = compilerIO.DiffInputs(incrementalCache.CompilerIO);

            if (diffResult.Deletions.Any())
            {
                return(new IncrementalResult("Input items removed from last build", diffResult.Deletions));
            }

            if (diffResult.Additions.Any())
            {
                return(new IncrementalResult("Input items added from last build", diffResult.Additions));
            }

            var keys           = incrementalCache.BuildArguments.Keys.Union(_incrementalAffectingArguments.Keys);
            var mismatchedKeys = keys.Where(k =>
            {
                string cachedVal;
                string currentVal;

                return(!incrementalCache.BuildArguments.TryGetValue(k, out cachedVal) ||
                       !_incrementalAffectingArguments.TryGetValue(k, out currentVal) ||
                       !string.Equals(cachedVal ?? string.Empty, currentVal ?? string.Empty, StringComparison.Ordinal));
            });

            if (mismatchedKeys.Any())
            {
                return(new IncrementalResult("Build arguments changed since last build", mismatchedKeys));
            }

            return(IncrementalResult.DoesNotNeedRebuild);
        }
예제 #21
0
        private void MakeRunnable(ProjectGraphNode graphNode)
        {
            try
            {
                var runtimeContext = graphNode.ProjectContext.ProjectFile.HasRuntimeOutput(_args.ConfigValue) ?
                                     _args.Workspace.GetRuntimeContext(graphNode.ProjectContext, _args.GetRuntimes()) :
                                     graphNode.ProjectContext;

                var outputPaths     = runtimeContext.GetOutputPaths(_args.ConfigValue, _args.BuildBasePathValue, _args.OutputValue);
                var libraryExporter = runtimeContext.CreateExporter(_args.ConfigValue, _args.BuildBasePathValue);

                CopyCompilationOutput(outputPaths);

                var executable = new Executable(runtimeContext, outputPaths, libraryExporter, _args.ConfigValue);
                executable.MakeCompilationOutputRunnable();
            }
            catch (Exception e)
            {
                throw new Exception($"Failed to make the following project runnable: {graphNode.ProjectContext.GetDisplayName()} reason: {e.Message}", e);
            }
        }
        public IncrementalPreconditions GetIncrementalPreconditions(ProjectGraphNode projectNode)
        {
            IncrementalPreconditions preconditions;
            if (_preconditions.TryGetValue(projectNode.ProjectContext.Identity, out preconditions))
            {
                return preconditions;
            }

            preconditions = new IncrementalPreconditions(_printPreconditions);

            if (_forceNonIncremental)
            {
                preconditions.AddForceUnsafePrecondition();
            }

            var project = projectNode.ProjectContext;
            CollectScriptPreconditions(project, preconditions);
            CollectCompilerNamePreconditions(project, preconditions);
            CollectCheckPathProbingPreconditions(project, preconditions);
            _preconditions[projectNode.ProjectContext.Identity] = preconditions;
            return preconditions;
        }
예제 #23
0
        public IncrementalResult NeedsRebuilding(ProjectGraphNode graphNode)
        {
            if (!_shouldSkipDependencies &&
                graphNode.Dependencies.Any(d => _projectBuilder.GetCompilationResult(d) != CompilationResult.IncrementalSkip))
            {
                return(new IncrementalResult("dependencies changed"));
            }

            var preconditions = _preconditionManager.GetIncrementalPreconditions(graphNode);

            if (preconditions.PreconditionsDetected())
            {
                return(new IncrementalResult($"project is not safe for incremental compilation. Use {BuildCommandApp.BuildProfileFlag} flag for more information."));
            }

            var compilerIO = _compilerIoManager.GetCompileIO(graphNode);

            var result = CLIChanged(graphNode);

            if (result.NeedsRebuilding)
            {
                return(result);
            }

            result = InputItemsChanged(graphNode, compilerIO);
            if (result.NeedsRebuilding)
            {
                return(result);
            }

            result = TimestampsChanged(compilerIO);
            if (result.NeedsRebuilding)
            {
                return(result);
            }

            return(IncrementalResult.DoesNotNeedRebuild);
        }
예제 #24
0
        public IncrementalPreconditions GetIncrementalPreconditions(ProjectGraphNode projectNode)
        {
            IncrementalPreconditions preconditions;

            if (_preconditions.TryGetValue(projectNode.ProjectContext.Identity, out preconditions))
            {
                return(preconditions);
            }

            preconditions = new IncrementalPreconditions(_printPreconditions);

            if (_forceNonIncremental)
            {
                preconditions.AddForceUnsafePrecondition();
            }

            var project = projectNode.ProjectContext;

            CollectScriptPreconditions(project, preconditions);
            CollectCompilerNamePreconditions(project, preconditions);
            CollectCheckPathProbingPreconditions(project, preconditions);
            _preconditions[projectNode.ProjectContext.Identity] = preconditions;
            return(preconditions);
        }
예제 #25
0
        public IncrementalResult NeedsRebuilding(ProjectGraphNode graphNode)
        {
            if (!_shouldSkipDependencies &&
                graphNode.Dependencies.Any(d => _projectBuilder.GetCompilationResult(d) != CompilationResult.IncrementalSkip))
            {
                return new IncrementalResult("dependencies changed");
            }

            var preconditions = _preconditionManager.GetIncrementalPreconditions(graphNode);
            if (preconditions.PreconditionsDetected())
            {
                return new IncrementalResult($"project is not safe for incremental compilation. Use {BuildCommandApp.BuildProfileFlag} flag for more information.");
            }

            var compilerIO = _compilerIoManager.GetCompileIO(graphNode);

            var result = CLIChanged(graphNode);
            if (result.NeedsRebuilding)
            {
                return result;
            }

            result = InputItemsChanged(graphNode, compilerIO);
            if (result.NeedsRebuilding)
            {
                return result;
            }

            result = TimestampsChanged(compilerIO);
            if (result.NeedsRebuilding)
            {
                return result;
            }

            return IncrementalResult.DoesNotNeedRebuild;
        }
예제 #26
0
        private IncrementalResult InputItemsChanged(ProjectGraphNode graphNode, CompilerIO compilerIO)
        {
            // check empty inputs / outputs
            if (!compilerIO.Inputs.Any())
            {
                return new IncrementalResult("the project has no inputs");
            }

            if (!compilerIO.Outputs.Any())
            {
                return new IncrementalResult("the project has no outputs");
            }

            // check non existent items
            var result = CheckMissingIO(compilerIO.Inputs, "inputs");
            if (result.NeedsRebuilding)
            {
                return result;
            }

            result = CheckMissingIO(compilerIO.Outputs, "outputs");
            if (result.NeedsRebuilding)
            {
                return result;
            }

            return CheckInputGlobChanges(graphNode, compilerIO);
        }
예제 #27
0
 protected virtual void ProjectSkiped(ProjectGraphNode projectNode)
 {
 }
예제 #28
0
 protected void AfterRootBuild(ProjectGraphNode projectNode, CompilationResult result)
 {
     if (result != CompilationResult.IncrementalSkip && projectNode.IsRoot)
     {
         var success = result == CompilationResult.Success;
         if (success)
         {
             MakeRunnable(projectNode);
         }
         PrintSummary(projectNode, success);
     }
 }
예제 #29
0
 protected abstract CompilationResult RunCompile(ProjectGraphNode projectNode);
예제 #30
0
        protected override CompilationResult RunCompile(ProjectGraphNode projectNode)
        {
            try
            {
                var managedCompiler = new ManagedCompiler(_scriptRunner, _commandFactory);

                var success = managedCompiler.Compile(projectNode.ProjectContext, _args);
                return success ? CompilationResult.Success : CompilationResult.Failure;
            }
            finally
            {
                StampProjectWithSDKVersion(projectNode.ProjectContext);
                _incrementalManager.CacheIncrementalState(projectNode);
            }
        }
예제 #31
0
 protected override void ProjectSkiped(ProjectGraphNode projectNode)
 {
     StampProjectWithSDKVersion(projectNode.ProjectContext);
     _incrementalManager.CacheIncrementalState(projectNode);
 }
예제 #32
0
        protected override bool NeedsRebuilding(ProjectGraphNode graphNode)
        {
            var result = _incrementalManager.NeedsRebuilding(graphNode);

            PrintIncrementalResult(graphNode.ProjectContext.GetDisplayName(), result);

            return result.NeedsRebuilding;
        }
예제 #33
0
 protected virtual bool NeedsRebuilding(ProjectGraphNode projectNode)
 {
     return true;
 }
예제 #34
0
 // computes all the inputs and outputs that would be used in the compilation of a project
 public CompilerIO GetCompileIO(ProjectGraphNode graphNode)
 {
     return(_cache.GetOrAdd(graphNode.ProjectContext.Identity, i => ComputeIO(graphNode)));
 }
예제 #35
0
 protected override CompilationResult Build(ProjectGraphNode projectNode)
 {
     var result = base.Build(projectNode);
     AfterRootBuild(projectNode, result);
     return result;
 }
예제 #36
0
 protected virtual bool NeedsRebuilding(ProjectGraphNode projectNode)
 {
     return(true);
 }
예제 #37
0
        private IncrementalResult CheckInputGlobChanges(ProjectGraphNode graphNode, CompilerIO compilerIO)
        {
            // check cache against input glob pattern changes
            var incrementalCacheFile = graphNode.ProjectContext.IncrementalCacheFile(_configuration, _buildBasePath, _outputPath);

            if (!File.Exists(incrementalCacheFile))
            {
                // cache is not present (first compilation); can't determine if globs changed; cache will be generated after build processes project
                return IncrementalResult.DoesNotNeedRebuild;
            }

            var incrementalCache = IncrementalCache.ReadFromFile(incrementalCacheFile);

            var diffResult = compilerIO.DiffInputs(incrementalCache.CompilerIO);

            if (diffResult.Deletions.Any())
            {
                return new IncrementalResult("Input items removed from last build", diffResult.Deletions);
            }

            if (diffResult.Additions.Any())
            {
                return new IncrementalResult("Input items added from last build", diffResult.Additions);
            }

            var keys = incrementalCache.BuildArguments.Keys.Union(_incrementalAffectingArguments.Keys);
            var mismatchedKeys = keys.Where(k =>
            {
                string cachedVal;
                string currentVal;

                return !incrementalCache.BuildArguments.TryGetValue(k, out cachedVal) ||
                    !_incrementalAffectingArguments.TryGetValue(k, out currentVal) ||
                    !string.Equals(cachedVal ?? string.Empty, currentVal ?? string.Empty, StringComparison.Ordinal);
            });
            if (mismatchedKeys.Any())
            {
                return new IncrementalResult("Build arguments changed since last build", mismatchedKeys);
            }

            return IncrementalResult.DoesNotNeedRebuild;
        }
예제 #38
0
 protected override void ProjectSkiped(ProjectGraphNode projectNode)
 {
     StampProjectWithSDKVersion(projectNode.ProjectContext);
     _incrementalManager.CacheIncrementalState(projectNode);
 }
예제 #39
0
 protected abstract CompilationResult RunCompile(ProjectGraphNode projectNode);
예제 #40
0
        public void CacheIncrementalState(ProjectGraphNode graphNode)
        {
            var incrementalCacheFile = graphNode.ProjectContext.IncrementalCacheFile(_configuration, _buildBasePath, _outputPath);

            var incrementalCache = new IncrementalCache(_compilerIoManager.GetCompileIO(graphNode), _incrementalAffectingArguments);
            incrementalCache.WriteToFile(incrementalCacheFile);
        }
예제 #41
0
 // computes all the inputs and outputs that would be used in the compilation of a project
 public CompilerIO GetCompileIO(ProjectGraphNode graphNode)
 {
     return _cache.GetOrAdd(graphNode.ProjectContext.Identity, i => ComputeIO(graphNode));
 }
예제 #42
0
        private void MakeRunnable(ProjectGraphNode graphNode)
        {
            try
            {
                var runtimeContext = graphNode.ProjectContext.ProjectFile.HasRuntimeOutput(_args.ConfigValue) ?
                    _args.Workspace.GetRuntimeContext(graphNode.ProjectContext, _args.GetRuntimes()) :
                    graphNode.ProjectContext;

                var outputPaths = runtimeContext.GetOutputPaths(_args.ConfigValue, _args.BuildBasePathValue, _args.OutputValue);
                var libraryExporter = runtimeContext.CreateExporter(_args.ConfigValue, _args.BuildBasePathValue);

                CopyCompilationOutput(outputPaths);

                var executable = new Executable(runtimeContext, outputPaths, libraryExporter, _args.ConfigValue);
                executable.MakeCompilationOutputRunnable();
            }
            catch (Exception e)
            {
                throw new Exception($"Failed to make the following project runnable: {graphNode.ProjectContext.GetDisplayName()} reason: {e.Message}", e);
            }
        }
예제 #43
0
 protected virtual void ProjectSkiped(ProjectGraphNode projectNode)
 {
 }