示例#1
0
        /// <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))
                        {
                            using (var source = targetRoot.ReadBinaryFile(outputPath))
                                using (var target = cacheDir.CreateBinaryFile(idx.ToString(CultureInfo.InvariantCulture)))
                                {
                                    StreamOperations.Copy(source, target);
                                }
                        }

                        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;
                        }
                    }
                }
            }
        }
示例#2
0
        /// <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);
        }
示例#3
0
        /// <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);
            }
        }
示例#4
0
        /// <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);
        }
示例#5
0
 private byte[] ComputeChecksum(HashAlgorithm hash, IFileSystemDirectory root, string path)
 {
     using (var stream = root.ReadBinaryFile(path))
         using (var bufferedStream = new BufferedStream(stream, 1048576))
         {
             return(hash.ComputeHash(bufferedStream));
         }
 }
示例#6
0
 private byte[] ComputeChecksum(IFileSystemDirectory root, string path)
 {
     using (var stream = root.ReadBinaryFile(path))
         using (var bufferedStream = new BufferedStream(stream, 1048576))
             using (var md5 = MD5.Create())
             {
                 return(md5.ComputeHash(bufferedStream));
             }
 }
示例#7
0
        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);
        }
示例#8
0
        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);
                }
            }
        }
示例#9
0
 private void Copy(TargetRelativePath sourcePath, string relativePath)
 {
     using (var source = targetRoot.ReadBinaryFile(sourcePath))
         using (var target = targetDirectory.CreateBinaryFileWithDirectories(relativePath))
             StreamOperations.Copy(source, target);
 }
示例#10
0
 private byte[] ComputeChecksum(HashAlgorithm hash, IFileSystemDirectory root, string path)
 {
     using (var stream = root.ReadBinaryFile(path))
     using (var bufferedStream = new BufferedStream(stream, 1048576))
     {
         return hash.ComputeHash(bufferedStream);
     }
 }
示例#11
0
        /// <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))
                        {
                            using (var source = targetRoot.ReadBinaryFile(outputPath))
                            using (var target = cacheDir.CreateBinaryFile(idx.ToString(CultureInfo.InvariantCulture)))
                            {
                                StreamOperations.Copy(source, target);
                            }
                        }

                        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;
                    }
                }
            }
        }
示例#12
0
 private byte[] ComputeChecksum(IFileSystemDirectory root, string path)
 {
     using (var stream = root.ReadBinaryFile(path))
     using (var bufferedStream = new BufferedStream(stream, 1048576))
     using (var md5 = MD5.Create())
     {
         return md5.ComputeHash(bufferedStream);
     }
 }
示例#13
0
        /// <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);
            }
        }