void applyDiffToFile(string deltaPath, string relativeFilePath, string workingDirectory) { var inputFile = Path.Combine(deltaPath, relativeFilePath); var finalTarget = Path.Combine(workingDirectory, Regex.Replace(relativeFilePath, @".diff$", "")); var tempTargetFile = Path.GetTempFileName(); // NB: Zero-length diffs indicate the file hasn't actually changed if (new FileInfo(inputFile).Length == 0) { this.Log().Info("{0} exists unchanged, skipping", relativeFilePath); return; } if (relativeFilePath.EndsWith(".diff", StringComparison.InvariantCultureIgnoreCase)) { using (var of = File.OpenWrite(tempTargetFile)) using (var inf = File.OpenRead(finalTarget)) { this.Log().Info("Applying Diff to {0}", relativeFilePath); BinaryPatchUtility.Apply(inf, () => File.OpenRead(inputFile), of); } try { verifyPatchedFile(relativeFilePath, inputFile, tempTargetFile); } catch (Exception) { File.Delete(tempTargetFile); throw; } } else { using (var of = File.OpenWrite(tempTargetFile)) using (var inf = File.OpenRead(inputFile)) { this.Log().Info("Adding new file: {0}", relativeFilePath); inf.CopyTo(of); } } if (File.Exists(finalTarget)) { File.Delete(finalTarget); } var targetPath = Directory.GetParent(finalTarget); if (!targetPath.Exists) { targetPath.Create(); } File.Move(tempTargetFile, finalTarget); }
void createDeltaForSingleFile(FileInfo targetFile, DirectoryInfo workingDirectory, Dictionary <string, string> baseFileListing) { // NB: There are three cases here that we'll handle: // // 1. Exists only in new => leave it alone, we'll use it directly. // 2. Exists in both old and new => write a dummy file so we know // to keep it. // 3. Exists in old but changed in new => create a delta file // // The fourth case of "Exists only in old => delete it in new" // is handled when we apply the delta package var relativePath = targetFile.FullName.Replace(workingDirectory.FullName, ""); if (!baseFileListing.ContainsKey(relativePath)) { this.Log().Info("{0} not found in base package, marking as new", relativePath); return; } var oldData = File.ReadAllBytes(baseFileListing[relativePath]); var newData = File.ReadAllBytes(targetFile.FullName); if (bytesAreIdentical(oldData, newData)) { this.Log().Info("{0} hasn't changed, writing dummy file", relativePath); File.Create(targetFile.FullName + ".diff").Dispose(); File.Create(targetFile.FullName + ".shasum").Dispose(); targetFile.Delete(); return; } this.Log().Info("Delta patching {0} => {1}", baseFileListing[relativePath], targetFile.FullName); using (var of = File.Create(targetFile.FullName + ".diff")) { BinaryPatchUtility.Create(oldData, newData, of); var rl = ReleaseEntry.GenerateFromFile(new MemoryStream(newData), targetFile.Name + ".shasum"); File.WriteAllText(targetFile.FullName + ".shasum", rl.EntryAsString, Encoding.UTF8); targetFile.Delete(); } }