| author | Fabian Huch <huch@in.tum.de> | 
| Fri, 01 Dec 2023 20:32:34 +0100 | |
| changeset 79101 | 4e47b34fbb8e | 
| parent 77852 | df35b5b7b6a4 | 
| child 80192 | 36e6ba1527f0 | 
| 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, | |
| 77795 | 15 | archive: Boolean = true, | 
| 16 | stats: Boolean = true | |
| 77788 
c2ce9ac85859
use remote copy of locally installed rsync component: for uniform version and options;
 wenzelm parents: 
77787diff
changeset | 17 |     ): Context = {
 | 
| 
c2ce9ac85859
use remote copy of locally installed rsync component: for uniform version and options;
 wenzelm parents: 
77787diff
changeset | 18 | val directory = Components.provide(Component_Rsync.home, ssh = ssh, progress = progress) | 
| 77795 | 19 | new Context(directory, progress, archive, stats) | 
| 77788 
c2ce9ac85859
use remote copy of locally installed rsync component: for uniform version and options;
 wenzelm parents: 
77787diff
changeset | 20 | } | 
| 77787 | 21 | } | 
| 22 | ||
| 23 | final class Context private( | |
| 77790 | 24 | directory: Components.Directory, | 
| 77787 | 25 | val progress: Progress, | 
| 26 | archive: Boolean, | |
| 77795 | 27 | stats: Boolean | 
| 75527 | 28 |   ) {
 | 
| 77791 | 29 | override def toString: String = directory.toString | 
| 30 | ||
| 77790 | 31 | def ssh: SSH.System = directory.ssh | 
| 77787 | 32 | |
| 76136 
1bb677cceea4
let rsync re-use ssh connection via control path;
 wenzelm parents: 
76131diff
changeset | 33 |     def command: String = {
 | 
| 77790 | 34 | val program = Component_Rsync.remote_program(directory) | 
| 77783 
fb61887c069a
clarified underlying SSH session of "isabelle hg_sync" and "isabelle sync";
 wenzelm parents: 
77518diff
changeset | 35 | 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 | 36 | 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 | 37 | if_proper(ssh_command, " --rsh=" + Bash.string(ssh_command)) + | 
| 77790 | 38 | " --rsync-path=" + Bash.string(quote(File.standard_path(program))) + | 
| 77795 | 39 | (if (archive) " --archive" else "") + | 
| 40 | (if (stats) " --stats" else "") | |
| 76136 
1bb677cceea4
let rsync re-use ssh connection via control path;
 wenzelm parents: 
76131diff
changeset | 41 | } | 
| 77783 
fb61887c069a
clarified underlying SSH session of "isabelle hg_sync" and "isabelle sync";
 wenzelm parents: 
77518diff
changeset | 42 | |
| 
fb61887c069a
clarified underlying SSH session of "isabelle hg_sync" and "isabelle sync";
 wenzelm parents: 
77518diff
changeset | 43 |     def target(path: Path, direct: Boolean = false): String = {
 | 
| 
fb61887c069a
clarified underlying SSH session of "isabelle hg_sync" and "isabelle sync";
 wenzelm parents: 
77518diff
changeset | 44 | val s = ssh.rsync_path(path) | 
| 
fb61887c069a
clarified underlying SSH session of "isabelle hg_sync" and "isabelle sync";
 wenzelm parents: 
77518diff
changeset | 45 | if (direct) Url.direct_path(s) else s | 
| 
fb61887c069a
clarified underlying SSH session of "isabelle hg_sync" and "isabelle sync";
 wenzelm parents: 
77518diff
changeset | 46 | } | 
| 75525 
68162e4f60a7
clarified signature: more explicit type Rsync.Context;
 wenzelm parents: 
75524diff
changeset | 47 | } | 
| 
68162e4f60a7
clarified signature: more explicit type Rsync.Context;
 wenzelm parents: 
75524diff
changeset | 48 | |
| 75526 | 49 | def exec( | 
| 75525 
68162e4f60a7
clarified signature: more explicit type Rsync.Context;
 wenzelm parents: 
75524diff
changeset | 50 | context: Context, | 
| 75523 | 51 | thorough: Boolean = false, | 
| 52 | prune_empty_dirs: Boolean = false, | |
| 53 | dry_run: Boolean = false, | |
| 54 | clean: Boolean = false, | |
| 55 | filter: List[String] = Nil, | |
| 56 | args: List[String] = Nil | |
| 57 |   ): Process_Result = {
 | |
| 77517 | 58 | val progress = context.progress | 
| 75523 | 59 | val script = | 
| 75525 
68162e4f60a7
clarified signature: more explicit type Rsync.Context;
 wenzelm parents: 
75524diff
changeset | 60 | context.command + | 
| 77518 
fda4da0f80f4
clarified signature: manage "verbose" flag via "progress";
 wenzelm parents: 
77517diff
changeset | 61 | (if (progress.verbose) " --verbose" else "") + | 
| 75523 | 62 | (if (thorough) " --ignore-times" else " --omit-dir-times") + | 
| 63 | (if (prune_empty_dirs) " --prune-empty-dirs" else "") + | |
| 64 | (if (dry_run) " --dry-run" else "") + | |
| 65 | (if (clean) " --delete-excluded" else "") + | |
| 66 | filter.map(s => " --filter=" + Bash.string(s)).mkString + | |
| 77369 | 67 | if_proper(args, " " + Bash.strings(args)) | 
| 77517 | 68 | progress.bash(script, echo = true) | 
| 75523 | 69 | } | 
| 70 | } |