diff --git a/kittens/ssh/copy.py b/kittens/ssh/copy.py index 7048af3cc..b861b914b 100644 --- a/kittens/ssh/copy.py +++ b/kittens/ssh/copy.py @@ -5,13 +5,15 @@ import glob import os import shlex +import uuid from typing import ( - Iterable, Iterator, List, NamedTuple, Optional, Sequence, Tuple + Dict, Iterable, Iterator, List, NamedTuple, Optional, Sequence, Tuple ) from kitty.cli import parse_args from kitty.cli_stub import CopyCLIOptions from kitty.types import run_once + from ..transfer.utils import expand_home, home_path @@ -81,11 +83,12 @@ def get_arcname(loc: str, dest: Optional[str], home: str) -> str: class CopyInstruction(NamedTuple): + local_path: str arcname: str exclude_patterns: Tuple[str, ...] -def parse_copy_instructions(val: str) -> Iterable[Tuple[str, CopyInstruction]]: +def parse_copy_instructions(val: str, current_val: Dict[str, str]) -> Iterable[Tuple[str, CopyInstruction]]: opts, args = parse_copy_args(shlex.split(val)) locations: List[str] = [] for a in args: @@ -97,4 +100,4 @@ def parse_copy_instructions(val: str) -> Iterable[Tuple[str, CopyInstruction]]: home = home_path() for loc in locations: arcname = get_arcname(loc, opts.dest, home) - yield loc, CopyInstruction(arcname, tuple(opts.exclude)) + yield str(uuid.uuid4()), CopyInstruction(loc, arcname, tuple(opts.exclude)) diff --git a/kittens/ssh/main.py b/kittens/ssh/main.py index 9f5873c4d..6e8cc2a65 100644 --- a/kittens/ssh/main.py +++ b/kittens/ssh/main.py @@ -98,8 +98,8 @@ def make_tarfile(ssh_opts: SSHOptions, base_env: Dict[str, str]) -> bytes: buf = io.BytesIO() with tarfile.open(mode='w:bz2', fileobj=buf, encoding='utf-8') as tf: rd = ssh_opts.remote_dir.rstrip('/') - for location, ci in ssh_opts.copy.items(): - tf.add(location, arcname=ci.arcname, filter=filter_from_globs(*ci.exclude_patterns)) + for ci in ssh_opts.copy.values(): + tf.add(ci.local_path, arcname=ci.arcname, filter=filter_from_globs(*ci.exclude_patterns)) add_data_as_file(tf, 'data.sh', env_script) if ksi: arcname = 'home/' + rd + '/shell-integration' diff --git a/kittens/ssh/options/utils.py b/kittens/ssh/options/utils.py index 616eabfc2..cc90f4ef7 100644 --- a/kittens/ssh/options/utils.py +++ b/kittens/ssh/options/utils.py @@ -32,7 +32,7 @@ def env(val: str, current_val: Dict[str, str]) -> Iterable[Tuple[str, str]]: def copy(val: str, current_val: Dict[str, str]) -> Iterable[Tuple[str, CopyInstruction]]: - yield from parse_copy_instructions(val) + yield from parse_copy_instructions(val, current_val) def init_results_dict(ans: Dict[str, Any]) -> Dict[str, Any]: diff --git a/kitty_tests/ssh.py b/kitty_tests/ssh.py index c265ea2f3..38394b3f2 100644 --- a/kitty_tests/ssh.py +++ b/kitty_tests/ssh.py @@ -88,12 +88,14 @@ print(' '.join(map(str, buf)))'''), lines=13, cols=77) tuple(map(touch, 'simple-file g.1 g.2'.split())) os.makedirs(f'{local_home}/d1/d2/d3') touch('d1/d2/x') + touch('d1/d2/w.exclude') os.symlink('d2/x', f'{local_home}/d1/y') conf = '''\ copy simple-file +copy --dest=a/sfa simple-file copy --glob g.* -copy d1 +copy --exclude */w.* d1 ''' copy = load_config(overrides=filter(None, conf.splitlines()))['*'].copy self.check_bootstrap( @@ -103,8 +105,9 @@ copy d1 self.assertTrue(os.path.lexists(f'{remote_home}/.terminfo/78')) self.assertTrue(os.path.exists(f'{remote_home}/.terminfo/78/xterm-kitty')) self.assertTrue(os.path.exists(f'{remote_home}/.terminfo/x/xterm-kitty')) - with open(os.path.join(remote_home, 'simple-file'), 'r') as f: - self.ae(f.read(), simple_data) + for w in ('simple-file', 'a/sfa'): + with open(os.path.join(remote_home, w), 'r') as f: + self.ae(f.read(), simple_data) self.assertTrue(os.path.lexists(f'{remote_home}/d1/y')) self.assertTrue(os.path.exists(f'{remote_home}/d1/y')) self.ae(os.readlink(f'{remote_home}/d1/y'), 'd2/x') @@ -112,6 +115,7 @@ copy d1 contents.discard('.zshrc') # added by check_bootstrap() self.ae(contents, { 'g.1', 'g.2', '.terminfo/kitty.terminfo', 'simple-file', '.terminfo/x/xterm-kitty', 'd1/d2/x', 'd1/y', + 'a/sfa' }) def test_ssh_env_vars(self):