private static void AddDependencies(ProjectDependenciesFacade dependencies, CompilerIO compilerIO) { // add dependency sources that need compilation compilerIO.Inputs.AddRange(dependencies.ProjectDependenciesWithSources.Values.SelectMany(p => p.Project.Files.SourceFiles)); // non project dependencies get captured by changes in the lock file }
// computes all the inputs and outputs that would be used in the compilation of a project // ensures that all paths are files // ensures no missing inputs public static CompilerIO GetCompileIO(ProjectContext project, string config, string outputPath, string intermediaryOutputPath, ProjectDependenciesFacade dependencies) { var compilerIO = new CompilerIO(new List<string>(), new List<string>()); var compilationOutput = CompilerUtil.GetCompilationOutput(project.ProjectFile, project.TargetFramework, config, outputPath); // input: project.json compilerIO.Inputs.Add(project.ProjectFile.ProjectFilePath); // input: lock file; find when dependencies change AddLockFile(project, compilerIO); // input: source files compilerIO.Inputs.AddRange(CompilerUtil.GetCompilationSources(project)); // todo: Factor out dependency resolution between Build and Compile. Ideally Build injects the dependencies into Compile // input: dependencies AddDependencies(dependencies, compilerIO); // output: compiler output compilerIO.Outputs.Add(compilationOutput); // input / output: compilation options files AddFilesFromCompilationOptions(project, config, compilationOutput, compilerIO); // input / output: resources without culture AddCultureResources(project, intermediaryOutputPath, compilerIO); // input / output: resources with culture AddNonCultureResources(project, outputPath, compilerIO); return compilerIO; }
private static void AddDependencies(ProjectDependenciesFacade dependencies, CompilerIO compilerIO) { // add dependency sources that need compilation compilerIO.Inputs.AddRange(dependencies.ProjectDependenciesWithSources.Values.SelectMany(p => p.Project.Files.SourceFiles)); // add compilation binaries compilerIO.Inputs.AddRange(dependencies.Dependencies.SelectMany(d => d.CompilationAssemblies.Select(ca => ca.ResolvedPath))); }
private bool NeedsRebuilding(ProjectContext project, ProjectDependenciesFacade dependencies) { var compilerIO = GetCompileIO(project, dependencies); // rebuild if empty inputs / outputs if (!(compilerIO.Outputs.Any() && compilerIO.Inputs.Any())) { Reporter.Output.WriteLine($"Project {project.GetDisplayName()} will be compiled because it either has empty inputs or outputs"); return(true); } //rebuild if missing inputs / outputs if (AnyMissingIO(project, compilerIO.Outputs, "outputs") || AnyMissingIO(project, compilerIO.Inputs, "inputs")) { return(true); } // find the output with the earliest write time var minOutputPath = compilerIO.Outputs.First(); var minDateUtc = File.GetLastWriteTimeUtc(minOutputPath); foreach (var outputPath in compilerIO.Outputs) { if (File.GetLastWriteTimeUtc(outputPath) >= minDateUtc) { continue; } minDateUtc = File.GetLastWriteTimeUtc(outputPath); minOutputPath = outputPath; } // find inputs that are older than the earliest output var newInputs = compilerIO.Inputs.FindAll(p => File.GetLastWriteTimeUtc(p) >= minDateUtc); if (!newInputs.Any()) { Reporter.Output.WriteLine($"Project {project.GetDisplayName()} was previously compiled. Skipping compilation."); return(false); } Reporter.Output.WriteLine($"Project {project.GetDisplayName()} will be compiled because some of its inputs were newer than its oldest output."); Reporter.Verbose.WriteLine(); Reporter.Verbose.WriteLine($" Oldest output item:"); Reporter.Verbose.WriteLine($" {minDateUtc.ToLocalTime()}: {minOutputPath}"); Reporter.Verbose.WriteLine(); Reporter.Verbose.WriteLine($" Inputs newer than the oldest output item:"); foreach (var newInput in newInputs) { Reporter.Verbose.WriteLine($" {File.GetLastWriteTime(newInput)}: {newInput}"); } Reporter.Verbose.WriteLine(); return(true); }
private bool NeedsRebuilding(ProjectContext project, ProjectDependenciesFacade dependencies) { var compilerIO = GetCompileIO(project, _args.ConfigValue, _args.OutputValue, _args.IntermediateValue, dependencies); // rebuild if empty inputs / outputs if (!(compilerIO.Outputs.Any() && compilerIO.Inputs.Any())) { Reporter.Verbose.WriteLine($"\nProject {project.ProjectName()} will be compiled because it either has empty inputs or outputs"); return(true); } //rebuild if missing inputs / outputs if (AnyMissingIO(project, compilerIO.Outputs, "outputs") || AnyMissingIO(project, compilerIO.Inputs, "inputs")) { return(true); } // find the output with the earliest write time var minOutputPath = compilerIO.Outputs.First(); var minDate = File.GetLastWriteTime(minOutputPath); foreach (var outputPath in compilerIO.Outputs) { if (File.GetLastWriteTime(outputPath) >= minDate) { continue; } minDate = File.GetLastWriteTime(outputPath); minOutputPath = outputPath; } // find inputs that are older than the earliest output var newInputs = compilerIO.Inputs.FindAll(p => File.GetLastWriteTime(p) > minDate); if (!newInputs.Any()) { Reporter.Verbose.WriteLine($"\nSkipped compilation for project {project.ProjectName()}. All the input files were older than the output files."); return(false); } Reporter.Verbose.WriteLine($"\nProject {project.ProjectName()} was compiled because some of its inputs were newer than its oldest output:"); Reporter.Verbose.WriteLine($"Oldest output item was written at {minDate} : {minOutputPath}"); Reporter.Verbose.WriteLine($"Inputs newer than the oldest output item:"); foreach (var newInput in newInputs) { Reporter.Verbose.WriteLine($"\t{File.GetLastWriteTime(newInput)}\t:\t{newInput}"); } return(true); }
// computes all the inputs and outputs that would be used in the compilation of a project // ensures that all paths are files // ensures no missing inputs public CompilerIO GetCompileIO(ProjectContext project, ProjectDependenciesFacade dependencies) { var buildConfiguration = _args.ConfigValue; var buildBasePath = _args.BuildBasePathValue; var outputPath = _args.OutputValue; var isRootProject = project == _rootProject; var compilerIO = new CompilerIO(new List <string>(), new List <string>()); var calculator = project.GetOutputPaths(buildConfiguration, buildBasePath, outputPath); var binariesOutputPath = calculator.CompilationOutputPath; // input: project.json compilerIO.Inputs.Add(project.ProjectFile.ProjectFilePath); // input: lock file; find when dependencies change AddLockFile(project, compilerIO); // input: source files compilerIO.Inputs.AddRange(CompilerUtil.GetCompilationSources(project)); // todo: Factor out dependency resolution between Build and Compile. Ideally Build injects the dependencies into Compile // input: dependencies AddDependencies(dependencies, compilerIO); var allOutputPath = new HashSet <string>(calculator.CompilationFiles.All()); if (isRootProject && project.ProjectFile.HasRuntimeOutput(buildConfiguration)) { var runtimeContext = project.CreateRuntimeContext(_args.GetRuntimes()); foreach (var path in runtimeContext.GetOutputPaths(buildConfiguration, buildBasePath, outputPath).RuntimeFiles.All()) { allOutputPath.Add(path); } } // output: compiler outputs foreach (var path in allOutputPath) { compilerIO.Outputs.Add(path); } // input compilation options files AddCompilationOptions(project, buildConfiguration, compilerIO); // input / output: resources with culture AddNonCultureResources(project, calculator.IntermediateOutputDirectoryPath, compilerIO); // input / output: resources without culture AddCultureResources(project, binariesOutputPath, compilerIO); return(compilerIO); }
public CompileContext(ProjectContext rootProject, BuilderCommandApp args) { _rootProject = rootProject; // Cleaner to clone the args and mutate the clone than have separate CompileContext fields for mutated args // and then reasoning which ones to get from args and which ones from fields. _args = (BuilderCommandApp)args.ShallowCopy(); // Set up dependencies _rootProjectDependencies = new ProjectDependenciesFacade(_rootProject, _args.ConfigValue); // gather preconditions _preconditions = GatherIncrementalPreconditions(); }
// computes all the inputs and outputs that would be used in the compilation of a project // ensures that all paths are files // ensures no missing inputs public CompilerIO GetCompileIO(ProjectContext project, ProjectDependenciesFacade dependencies) { var buildConfiguration = _args.ConfigValue; var buildBasePath = _args.BuildBasePathValue; var outputPath = _args.OutputValue; var isRootProject = project == _rootProject; var compilerIO = new CompilerIO(new List<string>(), new List<string>()); var calculator = project.GetOutputPaths(buildConfiguration, buildBasePath, outputPath); var binariesOutputPath = calculator.CompilationOutputPath; // input: project.json compilerIO.Inputs.Add(project.ProjectFile.ProjectFilePath); // input: lock file; find when dependencies change AddLockFile(project, compilerIO); // input: source files compilerIO.Inputs.AddRange(CompilerUtil.GetCompilationSources(project)); // todo: Factor out dependency resolution between Build and Compile. Ideally Build injects the dependencies into Compile // input: dependencies AddDependencies(dependencies, compilerIO); var allOutputPath = new List<string>(calculator.CompilationFiles.All()); if (isRootProject && project.ProjectFile.HasRuntimeOutput(buildConfiguration)) { var runtimeContext = project.CreateRuntimeContext(_args.GetRuntimes()); allOutputPath.AddRange(runtimeContext.GetOutputPaths(buildConfiguration, buildBasePath, outputPath).RuntimeFiles.All()); } // output: compiler outputs foreach (var path in allOutputPath) { compilerIO.Outputs.Add(path); } // input compilation options files AddCompilationOptions(project, buildConfiguration, compilerIO); // input / output: resources with culture AddNonCultureResources(project, calculator.IntermediateOutputDirectoryPath, compilerIO); // input / output: resources without culture AddCultureResources(project, binariesOutputPath, compilerIO); return compilerIO; }
public CompileContext(ProjectContext rootProject, BuilderCommandApp args) { _rootProject = rootProject; // Cleaner to clone the args and mutate the clone than have separate CompileContext fields for mutated args // and then reasoning which ones to get from args and which ones from fields. _args = (BuilderCommandApp)args.ShallowCopy(); // Set up Output Paths. They are unique per each CompileContext _args.OutputValue = _rootProject.GetOutputPath(_args.ConfigValue, _args.OutputValue); _args.IntermediateValue = _rootProject.GetIntermediateOutputPath(_args.ConfigValue, _args.IntermediateValue, _args.OutputValue); // Set up dependencies _dependencies = new ProjectDependenciesFacade(_rootProject, _args.ConfigValue); // gather preconditions _preconditions = GatherIncrementalPreconditions(); }
public CompileContext(ProjectContext rootProject, BuilderCommandApp args) { _rootProject = rootProject; // Cleaner to clone the args and mutate the clone than have separate CompileContext fields for mutated args // and then reasoning which ones to get from args and which ones from fields. _args = (BuilderCommandApp) args.ShallowCopy(); // Set up Output Paths. They are unique per each CompileContext _args.OutputValue = _rootProject.GetOutputPath(_args.ConfigValue, _args.OutputValue); _args.IntermediateValue = _rootProject.GetIntermediateOutputPath(_args.ConfigValue, _args.IntermediateValue, _args.OutputValue); // Set up dependencies _dependencies = new ProjectDependenciesFacade(_rootProject, _args.ConfigValue); // gather preconditions _preconditions = GatherIncrementalPreconditions(); }
// computes all the inputs and outputs that would be used in the compilation of a project // ensures that all paths are files // ensures no missing inputs public static CompilerIO GetCompileIO( ProjectContext project, string buildConfiguration, string outputPath, string intermediaryOutputPath, ProjectDependenciesFacade dependencies) { var compilerIO = new CompilerIO(new List <string>(), new List <string>()); var calculator = project.GetOutputPathCalculator(outputPath); var binariesOutputPath = calculator.GetOutputDirectoryPath(buildConfiguration); intermediaryOutputPath = calculator.GetIntermediateOutputDirectoryPath(buildConfiguration, intermediaryOutputPath); // input: project.json compilerIO.Inputs.Add(project.ProjectFile.ProjectFilePath); // input: lock file; find when dependencies change AddLockFile(project, compilerIO); // input: source files compilerIO.Inputs.AddRange(CompilerUtil.GetCompilationSources(project)); // todo: Factor out dependency resolution between Build and Compile. Ideally Build injects the dependencies into Compile // input: dependencies AddDependencies(dependencies, compilerIO); // output: compiler outputs foreach (var path in calculator.GetBuildOutputs(buildConfiguration)) { compilerIO.Outputs.Add(path); } // input compilation options files AddCompilationOptions(project, buildConfiguration, compilerIO); // input / output: resources without culture AddCultureResources(project, intermediaryOutputPath, compilerIO); // input / output: resources with culture AddNonCultureResources(project, binariesOutputPath, compilerIO); return(compilerIO); }
// computes all the inputs and outputs that would be used in the compilation of a project // ensures that all paths are files // ensures no missing inputs public static CompilerIO GetCompileIO( ProjectContext project, string buildConfiguration, string outputPath, string intermediaryOutputPath, ProjectDependenciesFacade dependencies) { var compilerIO = new CompilerIO(new List<string>(), new List<string>()); var calculator = project.GetOutputPathCalculator(outputPath); var binariesOutputPath = calculator.GetOutputDirectoryPath(buildConfiguration); // input: project.json compilerIO.Inputs.Add(project.ProjectFile.ProjectFilePath); // input: lock file; find when dependencies change AddLockFile(project, compilerIO); // input: source files compilerIO.Inputs.AddRange(CompilerUtil.GetCompilationSources(project)); // todo: Factor out dependency resolution between Build and Compile. Ideally Build injects the dependencies into Compile // input: dependencies AddDependencies(dependencies, compilerIO); // output: compiler outputs foreach (var path in calculator.GetBuildOutputs(buildConfiguration)) { compilerIO.Outputs.Add(path); } // input compilation options files AddCompilationOptions(project, buildConfiguration, compilerIO); // input / output: resources without culture AddCultureResources(project, intermediaryOutputPath, compilerIO); // input / output: resources with culture AddNonCultureResources(project, binariesOutputPath, compilerIO); return compilerIO; }
private bool NeedsRebuilding(ProjectContext project, ProjectDependenciesFacade dependencies) { return NeedsRebuilding(project, dependencies, _args.OutputValue, _args.IntermediateValue); }
private bool DependencyNeedsRebuilding(ProjectContext project, ProjectDependenciesFacade dependencies) { return NeedsRebuilding(project, dependencies, buildOutputPath: null, intermediateOutputPath: null); }
private bool DependencyNeedsRebuilding(ProjectContext project, ProjectDependenciesFacade dependencies) { return(NeedsRebuilding(project, dependencies, buildOutputPath: null, intermediateOutputPath: null)); }
private bool NeedsRebuilding(ProjectContext project, ProjectDependenciesFacade dependencies) { var compilerIO = GetCompileIO(project, _args.ConfigValue, _args.OutputValue, _args.IntermediateValue, dependencies); // rebuild if empty inputs / outputs if (!(compilerIO.Outputs.Any() && compilerIO.Inputs.Any())) { Reporter.Verbose.WriteLine($"\nProject {project.ProjectName()} will be compiled because it either has empty inputs or outputs"); return true; } //rebuild if missing inputs / outputs if (AnyMissingIO(project, compilerIO.Outputs, "outputs") || AnyMissingIO(project, compilerIO.Inputs, "inputs")) { return true; } // find the output with the earliest write time var minOutputPath = compilerIO.Outputs.First(); var minDate = File.GetLastWriteTime(minOutputPath); foreach (var outputPath in compilerIO.Outputs) { if (File.GetLastWriteTime(outputPath) >= minDate) { continue; } minDate = File.GetLastWriteTime(outputPath); minOutputPath = outputPath; } // find inputs that are older than the earliest output var newInputs = compilerIO.Inputs.FindAll(p => File.GetLastWriteTime(p) > minDate); if (!newInputs.Any()) { Reporter.Verbose.WriteLine($"\nSkipped compilation for project {project.ProjectName()}. All the input files were older than the output files."); return false; } Reporter.Verbose.WriteLine($"\nProject {project.ProjectName()} was compiled because some of its inputs were newer than its oldest output:"); Reporter.Verbose.WriteLine($"Oldest output item was written at {minDate} : {minOutputPath}"); Reporter.Verbose.WriteLine($"Inputs newer than the oldest output item:"); foreach (var newInput in newInputs) { Reporter.Verbose.WriteLine($"\t{File.GetLastWriteTime(newInput)}\t:\t{newInput}"); } return true; }
private bool NeedsRebuilding(ProjectContext project, ProjectDependenciesFacade dependencies, string buildOutputPath, string intermediateOutputPath) { var compilerIO = GetCompileIO(project, _args.ConfigValue, buildOutputPath, intermediateOutputPath, dependencies); // rebuild if empty inputs / outputs if (!(compilerIO.Outputs.Any() && compilerIO.Inputs.Any())) { Reporter.Output.WriteLine($"Project {project.GetDisplayName()} will be compiled because it either has empty inputs or outputs"); return true; } //rebuild if missing inputs / outputs if (AnyMissingIO(project, compilerIO.Outputs, "outputs") || AnyMissingIO(project, compilerIO.Inputs, "inputs")) { return true; } // find the output with the earliest write time var minOutputPath = compilerIO.Outputs.First(); var minDateUtc = File.GetLastWriteTimeUtc(minOutputPath); foreach (var outputPath in compilerIO.Outputs) { if (File.GetLastWriteTimeUtc(outputPath) >= minDateUtc) { continue; } minDateUtc = File.GetLastWriteTimeUtc(outputPath); minOutputPath = outputPath; } // find inputs that are older than the earliest output var newInputs = compilerIO.Inputs.FindAll(p => File.GetLastWriteTimeUtc(p) > minDateUtc); if (!newInputs.Any()) { Reporter.Output.WriteLine($"Project {project.GetDisplayName()} was previously compiled. Skipping compilation."); return false; } Reporter.Output.WriteLine($"Project {project.GetDisplayName()} will be compiled because some of its inputs were newer than its oldest output."); Reporter.Verbose.WriteLine(); Reporter.Verbose.WriteLine($" Oldest output item:"); Reporter.Verbose.WriteLine($" {minDateUtc.ToLocalTime()}: {minOutputPath}"); Reporter.Verbose.WriteLine(); Reporter.Verbose.WriteLine($" Inputs newer than the oldest output item:"); foreach (var newInput in newInputs) { Reporter.Verbose.WriteLine($" {File.GetLastWriteTime(newInput)}: {newInput}"); } Reporter.Verbose.WriteLine(); return true; }
// computes all the inputs and outputs that would be used in the compilation of a project // ensures that all paths are files // ensures no missing inputs public static CompilerIO GetCompileIO(ProjectContext project, string config, string outputPath, string intermediaryOutputPath, ProjectDependenciesFacade dependencies) { var compilerIO = new CompilerIO(new List <string>(), new List <string>()); // input: project.json compilerIO.Inputs.Add(project.ProjectFile.ProjectFilePath); // input: source files compilerIO.Inputs.AddRange(CompilerUtil.GetCompilationSources(project)); // todo: Factor out dependency resolution between Build and Compile. Ideally Build injects the dependencies into Compile // todo: use lock file insteaf of dependencies. One file vs many // input: dependencies AddDependencies(dependencies, compilerIO); // input: key file AddKeyFile(project, config, compilerIO); // output: compiler output compilerIO.Outputs.Add(CompilerUtil.GetCompilationOutput(project.ProjectFile, project.TargetFramework, config, outputPath)); // input / output: resources without culture AddCultureResources(project, intermediaryOutputPath, compilerIO); // input / output: resources with culture AddNonCultureResources(project, outputPath, compilerIO); return(compilerIO); }
private bool NeedsRebuilding(ProjectContext project, ProjectDependenciesFacade dependencies) { return(NeedsRebuilding(project, dependencies, _args.OutputValue, _args.IntermediateValue)); }