/// <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> /// 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) { MemoryCacheItem item = GetOrCreate(builder); var map = new ConcurrentDictionary <TargetRelativePath, byte[]>(); Parallel.ForEach(outputs, outputPath => { if (targetRoot.Exists(outputPath)) { using (var stream = targetRoot.ReadBinaryFile(outputPath)) { var buf = new byte[stream.Length]; stream.Read(buf, 0, buf.Length); map.TryAdd(outputPath, buf); } } else { map.TryAdd(outputPath, null); } }); item.Update(fingerprint, map); }
/// <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 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) { byte[] sourceChecksum = ComputeChecksum(sourceDirectory, sourceFileName); byte[] targetChecksum = ComputeChecksum(targetRoot, targetRelativePath); copy = !sourceChecksum.SequenceEqual(targetChecksum); } } if (copy) { using (var source = sourceDirectory.ReadBinaryFile(sourceFileName)) using (var target = targetRoot.CreateBinaryFileWithDirectories(targetRelativePath)) StreamOperations.Copy(source, target); } else { log.DebugFormat("File {0} is the same as the cached one", targetRelativePath); } }
/// <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) { MemoryCacheItem item = GetOrCreate(builder); var map = new ConcurrentDictionary<TargetRelativePath, byte[]>(); Parallel.ForEach(outputs, outputPath => { if (targetRoot.Exists(outputPath)) { using (var stream = targetRoot.ReadBinaryFile(outputPath)) { var buf = new byte[stream.Length]; stream.Read(buf, 0, buf.Length); map.TryAdd(outputPath, buf); } } else { map.TryAdd(outputPath, null); } }); item.Update(fingerprint, map); }
/// <summary> /// Checks if the repository contains a valid file in the given path /// </summary> /// <param name="path">Path to the file</param> /// <returns>Returns <c>true</c> if the file exists.</returns> public bool Exists(string path) { if (Path.GetFileName(path) == "*.*") { return(Exists(Path.GetDirectoryName(path))); } else { if (Path.IsPathRooted(path)) { return(File.Exists(path) || Directory.Exists(path)); } else { return(suiteRoot.Exists(path)); } } }
private void InitializeFromCache() { if (cacheRoot.Exists("guids")) { using (var reader = cacheRoot.ReadTextFile("guids")) { string line = reader.ReadLine(); while (line != null) { string[] parts = line.Split('='); var project = FindProject(parts[0]); if (project != null) { map.Add(project, Guid.Parse(parts[1])); } line = reader.ReadLine(); } } } }
/// <summary> /// Copy a file to a target directory /// </summary> /// <param name="name">Name of the file</param> /// <param name="target">Target file system directory</param> /// <param name="targetName">Name (relative path) in the target directory</param> public void CopyFile(string name, IFileSystemDirectory target, string targetName) { var localTarget = target as LocalFileSystemDirectory; if (localTarget != null) { var targetSubdir = Path.GetDirectoryName(targetName); if (!String.IsNullOrWhiteSpace(targetSubdir)) { var absoluteTargetDir = Path.Combine(localTarget.AbsolutePath, targetSubdir); if (!Directory.Exists(absoluteTargetDir)) { Directory.CreateDirectory(absoluteTargetDir); } } var copy = true; if (target.Exists(targetName)) { var sourceSize = GetFileSize(name); var targetSize = target.GetFileSize(targetName); var sourceDate = GetLastModifiedDate(name); var targetDate = target.GetLastModifiedDate(targetName); copy = sourceSize != targetSize || !sourceDate.Equals(targetDate); } if (copy) { File.Copy(Path.Combine(path, name), Path.Combine(localTarget.AbsolutePath, targetName), overwrite: true); } } else { using (var sourceStream = ReadBinaryFile(name)) using (var targetStream = target.CreateBinaryFileWithDirectories(targetName)) StreamOperations.Copy(sourceStream, targetStream); } }
private TargetRelativePath GenerateAddonSupportFile(string solutionName) { string contents = AddonSupportData(); var path = new TargetRelativePath("", solutionName + ".yaml"); bool writeFile = true; if (targetRoot.Exists(path.RelativePath)) { using (var reader = targetRoot.ReadTextFile(path.RelativePath)) { string existingContents = reader.ReadToEnd(); writeFile = existingContents != contents; } } if (writeFile) { using (var writer = targetRoot.CreateTextFile(path.RelativePath)) writer.WriteLine(contents); } return(path); }
/// <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; } } } }