/// <summary> /// Copies a source file to a target location, but only if it does not exist yet, with the same MD5 checksum /// as the source /// </summary> /// <param name="sourceDirectory">Source root directory</param> /// <param name="sourceFileName">Source file's relative path</param> /// <param name="targetRoot">Target root directory</param> /// <param name="targetRelativePath">Target file's relative path</param> private void CopyIfDifferent(IFileSystemDirectory sourceDirectory, string sourceFileName, IFileSystemDirectory targetRoot, string targetRelativePath) { bool copy = true; long sourceSize = sourceDirectory.GetFileSize(sourceFileName); if (targetRoot.Exists(targetRelativePath)) { long targetSize = targetRoot.GetFileSize(targetRelativePath); if (sourceSize == targetSize) { var sourceChecksum = Task.Factory.StartNew(() => ComputeChecksum(md5a, sourceDirectory, sourceFileName)); var targetChecksum = Task.Factory.StartNew(() => ComputeChecksum(md5b, targetRoot, targetRelativePath)); copy = !sourceChecksum.Result.SequenceEqual(targetChecksum.Result); } } if (copy) { sourceDirectory.CopyFile(sourceFileName, targetRoot, targetRelativePath); } else { log.DebugFormat("File {0} is the same as the cached one", targetRelativePath); } }
/// <summary> /// Copies output files to the cache directory, and also saves a '.names' file referring to he original target relative /// paths of these files. /// </summary> /// <param name="outputs">Build outputs to be copied</param> /// <param name="targetRoot">Root directory for the build outputs</param> /// <param name="cacheDir">Target directory for the copy operation</param> private void SaveOutputs(IEnumerable <TargetRelativePath> outputs, IFileSystemDirectory targetRoot, IFileSystemDirectory cacheDir) { using (var names = cacheDir.CreateTextFile(NamesFileName)) { int idx = 0; foreach (var outputPath in outputs) { try { // It is possible that the returned path is a special path and does not refer to an existing file // In this case we only have to save the filename, without its contents if (targetRoot.Exists(outputPath)) { targetRoot.CopyFile(outputPath, cacheDir, idx.ToString(CultureInfo.InvariantCulture)); } names.WriteLine("{0};{1}", outputPath.RelativeRoot, outputPath.RelativePath); idx++; } catch (IOException ex) { log.WarnFormat("IOException while reading {0}: {1}", outputPath, ex.Message); if (!outputPath.RelativePath.ToLowerInvariant().EndsWith(".vshost.exe")) { throw; } } } } }
/// <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> /// 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 files = context.GetResults(sourceBuilder); var result = new HashSet <TargetRelativePath>(); var relativeTargetDirectory = targetRoot.GetRelativePath(targetDirectory); foreach (var sourcePath in files) { log.DebugFormat("Copying result {0}...", sourcePath); var relativePath = sourcePath.RelativePath; targetRoot.CopyFile(sourcePath, targetDirectory, relativePath); result.Add(new TargetRelativePath(relativeTargetDirectory, relativePath)); } return(result); }
/// <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> /// Copies output files to the cache directory, and also saves a '.names' file referring to he original target relative /// paths of these files. /// </summary> /// <param name="outputs">Build outputs to be copied</param> /// <param name="targetRoot">Root directory for the build outputs</param> /// <param name="cacheDir">Target directory for the copy operation</param> private void SaveOutputs(IEnumerable<TargetRelativePath> outputs, IFileSystemDirectory targetRoot, IFileSystemDirectory cacheDir) { using (var names = cacheDir.CreateTextFile(NamesFileName)) { int idx = 0; foreach (var outputPath in outputs) { try { // It is possible that the returned path is a special path and does not refer to an existing file // In this case we only have to save the filename, without its contents if (targetRoot.Exists(outputPath)) { targetRoot.CopyFile(outputPath, cacheDir, idx.ToString(CultureInfo.InvariantCulture)); } names.WriteLine("{0};{1}", outputPath.RelativeRoot, outputPath.RelativePath); idx++; } catch (IOException ex) { log.WarnFormat("IOException while reading {0}: {1}", outputPath, ex.Message); if (!outputPath.RelativePath.ToLowerInvariant().EndsWith(".vshost.exe")) throw; } } } }
/// <summary> /// Copies a source file to a target location, but only if it does not exist yet, with the same MD5 checksum /// as the source /// </summary> /// <param name="sourceDirectory">Source root directory</param> /// <param name="sourceFileName">Source file's relative path</param> /// <param name="targetRoot">Target root directory</param> /// <param name="targetRelativePath">Target file's relative path</param> private void CopyIfDifferent(IFileSystemDirectory sourceDirectory, string sourceFileName, IFileSystemDirectory targetRoot, string targetRelativePath) { bool copy = true; long sourceSize = sourceDirectory.GetFileSize(sourceFileName); if (targetRoot.Exists(targetRelativePath)) { long targetSize = targetRoot.GetFileSize(targetRelativePath); if (sourceSize == targetSize) { var sourceChecksum = Task.Factory.StartNew(() => ComputeChecksum(md5a, sourceDirectory, sourceFileName)); var targetChecksum = Task.Factory.StartNew(() => ComputeChecksum(md5b, targetRoot, targetRelativePath)); copy = !sourceChecksum.Result.SequenceEqual(targetChecksum.Result); } } if (copy) { sourceDirectory.CopyFile(sourceFileName, targetRoot, targetRelativePath); } else { log.DebugFormat("File {0} is the same as the cached one", targetRelativePath); } }