diff --git a/.gitignore b/.gitignore index 3c4efe2..9e56738 100644 --- a/.gitignore +++ b/.gitignore @@ -258,4 +258,5 @@ paket-files/ # Python Tools for Visual Studio (PTVS) __pycache__/ -*.pyc \ No newline at end of file +*.pyc +/.dotnet-home/ diff --git a/SFTPSync.sln b/SFTPSync.sln index b3cce34..22e1f4a 100644 --- a/SFTPSync.sln +++ b/SFTPSync.sln @@ -20,6 +20,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution .github\workflows\build.yml = .github\workflows\build.yml LICENSE.md = LICENSE.md README.md = README.md + UpdateSubModules.bat = UpdateSubModules.bat EndProjectSection EndProject Global diff --git a/SFTPSyncLib/RemoteSync.cs b/SFTPSyncLib/RemoteSync.cs index f6197d5..0ad9906 100644 --- a/SFTPSyncLib/RemoteSync.cs +++ b/SFTPSyncLib/RemoteSync.cs @@ -110,6 +110,9 @@ public static async Task RunSharedInitialSyncAsync( return; } + localRootDirectory = Path.TrimEndingDirectorySeparator(Path.GetFullPath(localRootDirectory)); + remoteRootDirectory = NormalizeRemoteRootDirectory(remoteRootDirectory); + try { using (var sftp = new SftpClient(host, username, password)) @@ -282,7 +285,8 @@ public async Task InitialSync(string localPath, string remotePath) foreach (var item in localDirectories) { var directoryName = item.Split(Path.DirectorySeparatorChar).Last(); - await InitialSync(localPath + "\\" + directoryName, remotePath + "/" + directoryName); + var nextRemotePath = AppendRemotePath(remotePath, directoryName); + await InitialSync(localPath + "\\" + directoryName, nextRemotePath); } await SyncDirectoryAsync(_sftp, localPath, remotePath, _searchPattern); @@ -331,7 +335,7 @@ private static string[] FilteredDirectories(string localRootDirectory, string lo .OrderBy(path => path, StringComparer.OrdinalIgnoreCase)) { var directoryName = directory.Split(Path.DirectorySeparatorChar).Last(); - var remotePath = current.RemotePath + "/" + directoryName; + var remotePath = AppendRemotePath(current.RemotePath, directoryName); queue.Enqueue((directory, remotePath)); } } @@ -359,12 +363,13 @@ private static async Task CreateDirectoriesInternal( foreach (var item in localDirectories) { var directoryName = item.Split(Path.DirectorySeparatorChar).Last(); + var targetRemotePath = AppendRemotePath(remotePath, directoryName); if (!remoteDirectories.ContainsKey(directoryName)) { - Logger.LogInfo($"Creating remote directory {remotePath}{directoryName}"); - sftp.CreateDirectory(remotePath + "/" + directoryName); + Logger.LogInfo($"Creating remote directory {targetRemotePath}"); + sftp.CreateDirectory(targetRemotePath); } - await CreateDirectoriesInternal(sftp, localRootDirectory, localPath + "\\" + directoryName, remotePath + "/" + directoryName, excludedFolders); + await CreateDirectoriesInternal(sftp, localRootDirectory, localPath + "\\" + directoryName, targetRemotePath, excludedFolders); } } @@ -421,6 +426,32 @@ private string GetRemotePathForLocal(string localPath) return _remoteRootDirectory + "/" + relativePath; } + private static string NormalizeRemoteRootDirectory(string remoteRootDirectory) + { + if (remoteRootDirectory == "/") + return "/"; + + return remoteRootDirectory.TrimEnd('/', '\\'); + } + + private static string AppendRemotePath(string remotePath, string segment) + { + if (string.IsNullOrEmpty(segment)) + return remotePath; + + var normalizedSegment = segment.Replace('\\', '/').Trim('/'); + if (normalizedSegment.Length == 0) + return remotePath; + + if (remotePath == "/") + return "/" + normalizedSegment; + + if (string.IsNullOrEmpty(remotePath)) + return normalizedSegment; + + return remotePath + "/" + normalizedSegment; + } + private void EnsureConnected() { if (_disposed) diff --git a/SFTPSyncSetup/Product.wxs b/SFTPSyncSetup/Product.wxs index 74146a9..70374fe 100644 --- a/SFTPSyncSetup/Product.wxs +++ b/SFTPSyncSetup/Product.wxs @@ -5,7 +5,7 @@ Id="*" Name="SFTPSync" Language="1033" - Version="1.7" + Version="1.8" Manufacturer="Synergex International Corporation" UpgradeCode="6000f870-b811-4e22-b80b-5b8956317d09"> diff --git a/SFTPSyncSetup/SFTPSyncSetup.wixproj b/SFTPSyncSetup/SFTPSyncSetup.wixproj index 04ec8da..9479027 100644 --- a/SFTPSyncSetup/SFTPSyncSetup.wixproj +++ b/SFTPSyncSetup/SFTPSyncSetup.wixproj @@ -6,7 +6,7 @@ 3.10 5074cbcb-641b-4a9c-b3bc-8dd0b78810a6 2.0 - SFTPSync-1.7 + SFTPSync-1.8 Package SFTPSyncSetup diff --git a/SFTPSyncUI/SFTPSyncUI.csproj b/SFTPSyncUI/SFTPSyncUI.csproj index ad38383..64e8fc6 100644 --- a/SFTPSyncUI/SFTPSyncUI.csproj +++ b/SFTPSyncUI/SFTPSyncUI.csproj @@ -20,10 +20,10 @@ LICENSE.md True Synergex International, Inc. - 1.7 - 1.7 + 1.8 + 1.8 preview - 1.7 + 1.8 @@ -36,7 +36,7 @@ PreserveNewest - PreserveNewest + Always PreserveNewest diff --git a/SFTPSyncUI/docs/SFTPSync.chm b/SFTPSyncUI/docs/SFTPSync.chm index 80cc187..5c2152a 100644 Binary files a/SFTPSyncUI/docs/SFTPSync.chm and b/SFTPSyncUI/docs/SFTPSync.chm differ diff --git a/SFTPSyncUI/docs/SFTPSync_files/CompletedSettingsFile.png b/SFTPSyncUI/docs/SFTPSync_files/CompletedSettingsFile.png index f71437b..1014e69 100644 Binary files a/SFTPSyncUI/docs/SFTPSync_files/CompletedSettingsFile.png and b/SFTPSyncUI/docs/SFTPSync_files/CompletedSettingsFile.png differ diff --git a/SFTPSyncUI/docs/SFTPSync_files/EmptySettingsDialog.png b/SFTPSyncUI/docs/SFTPSync_files/EmptySettingsDialog.png index f914963..d317f7d 100644 Binary files a/SFTPSyncUI/docs/SFTPSync_files/EmptySettingsDialog.png and b/SFTPSyncUI/docs/SFTPSync_files/EmptySettingsDialog.png differ diff --git a/SFTPSyncUI/docs/SFTPSync_files/SettingsFileContent.png b/SFTPSyncUI/docs/SFTPSync_files/SettingsFileContent.png index 6c5a7e5..94b7bf3 100644 Binary files a/SFTPSyncUI/docs/SFTPSync_files/SettingsFileContent.png and b/SFTPSyncUI/docs/SFTPSync_files/SettingsFileContent.png differ diff --git a/UpdateSubModules.bat b/UpdateSubModules.bat new file mode 100644 index 0000000..ec1b037 --- /dev/null +++ b/UpdateSubModules.bat @@ -0,0 +1,10 @@ +@echo off +pushd %~dp0 + +rem Keep submodules pinned to the commit recorded by this repo. +git submodule sync --recursive +git submodule update --init --recursive --checkout + +rem Do not auto-pull submodule branches here; that makes the superproject dirty. + +popd