示例#1
0
        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();
        }
示例#2
0
        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"));
        }
示例#3
0
        // 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);
                }
            }
        }
示例#4
0
 public void Setup()
 {
     _fileList = new FileMaskList();
     _fileList.SetList(new List <string>
     {
         "*.txt",
         "/var",
         "dist",
         "!/var/log",
         "start*end.cpp",
         "~*",
         "*.tmp",
         "*.pyc",
         "*.swp",
         ".git",
         "CVS",
     });
 }
示例#5
0
 public CommandRunner(ILogger logger)
 {
     _logger      = logger;
     _excludeList = new FileMaskList();
 }
示例#6
0
        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
            });
        }