| author | wenzelm | 
| Tue, 10 Dec 2024 21:06:04 +0100 | |
| changeset 81572 | 693a95492008 | 
| parent 80234 | cce5670be9f9 | 
| permissions | -rw-r--r-- | 
| 75523 | 1 | /* Title: Pure/General/rsync.scala | 
| 2 | Author: Makarius | |
| 3 | ||
| 77793 | 4 | Support for rsync, based on Isabelle component. | 
| 75523 | 5 | */ | 
| 6 | ||
| 7 | package isabelle | |
| 8 | ||
| 9 | ||
| 10 | object Rsync {
 | |
| 77787 | 11 |   object Context {
 | 
| 12 | def apply( | |
| 13 | progress: Progress = new Progress, | |
| 14 | ssh: SSH.System = SSH.Local, | |
| 80234 
cce5670be9f9
support "rsync --chmod --chown" via Rsync.Context;
 wenzelm parents: 
80233diff
changeset | 15 | chmod: String = "", | 
| 
cce5670be9f9
support "rsync --chmod --chown" via Rsync.Context;
 wenzelm parents: 
80233diff
changeset | 16 | chown: String = "", | 
| 77795 | 17 | archive: Boolean = true, | 
| 18 | stats: Boolean = true | |
| 77788 
c2ce9ac85859
use remote copy of locally installed rsync component: for uniform version and options;
 wenzelm parents: 
77787diff
changeset | 19 |     ): Context = {
 | 
| 
c2ce9ac85859
use remote copy of locally installed rsync component: for uniform version and options;
 wenzelm parents: 
77787diff
changeset | 20 | val directory = Components.provide(Component_Rsync.home, ssh = ssh, progress = progress) | 
| 80234 
cce5670be9f9
support "rsync --chmod --chown" via Rsync.Context;
 wenzelm parents: 
80233diff
changeset | 21 | new Context(directory, progress, chmod, chown, archive, stats) | 
| 77788 
c2ce9ac85859
use remote copy of locally installed rsync component: for uniform version and options;
 wenzelm parents: 
77787diff
changeset | 22 | } | 
| 77787 | 23 | } | 
| 24 | ||
| 25 | final class Context private( | |
| 77790 | 26 | directory: Components.Directory, | 
| 77787 | 27 | val progress: Progress, | 
| 80234 
cce5670be9f9
support "rsync --chmod --chown" via Rsync.Context;
 wenzelm parents: 
80233diff
changeset | 28 | chmod: String, | 
| 
cce5670be9f9
support "rsync --chmod --chown" via Rsync.Context;
 wenzelm parents: 
80233diff
changeset | 29 | chown: String, | 
| 77787 | 30 | archive: Boolean, | 
| 77795 | 31 | stats: Boolean | 
| 75527 | 32 |   ) {
 | 
| 77791 | 33 | override def toString: String = directory.toString | 
| 34 | ||
| 77790 | 35 | def ssh: SSH.System = directory.ssh | 
| 77787 | 36 | |
| 76136 
1bb677cceea4
let rsync re-use ssh connection via control path;
 wenzelm parents: 
76131diff
changeset | 37 |     def command: String = {
 | 
| 77790 | 38 | val program = Component_Rsync.remote_program(directory) | 
| 77783 
fb61887c069a
clarified underlying SSH session of "isabelle hg_sync" and "isabelle sync";
 wenzelm parents: 
77518diff
changeset | 39 | val ssh_command = ssh.client_command | 
| 77792 
b81b2c50fc7c
use "rsync --secluded-args" by default, discontinue obsolete option -P of sync tools;
 wenzelm parents: 
77791diff
changeset | 40 | File.bash_path(Component_Rsync.local_program) + " --secluded-args" + | 
| 77783 
fb61887c069a
clarified underlying SSH session of "isabelle hg_sync" and "isabelle sync";
 wenzelm parents: 
77518diff
changeset | 41 | if_proper(ssh_command, " --rsh=" + Bash.string(ssh_command)) + | 
| 77790 | 42 | " --rsync-path=" + Bash.string(quote(File.standard_path(program))) + | 
| 80234 
cce5670be9f9
support "rsync --chmod --chown" via Rsync.Context;
 wenzelm parents: 
80233diff
changeset | 43 | if_proper(chmod, " --chmod=" + Bash.string(chmod)) + | 
| 
cce5670be9f9
support "rsync --chmod --chown" via Rsync.Context;
 wenzelm parents: 
80233diff
changeset | 44 | if_proper(chown, " --chown=" + Bash.string(chown)) + | 
| 80233 | 45 | if_proper(archive, " --archive") + | 
| 46 | if_proper(stats, " --stats") | |
| 76136 
1bb677cceea4
let rsync re-use ssh connection via control path;
 wenzelm parents: 
76131diff
changeset | 47 | } | 
| 77783 
fb61887c069a
clarified underlying SSH session of "isabelle hg_sync" and "isabelle sync";
 wenzelm parents: 
77518diff
changeset | 48 | |
| 80192 | 49 | def target(path: Path, direct: Boolean = false): String = | 
| 50 | Url.dir_path(ssh.rsync_path(path), direct = direct) | |
| 75525 
68162e4f60a7
clarified signature: more explicit type Rsync.Context;
 wenzelm parents: 
75524diff
changeset | 51 | } | 
| 
68162e4f60a7
clarified signature: more explicit type Rsync.Context;
 wenzelm parents: 
75524diff
changeset | 52 | |
| 75526 | 53 | def exec( | 
| 75525 
68162e4f60a7
clarified signature: more explicit type Rsync.Context;
 wenzelm parents: 
75524diff
changeset | 54 | context: Context, | 
| 75523 | 55 | thorough: Boolean = false, | 
| 56 | prune_empty_dirs: Boolean = false, | |
| 57 | dry_run: Boolean = false, | |
| 58 | clean: Boolean = false, | |
| 59 | filter: List[String] = Nil, | |
| 60 | args: List[String] = Nil | |
| 61 |   ): Process_Result = {
 | |
| 77517 | 62 | val progress = context.progress | 
| 75523 | 63 | val script = | 
| 75525 
68162e4f60a7
clarified signature: more explicit type Rsync.Context;
 wenzelm parents: 
75524diff
changeset | 64 | context.command + | 
| 80233 | 65 | if_proper(progress.verbose, " --verbose") + | 
| 75523 | 66 | (if (thorough) " --ignore-times" else " --omit-dir-times") + | 
| 80233 | 67 | if_proper(prune_empty_dirs, " --prune-empty-dirs") + | 
| 68 | if_proper(dry_run, " --dry-run") + | |
| 69 | if_proper(clean, " --delete-excluded") + | |
| 75523 | 70 | filter.map(s => " --filter=" + Bash.string(s)).mkString + | 
| 77369 | 71 | if_proper(args, " " + Bash.strings(args)) | 
| 77517 | 72 | progress.bash(script, echo = true) | 
| 75523 | 73 | } | 
| 74 | } |