public void AddingFileToSubdirectoryChangesFingerprint() { var dep = new SourceSetDependencies(fingerprintFactory, sourceSet); var fp1 = dep.CreateFingerprint(); Directory.CreateDirectory(Path.Combine(tmp, "subdir")); using (var writer = rootDir.GetChildDirectory("subdir").CreateTextFile("file3")) writer.WriteLine("Contents of file 3"); sourceSet.Add(new SuiteRelativePath("subdir\\file3")); var fp2 = dep.CreateFingerprint(); fp1.Should().NotBe(fp2); }
/// <summary> /// Performs the additional cleaning step /// </summary> /// <param name="parameters"></param> public void Clean(ICleanParameters parameters) { if (parameters.KeepReferences) { var persistentReferenceBuilders = builderEnumerator.GetAllPersistentBuilders().ToList(); var persistentBuilderPrefixes = persistentReferenceBuilders.Select(b => b.FullName + "_").ToList(); foreach (var directory in cacheDir.ChildDirectories) { foreach (var prefix in persistentBuilderPrefixes) { if (!directory.StartsWith(prefix)) { cacheDir.GetChildDirectory(directory).Delete(); break; } else { log.InfoFormat("Keeping {0} because keep-references option is active", directory); } } } if (!cacheDir.ChildDirectories.Any()) { cacheDir.Delete(); } } else { cacheDir.Delete(); } }
private IBuilder CreateRuntimeReferenceDeployment(IBuildContext context, Project project, IReferenceBuilder refBuilder) { var copy = new CopyResultBuilder(refBuilder, targetRoot, targetRoot.GetChildDirectory(project.Module.Name, createIfMissing: true)); context.AddBuilder(copy, new[] { refBuilder }); return(copy); }
/// <summary> /// Extends suite model with discovered information based on bari conventions /// </summary> /// <param name="suite">The suite model to be extended with discoveries</param> public void ExtendWithDiscoveries(Suite suite) { var srcDir = suiteRoot.GetChildDirectory("src"); srcDir.With(s => s.ChildDirectories.Do( moduleName => { Module module = suite.GetModule(moduleName); var moduleDir = srcDir.GetChildDirectory(moduleName); foreach (var projectName in moduleDir.ChildDirectories) { if (projectName.Equals("tests", StringComparison.InvariantCultureIgnoreCase)) { // This is the special subdirectory for test projects var testsDir = moduleDir.GetChildDirectory(projectName); foreach (var testProjectName in testsDir.ChildDirectories) { var testProject = module.GetTestProject(testProjectName); DiscoverProjectSources(testProject, testsDir.GetChildDirectory(testProjectName)); } } else { // This is a project directory Project project = module.GetProject(projectName); DiscoverProjectSources(project, moduleDir.GetChildDirectory(projectName)); } } })); }
/// <summary> /// Runs this builder /// </summary> /// <param name="context">Current build context</param> /// <exception cref="TooManyAppConfigsException"></exception> /// <returns>Returns a set of generated files, in target relative paths</returns> public override ISet <TargetRelativePath> Run(IBuildContext context) { if (project.HasNonEmptySourceSet(appConfigSourceSetName)) { var configs = project.GetSourceSet("appconfig"); if (configs.Files.Count() > 1) { throw new TooManyAppConfigsException(project); } if (project.Type != ProjectType.Executable) { throw new InvalidSpecificationException(string.Format("Invalid project type ({0}) for {1}.{2} or unecessary application config file ({3})!", project.Type, project.Module.Name, project.Name, ToString())); } var configFile = configs.Files.FirstOrDefault(); log.DebugFormat("Copying config {0}...", configFile); var targetDir = targetRoot.GetChildDirectory(project.RelativeTargetPath, createIfMissing: true); var relativePath = project.Name + ".exe.config"; suiteRoot.CopyFile(configFile, targetDir, relativePath); return(new HashSet <TargetRelativePath> { new TargetRelativePath(project.RelativeTargetPath, relativePath) }); } else { return(new HashSet <TargetRelativePath>()); } }
/// <summary> /// Goes through all the subdirectories of a project and interprets them as source sets /// </summary> /// <param name="project">The project to be extended with source sets</param> /// <param name="projectDir">The project's directory</param> /// <param name="ignoreLists">The suite's source set ignore lists</param> private void DiscoverProjectSources(Project project, IFileSystemDirectory projectDir, SourceSetIgnoreLists ignoreLists) { foreach (var sourceSetName in projectDir.ChildDirectories) { var sourceSet = project.GetSourceSet(sourceSetName); AddAllFiles(sourceSet, projectDir.GetChildDirectory(sourceSetName), ignoreLists.Get(new SourceSetType(sourceSetName))); } }
/// <summary> /// Goes through all the subdirectories of a project and interprets them as source sets /// </summary> /// <param name="project">The project to be extended with source sets</param> /// <param name="projectDir">The project's directory</param> private void DiscoverProjectSources(Project project, IFileSystemDirectory projectDir) { foreach (var sourceSetName in projectDir.ChildDirectories) { var sourceSet = project.GetSourceSet(sourceSetName); AddAllFiles(sourceSet, projectDir.GetChildDirectory(sourceSetName)); } }
private ISet <TargetRelativePath> GetProductOutputs(Product product) { var root = targetRoot.GetChildDirectory(product.Name); var result = new HashSet <TargetRelativePath>(); CollectOutput(root, product.Name, root, result); return(result); }
/// <summary> /// Store build outputs in the cache by reading them from the file system /// </summary> /// <param name="builder">Builder key (first part of the key)</param> /// <param name="fingerprint">Dependency fingerprint created when the builder was executed (second part of the key)</param> /// <param name="outputs">Target-relative path of the build outputs to be cached</param> /// <param name="targetRoot">File system abstraction of the root target directory</param> public void Store(BuildKey builder, IDependencyFingerprint fingerprint, IEnumerable <TargetRelativePath> outputs, IFileSystemDirectory targetRoot) { var lck = GetOrCreateLock(builder); lck.EnterWriteLock(); try { var cacheDir = cacheRoot.GetChildDirectory(GetCacheDirectoryName(builder), createIfMissing: true); SaveDependencyFingerprint(fingerprint, cacheDir); SaveOutputs(outputs, targetRoot, cacheDir); } finally { lck.ExitWriteLock(); } }
private void CollectOutput(IFileSystemDirectory productRoot, string productName, IFileSystemDirectory dir, HashSet <TargetRelativePath> result) { foreach (var file in dir.Files) { result.Add(new TargetRelativePath(productName, Path.Combine(productRoot.GetRelativePath(dir), file))); } foreach (var childDir in dir.ChildDirectories) { CollectOutput(productRoot, productName, dir.GetChildDirectory(childDir), result); } }
/// <summary> /// Recursively adds every file in a given directory to a source set (<see cref="SourceSet"/>) /// </summary> /// <param name="target">The target source set to be extended</param> /// <param name="dir">The root directory for the operation</param> private void AddAllFiles(SourceSet target, IFileSystemDirectory dir) { foreach (var fileName in dir.Files) { target.Add(new SuiteRelativePath(Path.Combine(suiteRoot.GetRelativePath(dir), fileName))); } foreach (var childDirectory in dir.ChildDirectories) { AddAllFiles(target, dir.GetChildDirectory(childDirectory)); } }
/// <summary> /// Gets the directory for a given path (the path's file name part is not used) /// </summary> /// <param name="path">Path to the file</param> /// <returns>Returns an abstract directory interface</returns> public IFileSystemDirectory GetDirectory(string path) { var dir = Path.GetDirectoryName(path); if (Path.IsPathRooted(path)) { return(new LocalFileSystemDirectory(dir)); } else { return(suiteRoot.GetChildDirectory(dir)); } }
private void Copy(SuiteRelativePath sourcePath, string relativePath) { var relativeDir = Path.GetDirectoryName(relativePath); var fileName = Path.GetFileName(relativePath); var targetDir = targetRoot.GetChildDirectory(project.Module.Name, createIfMissing: true); IFileSystemDirectory realTargetDir = String.IsNullOrWhiteSpace(relativeDir) ? targetDir : targetDir.GetChildDirectory(relativeDir, createIfMissing: true); using (var source = suiteRoot.ReadBinaryFile(sourcePath)) using (var target = realTargetDir.CreateBinaryFile(fileName)) StreamOperations.Copy(source, target); }
/// <summary> /// Recursively adds every file in a given directory to a source set (<see cref="SourceSet"/>) /// </summary> /// <param name="target">The target source set to be extended</param> /// <param name="dir">The root directory for the operation</param> /// <param name="ignoreList">Ignore list for the target source set</param> private void AddAllFiles(SourceSet target, IFileSystemDirectory dir, SourceSetIgnoreList ignoreList) { foreach (var fileName in dir.Files) { var suiteRelativePath = new SuiteRelativePath(Path.Combine(suiteRoot.GetRelativePath(dir), fileName)); if (!ignoreList.IsIgnored(suiteRelativePath)) { target.Add(suiteRelativePath); } } foreach (var childDirectory in dir.ChildDirectories) { AddAllFiles(target, dir.GetChildDirectory(childDirectory), ignoreList); } }
private void MergeOutputForProduct(Product product, ISet <TargetRelativePath> outputs) { log.InfoFormat("Merging {0} files to product output directory {1}...", outputs.Count, new TargetRelativePath(product.Name, String.Empty)); var productOutput = targetRoot.GetChildDirectory(product.Name, createIfMissing: true); foreach (var sourcePath in outputs) { if (sourcePath.RelativeRoot != product.Name) // Postprocessors can generate output to product output directory directly { using (var source = targetRoot.ReadBinaryFile(sourcePath)) using (var target = productOutput.CreateBinaryFileWithDirectories(sourcePath.RelativePath)) StreamOperations.Copy(source, target); } } }
/// <summary> /// Creates a binary file in the given directory, or in a subdirectory of it. /// If the subdirectory does not exist, it will be created. /// </summary> /// <param name="root">The root directory</param> /// <param name="relativePath">Relative path of the file to be created</param> /// <returns>Returns the stream for writing the binary file.</returns> public static Stream CreateBinaryFileWithDirectories(this IFileSystemDirectory root, string relativePath) { Contract.Requires(root != null); Contract.Requires(!String.IsNullOrWhiteSpace(relativePath)); string dirName = Path.GetDirectoryName(relativePath); if (!String.IsNullOrWhiteSpace(dirName)) { var subdir = root.GetChildDirectory(dirName, createIfMissing: true); return(subdir.CreateBinaryFile(Path.GetFileName(relativePath))); } else { return(root.CreateBinaryFile(relativePath)); } }
/// <summary> /// Runs this builder /// </summary> /// <param name="context">Current build context</param> /// <returns>Returns a set of generated files, in target relative paths</returns> public override ISet <TargetRelativePath> Run(IBuildContext context) { var contents = project.GetSourceSet("content"); var contentsDir = project.RootDirectory.GetChildDirectory("content"); var targetDir = targetRoot.GetChildDirectory(project.RelativeTargetPath, createIfMissing: true); var result = new HashSet <TargetRelativePath>(); foreach (var sourcePath in contents.Files) { log.DebugFormat("Copying content {0}...", sourcePath); var relativePath = suiteRoot.GetRelativePathFrom(contentsDir, sourcePath); suiteRoot.CopyFile(sourcePath, targetDir, relativePath); result.Add(new TargetRelativePath(project.RelativeTargetPath, relativePath)); } return(result); }
/// <summary> /// Runs this builder /// </summary> /// <param name="context"> </param> /// <returns>Returns a set of generated files, in target relative paths</returns> public ISet <TargetRelativePath> Run(IBuildContext context) { msbuild.Run(targetRoot, slnPath); // Collecting all the files in 'targetdir/modulename' directories as results var modules = new HashSet <Module>(from proj in slnBuilder.Projects select proj.Module); var outputs = new HashSet <TargetRelativePath>(); foreach (var module in modules) { var moduleTargetDir = targetRoot.GetChildDirectory(module.Name); if (moduleTargetDir != null) { foreach (var fileName in moduleTargetDir.Files) { outputs.Add(new TargetRelativePath(module.Name, fileName)); } } } return(outputs); }
/// <summary> /// Gets a child directory and optionally creates it if missing /// </summary> /// <param name="root">The root directory</param> /// <param name="childName">The name of the direct child directory</param> /// <param name="createIfMissing">If <c>true</c>, the child directory will be created if does not exist</param> /// <exception cref="ArgumentException">Thrown if the child directory does not exist and <c>createIfMissing</c> parameter is false</exception> /// <returns>Returns the file system abstraction of the child directory</returns> public static IFileSystemDirectory GetChildDirectory(this IFileSystemDirectory root, string childName, bool createIfMissing) { Contract.Requires(root != null); Contract.Requires(!String.IsNullOrWhiteSpace(childName)); Contract.Ensures(Contract.Result <IFileSystemDirectory>() != null); if (root.ChildDirectories.Any(name => name.Equals(childName, StringComparison.InvariantCultureIgnoreCase))) { return(root.GetChildDirectory(childName)); } else { if (createIfMissing) { return(root.CreateDirectory(childName)); } else { throw new ArgumentException("The argument is not a child directory of this directory", "childName"); } } }
private IBuilder AddProductBuildStep(IBuildContext context, Product product, IBuilder rootBuilder) { var productOutput = targetRoot.GetChildDirectory(product.Name, createIfMissing: true); var copyResultsStep = coreBuilderFactory.CreateCopyResultBuilder(rootBuilder, productOutput); context.AddBuilder(copyResultsStep); var resultBuilders = new List <IPostProcessor>(); if (product.PostProcessors.Any()) { var factories = postProcessorFactories.ToList(); foreach (var pp in product.PostProcessors) { var postProcessor = factories .Select(f => f.CreatePostProcessorFor(product, pp, new[] { copyResultsStep })) .FirstOrDefault(p => p != null); if (postProcessor != null) { resultBuilders.Add(postProcessor); } } } if (resultBuilders.Any()) { var merger = coreBuilderFactory.CreateMergingBuilder(resultBuilders, new DescriptionTag(String.Format("Product {0}'s result builders", product.Name))); context.AddBuilder(merger); return(merger); } else { return(copyResultsStep); } }
/// <summary> /// Runs this builder /// </summary> /// <param name="context"> </param> /// <returns>Returns a set of generated files, in target relative paths</returns> public override ISet <TargetRelativePath> Run(IBuildContext context) { // Collecting all the files already existing in 'targetdir/modulename' directories var targetDirs = new HashSet <string>(slnBuilder.Projects.Select(GetTargetDir)); var existingFiles = new Dictionary <TargetRelativePath, DateTime>(); var expectedOutputs = new HashSet <TargetRelativePath>(slnBuilder.Projects.SelectMany(GetExpectedProjectOutputs).Union(GetDependencyResults(context))); foreach (var targetDir in targetDirs) { var moduleTargetDir = targetRoot.GetChildDirectory(targetDir); if (moduleTargetDir != null) { foreach (var fileName in moduleTargetDir.Files) { existingFiles.Add(new TargetRelativePath(targetDir, fileName), moduleTargetDir.GetLastModifiedDate(fileName)); } } } msbuild.Run(targetRoot, slnPath); // Collecting all the files in 'targetdir/modulename' directories as results var outputs = new HashSet <TargetRelativePath>(); foreach (var targetDir in targetDirs) { var moduleTargetDir = targetRoot.GetChildDirectory(targetDir); if (moduleTargetDir != null) { moduleTargetDir.InvalidateCacheFileData(); foreach (var fileName in moduleTargetDir.Files) { var relativePath = new TargetRelativePath(targetDir, fileName); var lastModified = moduleTargetDir.GetLastModifiedDate(fileName); bool isNew = false; if (expectedOutputs.Contains(relativePath)) { isNew = true; } else { DateTime previousLastModified; if (existingFiles.TryGetValue(relativePath, out previousLastModified)) { if (lastModified != previousLastModified) { isNew = true; } } else { isNew = true; } } if (isNew) { outputs.Add(relativePath); } } } } foreach (var targetDir in targetDirs) { outputs.ExceptWith(context.GetAllResultsIn(new TargetRelativePath(targetDir, String.Empty))); } return(outputs); }
private void CollectOutput(IFileSystemDirectory productRoot, string productName, IFileSystemDirectory dir, HashSet<TargetRelativePath> result) { foreach (var file in dir.Files) { result.Add(new TargetRelativePath(productName, Path.Combine(productRoot.GetRelativePath(dir), file))); } foreach (var childDir in dir.ChildDirectories) CollectOutput(productRoot, productName, dir.GetChildDirectory(childDir), result); }
private IBuilder CreateRuntimeReferenceDeployment(Project project, IReferenceBuilder refBuilder) { return(coreBuilderFactory.CreateCopyResultBuilder(refBuilder, targetRoot.GetChildDirectory(project.RelativeTargetPath, createIfMissing: true))); }