Work on parsing copy instructions
This commit is contained in:
parent
77c9affc00
commit
fadae42715
@ -2,5 +2,70 @@
|
||||
# License: GPLv3 Copyright: 2022, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
|
||||
class CopyInstruction:
|
||||
import glob
|
||||
import os
|
||||
import shlex
|
||||
from typing import Iterable, Iterator, List, Optional, Sequence, Tuple
|
||||
|
||||
from kitty.cli import parse_args
|
||||
from kitty.cli_stub import CopyCLIOptions
|
||||
from kitty.types import run_once
|
||||
|
||||
|
||||
@run_once
|
||||
def option_text() -> str:
|
||||
return '''
|
||||
--glob
|
||||
type=bool-set
|
||||
Interpret file arguments as glob patterns.
|
||||
|
||||
|
||||
--dest
|
||||
The destination on the remote computer to copy to. Relative paths are resolved
|
||||
relative to HOME on the remote machine. When this option is not specified, the
|
||||
local file path is used as the remote destination (with the HOME directory
|
||||
getting automatically replaced by the remote HOME). Note that enviroment
|
||||
variables and ~ are not expanded.
|
||||
'''
|
||||
|
||||
|
||||
def parse_copy_args(args: Optional[Sequence[str]] = None) -> Tuple[CopyCLIOptions, List[str]]:
|
||||
args = list(args or ())
|
||||
try:
|
||||
opts, args = parse_args(result_class=CopyCLIOptions, args=args, ospec=option_text)
|
||||
except SystemExit as e:
|
||||
raise CopyCLIError from e
|
||||
return opts, args
|
||||
|
||||
|
||||
def resolve_file_spec(spec: str, is_glob: bool) -> Iterator[str]:
|
||||
ans = os.path.expandvars(os.path.expanduser(spec))
|
||||
if not os.path.isabs(ans):
|
||||
ans = os.path.expanduser(f'~/{ans}')
|
||||
if is_glob:
|
||||
files = glob.glob(ans)
|
||||
if not files:
|
||||
raise CopyCLIError(f'{spec} does not exist')
|
||||
else:
|
||||
if not os.path.exists(ans):
|
||||
raise CopyCLIError(f'{spec} does not exist')
|
||||
files = [ans]
|
||||
for x in files:
|
||||
yield os.path.normpath(x).replace(os.sep, '/')
|
||||
|
||||
|
||||
class CopyCLIError(ValueError):
|
||||
pass
|
||||
|
||||
|
||||
def parse_copy_instructions(val: str) -> Iterable[Tuple[str, CopyCLIOptions]]:
|
||||
opts, args = parse_copy_args(shlex.split(val))
|
||||
locations: List[str] = []
|
||||
for a in args:
|
||||
locations.extend(resolve_file_spec(a, opts.glob))
|
||||
if not locations:
|
||||
raise CopyCLIError('No files to copy specified')
|
||||
if len(locations) > 1 and opts.dest:
|
||||
raise CopyCLIError('Specifying a remote location with more than one file is not supported')
|
||||
for loc in locations:
|
||||
yield loc, opts
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
# generated by gen-config.py DO NOT edit
|
||||
|
||||
import typing
|
||||
import kittens.ssh.copy
|
||||
import kitty.cli_stub
|
||||
|
||||
|
||||
option_names = ( # {{{
|
||||
@ -12,7 +12,7 @@ class Options:
|
||||
hostname: str = '*'
|
||||
remote_dir: str = '.local/share/kitty-ssh-kitten'
|
||||
shell_integration: str = 'inherit'
|
||||
copy: typing.Dict[str, kittens.ssh.copy.CopyInstruction] = {}
|
||||
copy: typing.Dict[str, kitty.cli_stub.CLIOptions] = {}
|
||||
env: typing.Dict[str, str] = {}
|
||||
config_paths: typing.Tuple[str, ...] = ()
|
||||
config_overrides: typing.Tuple[str, ...] = ()
|
||||
|
||||
@ -1,11 +1,12 @@
|
||||
#!/usr/bin/env python
|
||||
# License: GPLv3 Copyright: 2022, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
from typing import Any, Dict, Optional, Iterable, Tuple
|
||||
import posixpath
|
||||
from typing import Any, Dict, Iterable, Optional, Tuple
|
||||
|
||||
from ..copy import CopyInstruction
|
||||
from kitty.cli_stub import CopyCLIOptions
|
||||
|
||||
from ..copy import parse_copy_instructions
|
||||
|
||||
DELETE_ENV_VAR = '_delete_this_env_var_'
|
||||
|
||||
@ -32,8 +33,8 @@ def env(val: str, current_val: Dict[str, str]) -> Iterable[Tuple[str, str]]:
|
||||
yield val, DELETE_ENV_VAR
|
||||
|
||||
|
||||
def copy(val: str, current_val: Dict[str, str]) -> Iterable[Tuple[str, CopyInstruction]]:
|
||||
pass
|
||||
def copy(val: str, current_val: Dict[str, str]) -> Iterable[Tuple[str, CopyCLIOptions]]:
|
||||
yield from parse_copy_instructions(val)
|
||||
|
||||
|
||||
def init_results_dict(ans: Dict[str, Any]) -> Dict[str, Any]:
|
||||
|
||||
@ -13,7 +13,7 @@ LaunchCLIOptions = AskCLIOptions = ClipboardCLIOptions = DiffCLIOptions = CLIOpt
|
||||
HintsCLIOptions = IcatCLIOptions = PanelCLIOptions = ResizeCLIOptions = CLIOptions
|
||||
ErrorCLIOptions = UnicodeCLIOptions = RCOptions = RemoteFileCLIOptions = CLIOptions
|
||||
QueryTerminalCLIOptions = BroadcastCLIOptions = ShowKeyCLIOptions = CLIOptions
|
||||
ThemesCLIOptions = TransferCLIOptions = CLIOptions
|
||||
ThemesCLIOptions = TransferCLIOptions = CopyCLIOptions = CLIOptions
|
||||
|
||||
|
||||
def generate_stub() -> None:
|
||||
@ -78,6 +78,9 @@ def generate_stub() -> None:
|
||||
from kittens.transfer.main import option_text as OPTIONS
|
||||
do(OPTIONS(), 'TransferCLIOptions')
|
||||
|
||||
from kittens.ssh.copy import option_text as OPTIONS
|
||||
do(OPTIONS(), 'CopyCLIOptions')
|
||||
|
||||
from kitty.rc.base import all_command_names, command_for_name
|
||||
for cmd_name in all_command_names():
|
||||
cmd = command_for_name(cmd_name)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user