public FolderVersionEntry CreateDiff(Dictionary <string, string> tagPathToHashMap, Dictionary <string, string> actualPathToHashMap) { FolderVersionEntry folderVersion = new FolderVersionEntry(); List <string> addedPaths = actualPathToHashMap.Keys.Except(tagPathToHashMap.Keys).ToList(); List <string> removedPaths = tagPathToHashMap.Keys.Except(actualPathToHashMap.Keys).ToList(); List <string> changedPaths = actualPathToHashMap.Keys.Except(addedPaths).ToList(); foreach (string path in removedPaths) { folderVersion.AddEntry(path, string.Empty, FileHistoryType.Deleted); } foreach (var path in addedPaths) { folderVersion.AddEntry(path, actualPathToHashMap[path], FileHistoryType.Added); } foreach (var path in changedPaths) { if (actualPathToHashMap[path] != tagPathToHashMap[path]) { folderVersion.AddEntry(path, actualPathToHashMap[path], FileHistoryType.Modified); } } return(folderVersion); }
public FolderVersionEntry CreateDiff(IEnumerable <string> currentFilesList) { FolderVersionEntry[] currentHistory = ReadCurrentHistory(); var lastFilesVersion = new List <FileHistoryEntry>(); foreach (var historyEntry in currentHistory) { lastFilesVersion.AddRange(historyEntry.Files.Where(f => f.EditType == FileHistoryType.Added)); foreach (FileHistoryEntry deletedEntry in historyEntry.Files.Where(fv => fv.EditType == FileHistoryType.Deleted)) { FileHistoryEntry entryToRemove = lastFilesVersion.FirstOrDefault(fv => fv.Path == deletedEntry.Path); if (entryToRemove != null) { lastFilesVersion.Remove(entryToRemove); } else { //delete entry without added file, an error? } } } FolderVersionEntry currentVersion = new FolderVersionEntry(); List <FileHistoryEntry> touchedEntries = new List <FileHistoryEntry>(); foreach (string currentFilePath in currentFilesList) { string currentFileHash = hashService.ComputeFileHash(currentFilePath); FileHistoryEntry fileLastVersion = lastFilesVersion.FirstOrDefault(f => f.Path == currentFilePath); if (fileLastVersion != null) { if (fileLastVersion.Hash != currentFileHash) { currentVersion.AddEntry(currentFilePath, currentFileHash, FileHistoryType.Modified); } touchedEntries.Add(fileLastVersion); } else { currentVersion.AddEntry(currentFilePath, currentFileHash, FileHistoryType.Added); } } foreach (FileHistoryEntry deletedEntry in lastFilesVersion.Except(touchedEntries)) { currentVersion.AddEntry(deletedEntry.Path, string.Empty, FileHistoryType.Deleted); } SaveHistory(currentVersion); return(currentVersion); }
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously public async Task <FolderVersionEntry> CreateInitialVersion(IEnumerable <string> files) #pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously { var folderVersion = new FolderVersionEntry(); foreach (string filePath in files) { uiService.AddMessage($"Adding {filePath}..."); folderVersion.AddEntry(filePath, hashService.ComputeFilesHash(new[] { filePath }), FileHistoryType.Added); } SaveHistory(new[] { folderVersion }); return(folderVersion); }
protected async override Task RunCommandAsync() { bool explicitInclude = HasModifier(explicitIncludeModifier); string ignoreSetup = GetArgumentValue(ignoreList); List <string> packageFiles = fileService.GetWorkingDirectoryFiles(ignoreSetup.Split(',')); FolderVersionEntry version = await versioningService.CreateInitialVersion(packageFiles.ToArray <string>()); string packageName = uiService.RequestValue($"Enter package name: "); string packageHash = hashService.ComputeFilesHash(packageFiles); configService.CreateConfig(packageName, packageHash); await onlineStoreService.PushPackageAsync($"{packageName}@initial", version); }
public async Task PushPackageAsync(string name, FolderVersionEntry folderVersion) { byte[] fileData = await fileService.ZipFiles(folderVersion.Files.Where(f => f.EditType != FileHistoryType.Deleted).Select(f => f.Path)); var content = new MultipartFormDataContent { { new StringContent(name), "nameAndTag" }, { new StringContent(JsonConvert.SerializeObject(folderVersion)), "packageChanges" }, { new ByteArrayContent(fileData), "versionFile", "data.zip" } }; var request = new HttpRequestMessage { Method = HttpMethod.Post, Content = new ProgressableStreamContent(content, (long uploaded, long size) => { uiService.DisplayProgress((float)uploaded * 100 / size); }) }; request.Headers.TransferEncodingChunked = true; uiService.AddMessage("Uploading package..."); var response = await httpClient.SendAsync(request); var responseContent = await response.Content.ReadAsStringAsync(); if (response.IsSuccessStatusCode) { uiService.AddMessage("/r/nUpload done"); } else { throw new InvalidOperationException(responseContent); } }
protected async override Task RunCommandAsync() { string packageNameAndTag = GetCommandInputValue(packageNameInput); string packageName = packageNameAndTag.Split('@').FirstOrDefault(); string packageTagName = packageNameAndTag.Contains("@") ? packageNameAndTag.Split('@').LastOrDefault() : string.Empty; string[] packageTagHistory = null; bool createConfig = false; if (configService.TryGetConfig(out Config.PackageConfiguration config)) { if (packageName != config.Name) { throw new InvalidOperationException($"Folder binded to another package {config.Name}"); } string currentPackageName = $"{config.Name}@{config.Tag}"; packageTagHistory = await onlineStoreService.GetPackageTagsAsync(packageNameAndTag, currentPackageName); } else { createConfig = true; packageTagHistory = await onlineStoreService.GetAllPackageTagsAsync(packageName); if (!string.IsNullOrEmpty(packageTagName)) { packageTagHistory = packageTagHistory.SkipWhile(t => t != packageTagName).ToArray(); } else { uiService.AddMessage($"Pulling {packageName}@{packageTagHistory.FirstOrDefault()}"); } } foreach (string packageTag in packageTagHistory.Reverse()) { PackageInfo packageInfo = await onlineStoreService.GetPackageVersionAsync($"{packageName}@{packageTag}"); FolderVersionEntry folderVersion = JsonConvert.DeserializeObject <FolderVersionEntry>(packageInfo.VersionInfo); if (!localStoreService.PackageExist(packageInfo)) { HttpOperationWithProgress downloadOperation = onlineStoreService.DownloadPackage(packageName, packageTag); downloadOperation.OnProgress += (processedCount, totalCount) => { uiService.DisplayProgress((float)processedCount * 100 / totalCount); }; HttpResponseMessage response = await downloadOperation.GetOperationResultAsync(); localStoreService.SavePackage(packageInfo, await response.Content.ReadAsByteArrayAsync()); } localStoreService.RestorePackage(packageName, packageTag); if (createConfig) { configService.CreateConfig(packageNameAndTag, packageInfo.Hash); createConfig = false; } else { configService.SetTag(packageTag); } } }
protected async override Task RunCommandAsync() { PackageConfiguration config = null; if (!configService.TryGetConfig(out config)) { uiService.AddMessage("No config inited, can not compute diff"); return; } string newTag = await GetTagName(config); Dictionary <string, string> actualPathToHashMap = new Dictionary <string, string>(); foreach (var filePath in fileService.GetWorkingDirectoryFiles(config.ExcludePaths)) { actualPathToHashMap.Add(filePath, hashService.ComputeFileHash(filePath)); } Dictionary <string, string> tagPathToHashMap = await onlineStoreService.GetPackageFilesAtVersionAsync(config.Name, config.Tag); bool hasChanges = tagPathToHashMap.Keys.Except(actualPathToHashMap.Keys).Any() || actualPathToHashMap.Keys.Except(tagPathToHashMap.Keys).Any(); if (!hasChanges) { foreach (var pathToHashMap in tagPathToHashMap) { if (actualPathToHashMap[pathToHashMap.Key] != pathToHashMap.Value) { hasChanges = true; break; } } } if (!hasChanges) { uiService.AddMessage("No difference with previous version. Can not add tag"); return; } FolderVersionEntry folderVersion = versioningService.CreateDiff(tagPathToHashMap, actualPathToHashMap); ConsoleColor?statusToColor(FileHistoryType status) { switch (status) { case FileHistoryType.Added: return(ConsoleColor.Green); case FileHistoryType.Modified: return(ConsoleColor.Yellow); case FileHistoryType.Deleted: return(ConsoleColor.Red); default: return(null); } } uiService.AddMessage($"Created {config.Name}@{newTag}"); uiService.AddMessage("List of changes:"); foreach (FileHistoryEntry fileHistoryEntry in folderVersion.Files) { uiService.AddMessage( message: $"\t[{fileHistoryEntry.EditType.ToString().ToLower()}]\t{Path.GetFileName(fileHistoryEntry.Path)}", color: statusToColor(fileHistoryEntry.EditType)); } configService.SetTag(newTag); await onlineStoreService.PushPackageAsync($"{config.Name}@{newTag}", folderVersion); }
private void SaveHistory(FolderVersionEntry entry) => SaveHistory(new[] { entry });