A Swift package for building rsync command arguments in RsyncUI. This package provides type-safe, maintainable builders for creating rsync parameters for synchronization, snapshot, and remote sync operations.
- ✅ Type-safe parameter configuration
- ✅ Immutable argument building (no side effects)
- ✅ Clear naming - descriptive property names instead of
parameter1-14 - ✅ Error handling with proper Swift error types
- ✅ Modular design - separated concerns for SSH, core params, and optional params
- ✅ Comprehensive support for synchronize, snapshot, and syncremote tasks
import RsyncArguments
// Create parameter configuration
letbasicParams=BasicRsyncParameters(
archiveMode:"--archive",
verboseOutput:"--verbose",
compressionEnabled:"--compress",
deleteExtraneous:"--delete")letsshParams=SSHParameters(
offsiteServer:"backup.example.com",
offsiteUsername:"user",
sshport:"22",
sshkeypathandidentityfile:"~/.ssh/id_rsa",
sharedsshport:nil,
sharedsshkeypathandidentityfile:nil,
rsyncversion3:true)letpaths=PathConfiguration(
localCatalog:"/Users/user/Documents/",
offsiteCatalog:"/backup/documents/")letparams=Parameters(
task:DefaultRsyncParameters.synchronize.rawValue,
basicParameters: basicParams,
optionalParameters:OptionalRsyncParameters(),
sshParameters: sshParams,
paths: paths,
snapshotNumber:nil,
isRsyncDaemon:false,
rsyncVersion3:true)
// Build arguments
letbuilder=RsyncParametersSynchronize(parameters: params)try builder.argumentsForSynchronize(forDisplay:false, verify:false, dryrun:false)print(builder.computedArguments)
// Output: ["--archive", "--verbose", "--compress", "--delete", "-e", "ssh -i ~/.ssh/id_rsa -p 22", ...]letparams=Parameters(
task:DefaultRsyncParameters.snapshot.rawValue,
basicParameters: basicParams,
optionalParameters:OptionalRsyncParameters(),
sshParameters: sshParams,
paths: paths,
snapshotNumber:5, // Snapshot number
isRsyncDaemon:false,
rsyncVersion3:true)letbuilder=RsyncParametersSynchronize(parameters: params)try builder.argumentsForSynchronizeSnapshot(forDisplay:false, verify:false, dryrun:false)letpullBuilder=RsyncParametersPullRemote(parameters: params)try pullBuilder.argumentsPullRemote(forDisplay:false, verify:false, dryrun:false)letrestoreParams=Parameters(
task:DefaultRsyncParameters.synchronize.rawValue,
basicParameters: basicParams,
optionalParameters:OptionalRsyncParameters(),
sshParameters: sshParams,
paths:PathConfiguration(
localCatalog:"/Users/user/Documents/",
offsiteCatalog:"/backup/documents/",
sharedPathForRestore:"/Users/user/Restore/"),
snapshotNumber:nil,
isRsyncDaemon:false,
rsyncVersion3:true)letrestoreBuilder=RsyncParametersRestore(parameters: restoreParams)try restoreBuilder.argumentsRestore(
forDisplay:false,
verify:false,
dryrun:true,
restoreSnapshotByFiles:false)// Create snapshot root catalog
letsshParams=SSHParameters(
server:"backup.example.com",
username:"user",
localConfig:SSHConfiguration(port:22, identityFile:"~/.ssh/id_rsa"),
sharedConfig:SSHConfiguration(port:nil, identityFile:nil),
rsyncVersion3:true)letcreateCatalog=SnapshotCreateRootCatalog(sshParameters: sshParams)letargs= createCatalog.snapshotCreateRootCatalog(offsiteCatalog:"/backup/snapshots/")
// Delete snapshot
letdeleteSnapshot=SnapshotDelete(sshParameters: sshParams)letdeleteArgs= deleteSnapshot.snapshotDelete(remoteCatalog:"/backup/snapshots/5/")
// Check remote size
letremoteSize=RemoteSize(sshParameters: sshParams)iflet sizeArgs = remoteSize.remoteDiskSize(remoteCatalog:"/backup/"){
// Use sizeArgs to execute command
}- Parameters - Main configuration container with structured parameter groups
- RsyncParametersSynchronize - Builds arguments for sync, snapshot, and syncremote
- RsyncParametersRestore - Builds arguments for restore operations
- RsyncParametersPullRemote - Builds arguments for pulling from remote
- SSHParameterBuilder - Consolidated SSH parameter building
- RsyncArgumentBuilder - Helper for building argument arrays
- BasicRsyncParameters - Core rsync flags (archive, verbose, compress, delete)
- OptionalRsyncParameters - User-defined parameters 8-14
- SSHConfiguration - SSH port and identity file settings
- SSHParameters - Complete SSH configuration with server info
- PathConfiguration - Source and destination paths
All public methods that can fail throw ParameterError:
publicenumParameterError:LocalizedError{case missingLocalCatalog
case missingOffsiteCatalog
case missingOffsiteServer
case missingOffsiteUsername
case invalidTaskType
case invalidSnapshotNumber
case invalidSSHConfiguration
}Example error handling:
do{try builder.argumentsForSynchronize(forDisplay:false, verify:false, dryrun:false)}catchParameterError.missingOffsiteServer {print("Server configuration required for remote sync")}catch{print("Error: \(error.localizedDescription)")}letparams=Parameters(
task:DefaultRsyncParameters.synchronize.rawValue,
basicParameters:BasicRsyncParameters(
archiveMode:"--archive",
verboseOutput:"--verbose",
compressionEnabled:"--compress",
deleteExtraneous:"--delete"),
optionalParameters:OptionalRsyncParameters(),
sshParameters: sshParams,
paths: pathConfig,
snapshotNumber:nil,
isRsyncDaemon:false,
rsyncVersion3:true)- Swift 5.9+
- macOS 13.0+ / iOS 16.0+
MIT
Thomas Evensen