public Sender(SyncOptions syncOptions, ILogger logger) { _logger = logger; _pathScanner = new PathScanner(this); _sentReporter = new SentReporter(_logger); _srcPath = Path.GetFullPath(syncOptions.SourcePath); _cancellationTokenSource = new CancellationTokenSource(); if (!Directory.Exists(_srcPath)) { throw new SyncException($"Invalid source path: {_srcPath}"); } _excludeList = new FileMaskList(); _excludeList.SetList(syncOptions.ExcludeList); _changes = new Dictionary <string, FsSenderChange>(); _needToScan = true; _agentStarter = AgentStarter.Create(syncOptions, _logger); _logger.Log($"Sync {syncOptions}"); _applyRequest = new ApplyRequest(_logger) { BasePath = _srcPath, }; UpdateHasWork(); }
public void TestMasks() { var fileList = new FileMaskList(); fileList.SetList(new List <string> { "*.txt", "/var", "dist", "!/var/log", "start*end.cpp" }); // txt Assert.True(fileList.IsMatch("test.txt")); Assert.True(fileList.IsMatch("home/test.txt")); Assert.False(fileList.IsMatch("test.txt1")); // var Assert.True(fileList.IsMatch("var/www")); Assert.False(fileList.IsMatch("www/var")); // dist Assert.True(fileList.IsMatch("home/www/dist")); Assert.True(fileList.IsMatch("dist")); Assert.False(fileList.IsMatch("distX")); // negative Assert.False(fileList.IsMatch("var/log")); Assert.True(fileList.IsMatch("var/log1")); Assert.False(fileList.IsMatch("var/log/test")); // wildcard Assert.True(fileList.IsMatch("start_middle_end.cpp")); Assert.False(fileList.IsMatch("start_middle.cpp")); }
// read and apply changes public IEnumerable <FsChangeResult> ReadAndApplyChanges(FileMaskList excludeList) { while (true) { var fsChange = Reader.ReadFsChange(); if (fsChange.IsEmpty) { break; } var fsChangeResult = ApplyFsChange(fsChange, excludeList); if (fsChangeResult.ResultCode != FsChangeResultCode.Ok && fsChange.IsChange) { var path = Path.Combine(BasePath, fsChange.Path); if (fsChange.IsDirectory && File.Exists(path) || !fsChange.IsDirectory && Directory.Exists(path)) { // delete and retry var fsRemoveChangeResult = ApplyFsChange( new FsChange(FsChangeType.Remove, fsChange.Path), excludeList); if (fsRemoveChangeResult.ResultCode == FsChangeResultCode.Ok) { fsChangeResult = ApplyFsChange(fsChange, excludeList); } } } // TODO: skip ok codes (sender do not use them at the moment) if (fsChangeResult.ResultCode != FsChangeResultCode.Ok) { yield return(fsChangeResult); } } }
public void Setup() { _fileList = new FileMaskList(); _fileList.SetList(new List <string> { "*.txt", "/var", "dist", "!/var/log", "start*end.cpp", "~*", "*.tmp", "*.pyc", "*.swp", ".git", "CVS", }); }
public CommandRunner(ILogger logger) { _logger = logger; _excludeList = new FileMaskList(); }
private FsChangeResult ApplyFsChange(FsChange fsChange, FileMaskList excludeList) { var path = Path.Combine(BasePath, fsChange.Path); FsChangeResultCode resultCode = FsChangeResultCode.None; string error = null; // Change file | Remove | Rename + Change directory if (fsChange.IsChange && !fsChange.IsDirectory) { try { if (fsChange.HasBody && Reader.ReadFsChangeBody(path, fsChange)) { resultCode = FsChangeResultCode.Ok; } else { // error occurred in sender error = "Sender error"; resultCode = FsChangeResultCode.SenderError; } } catch (EndOfStreamException) { // end of data throw; } catch (Exception ex) { resultCode = FsChangeResultCode.Error; error = ex.Message; } } else if (fsChange.IsRemove) { // directory if (Directory.Exists(path)) { var scanDirectory = new ScanDirectory(Logger, excludeList, false); Exception exception = null; foreach (var fsEntry in scanDirectory.ScanPath(BasePath, fsChange.Path)) { var fsEntryPath = Path.Combine(BasePath, fsEntry.Path); try { if (fsEntry.IsDirectory) { Directory.Delete(fsEntryPath, false); } else { File.Delete(fsEntryPath); } } catch (Exception ex) { exception ??= ex; Logger.Log($"Error deleting {fsEntryPath}: {ex.Message}", LogLevel.Warning); } } try { Directory.Delete(path, false); } catch (Exception ex) { exception ??= ex; Logger.Log($"Error deleting {path}: {ex.Message}", LogLevel.Warning); } if (exception == null) { resultCode = FsChangeResultCode.Ok; } else { // scan directory see any file -> error (handle excludes) if (scanDirectory.ScanPath(BasePath, fsChange.Path).Any(x => !x.IsDirectory)) { resultCode = FsChangeResultCode.Error; error = exception.Message; } else { resultCode = FsChangeResultCode.Ok; } } } else if (File.Exists(path)) { try { File.Delete(path); resultCode = FsChangeResultCode.Ok; } catch (Exception ex) { resultCode = FsChangeResultCode.Error; error = ex.Message; } } else { resultCode = FsChangeResultCode.Ok; } } else { if (fsChange.IsChange && fsChange.IsDirectory) { try { var directoryPath = fsChange.IsRename ? Path.Combine(BasePath, fsChange.OldPath) : path; Directory.CreateDirectory(directoryPath); Directory.SetLastWriteTime(directoryPath, fsChange.LastWriteTime); resultCode = FsChangeResultCode.Ok; } catch (Exception ex) { error = ex.Message; resultCode = FsChangeResultCode.Error; } } if (resultCode != FsChangeResultCode.Error && fsChange.IsRename) { try { var oldPath = Path.Combine(BasePath, fsChange.OldPath); if (Directory.Exists(oldPath)) { Directory.Move(oldPath, path); } else { File.Move(oldPath, path, true); } resultCode = FsChangeResultCode.Ok; } catch (Exception ex) { error = ex.Message; resultCode = FsChangeResultCode.Error; } } } if (resultCode == FsChangeResultCode.None) { resultCode = FsChangeResultCode.Error; error = "Unknown change type"; } return(new FsChangeResult { ChangeType = fsChange.ChangeType, Path = fsChange.Path, ResultCode = resultCode, ErrorMessage = error }); }