public static async Task syncFile(PathChange change, IPathInfo sourceInfo, IPathInfo targetInfo)
		{
			var compareResult = await compareFile(change.ReadFileSystem, change.Source, change.Target);

			if (compareResult != CompareResult.Differ)
				return;

			// decide in which direction to sync.

			var changeLocation = change.Location;
			if (changeLocation == ChangeLocation.Unknown)
			{
				changeLocation = sourceInfo.LastWriteTimeUtc >= targetInfo.LastWriteTimeUtc
					? ChangeLocation.AtSource
					: ChangeLocation.AtTarget;
			}

			switch (changeLocation)
			{
				case ChangeLocation.AtSource:
					await overwriteFile(change, change.Source, change.Target);
					break;

				case ChangeLocation.AtTarget:
					await overwriteFile(change, change.Target, change.Source);
					break;
			}
		}
		public static async Task syncDirectory(PathChange change)
		{
			if (change.Mode != ChangeMode.Deep)
				return;

			var rfs = change.ReadFileSystem;
			var sourceEntries = rfs.scan(change.Source);
			var targetEntries = rfs.scan(change.Target);

			var all = sourceEntries.Concat(targetEntries).Distinct();

			await Task.WhenAll(all.Select(str => Synchronizer.sync(change.nested(str))));
		}
Beispiel #3
0
		public static async Task sync(PathChange change)
		{
			var reader = change.ReadFileSystem;
			var sourceInfo = reader.query(change.Source);
			var targetInfo = reader.query(change.Target);

			var sourceKind = sourceInfo.Type;
			var targetKind = targetInfo.Type;
			if (sourceKind == PathType.NotExisting && targetKind == PathType.NotExisting)
			{
				change.log("not existing");
				return;
			}

			if (sourceKind == PathType.Ignored || targetKind == PathType.Ignored)
			{
				change.log("ignored");
				return;
			}

			if (targetKind == PathType.NotExisting)
			{
				if (change.Location == ChangeLocation.AtTarget)
					deleteSource(change, sourceKind);
				else
					await copyToTarget(change, sourceKind);
				return;
			}
		
			if (sourceKind == PathType.NotExisting)
			{
				if (change.Location == ChangeLocation.AtSource)
					deleteTarget(change, targetKind);
				else
					await copyToSource(change, targetKind);
				return;
			}

			if (sourceKind != targetKind)
			{
				change.log("directory <-> file sync not implemented");
				return;
			}

			if (sourceKind == PathType.Directory)
				await DirectorySynchronizer.syncDirectory(change);
			else
				await FileSynchronizer.syncFile(change, sourceInfo, targetInfo);
		}
Beispiel #4
0
		static async Task copyToSource(PathChange change, PathType kind)
		{
			switch (kind)
			{
				case PathType.Directory:
					DirectorySynchronizer.createDirectory(change, change.Source);
					if (change.Mode == ChangeMode.Deep && change.Configuration.Sync)
						await sync(change);
					break;

				case PathType.File:
					await FileSynchronizer.copyFile(change, change.Target, change.Source);
					break;
			}
		}
Beispiel #5
0
		static void internalMain(string[] args)
		{
			var configuration = Configuration.fromCommandLine(args);

			var sourcePath = PathHelper.importSyncPath(configuration.SourcePath);
			var targetPath = PathHelper.importSyncPath(configuration.TargetPath);

			var readFileSystem = new ReadFileSystem();
			var writeFileSystem = configuration.Sync 
				? (IWriteFileSystem) new WriteFileSystem() 
				: new FakeWriteFileSystem();

			if (configuration.Watch)
			{
				Action<string, ChangeLocation> watcherChange = (path, loc) =>
					{
						var pc = new PathChange(configuration,
							ChangeMode.Shallow,
							loc,
							path,
							readFileSystem,
							writeFileSystem);

						Synchronizer.sync(pc);
					};

				beginWatching(
					readFileSystem,
					sourcePath,
					targetPath,
					path => watcherChange(path, ChangeLocation.AtSource),
					path => watcherChange(path, ChangeLocation.AtTarget));
			}

			deepSynchronization(configuration, readFileSystem, writeFileSystem)
				.Wait();

			if (configuration.Watch)
				Thread.Sleep(Timeout.Infinite);
		}
		public static void createDirectory(PathChange change, string path)
		{
			change.log("creating directory");
			
			change.WriteFileSystem.createDirectory(path);
		}
		public static async Task overwriteFile(PathChange change, string source, string target)
		{
			change.log("overwriting");

			await change.WriteFileSystem.overwriteAsync(source, target);
		}
		// we probably should copy the files by hand to ensure that the proper sharing flags are set.

		public static async Task copyFile(PathChange change, string source, string target)
		{
			change.log("copying");

			await change.WriteFileSystem.copyAsync(source, target);
		}
Beispiel #9
0
		static async Task deepSynchronization(Configuration Configuration, IReadFileSystem reader, IWriteFileSystem writer)
		{
			var pc = new PathChange(Configuration, ChangeMode.Deep, ChangeLocation.Unknown, "", reader, writer);
			await Synchronizer.sync(pc);
		}
Beispiel #10
0
		static void delete(PathChange change, string path, PathType type)
		{
			var writer = change.WriteFileSystem;
			switch (type)
			{
				case PathType.Directory:
					writer.deleteDirectoryRecursive(path);
					break;
				case PathType.File:
					writer.deleteFile(path);
					break;
			}
		}
Beispiel #11
0
		static void deleteTarget(PathChange change, PathType type)
		{
			delete(change, change.Target, type);
		}
Beispiel #12
0
		static void deleteSource(PathChange change, PathType type)
		{
			delete(change, change.Source, type);
		}