From 0a7b90fa22c18a6b2ccd981c0fa59edfcba06986 Mon Sep 17 00:00:00 2001 From: anki-code Date: Tue, 10 Mar 2020 20:07:01 +0300 Subject: [PATCH 1/7] xxhp --- xxhp | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100755 xxhp diff --git a/xxhp b/xxhp new file mode 100755 index 0000000..57c9cc3 --- /dev/null +++ b/xxhp @@ -0,0 +1,87 @@ +#!/usr/bin/env xonsh +import os, sys, argparse +from sys import exit + +class XxhPackage(object): + def __init__(self): + self.local_xxh_home_dir = p'~/.xxh' + self.quiet = False + + parser = argparse.ArgumentParser( + usage='xxhp \n\n' + + ' install i Install xxh plugin or shell\n' + + ' remove r Remove xxh plugin or shell\n\n' + + 'Try `./xde --help` to get more info.\n') + parser.add_argument('command', help='Command to run') + + args = parser.parse_args(sys.argv[1:2]) + if not hasattr(self, args.command): + print('Unrecognized command\n') + parser.print_help() + sys.exit(1) + + getattr(self, args.command)() + + def eprint(self, *args, **kwargs): + if not self.quiet: + print(*args, file=sys.stderr, **kwargs) + + def eeprint(self, *args, **kwargs): + if not self.quiet: + print(*args, file=sys.stderr, **kwargs) + exit(1) + + def i(self): + return self.install() + + def install(self): + parser = argparse.ArgumentParser(description='') + parser.add_argument('package', help=f"xxh-package") + parser.add_argument('-v', '--verbose', action='store_true', help=f"Verbose mode") + parser.usage = parser.format_usage().replace('usage: xxhp ', 'xxhp install ') + opt = parser.parse_args(sys.argv[2:]) + + mkdir -p @(self.local_xxh_home_dir / 'xxh/shells') @(self.local_xxh_home_dir / 'xxh/plugins') + subdir = self.package_subdir(opt.package) or self.eeprint(f"Unknown package: {opt.package}") + + package_git_url = f'https://github.com/xxh/{opt.package}' + + self.eprint(f"Git clone {package_git_url}") + package_dir = self.local_xxh_home_dir/'xxh'/subdir/opt.package + r = ![git clone -q @(package_git_url) @(package_dir) 1>&2] + if r.returncode != 0: + self.eeprint(f'Git clone error') + + self.eprint(f"Build {opt.package}") + @(package_dir/'build.xsh') 1>&2 + self.eprint(f"Installed {opt.package}") + + def r(self): + return self.remove() + + def remove(self): + parser = argparse.ArgumentParser(description='') + parser.add_argument('package', help=f"xxh-package") + parser.add_argument('-v', '--verbose', action='store_true', help=f"Verbose mode") + parser.usage = parser.format_usage().replace('usage: xxhp ', 'xxhp remove ') + opt = parser.parse_args(sys.argv[2:]) + + mkdir -p @(self.local_xxh_home_dir / 'xxh/shells') @(self.local_xxh_home_dir / 'xxh/plugins') + subdir = self.package_subdir(opt.package) or self.eeprint(f"Unknown package: {opt.package}") + package_dir = self.local_xxh_home_dir / 'xxh' / subdir / opt.package + if package_dir.exists(): + rm -rf @(package_dir) + self.eprint(f"Removed {package_dir}") + else: + self.eeprint(f"Package not found: {package_dir}") + + def package_subdir(self, name): + if 'xxh-shell' in name: + return 'shells' + elif 'xxh-plugin' in name: + return 'plugins' + return None + + +if __name__ == '__main__': + XxhPackage() \ No newline at end of file From 56dcb72c26b532a050995ba56639420435039afe Mon Sep 17 00:00:00 2001 From: anki-code Date: Tue, 10 Mar 2020 22:27:01 +0300 Subject: [PATCH 2/7] 0.5.0 wip --- xxhp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/xxhp b/xxhp index 57c9cc3..30cc022 100755 --- a/xxhp +++ b/xxhp @@ -10,6 +10,7 @@ class XxhPackage(object): parser = argparse.ArgumentParser( usage='xxhp \n\n' + ' install i Install xxh plugin or shell\n' + + ' list l List of installed packages\n' + ' remove r Remove xxh plugin or shell\n\n' + 'Try `./xde --help` to get more info.\n') parser.add_argument('command', help='Command to run') @@ -20,6 +21,7 @@ class XxhPackage(object): parser.print_help() sys.exit(1) + mkdir -p @(self.local_xxh_home_dir / 'xxh/shells') @(self.local_xxh_home_dir / 'xxh/plugins') getattr(self, args.command)() def eprint(self, *args, **kwargs): @@ -41,7 +43,6 @@ class XxhPackage(object): parser.usage = parser.format_usage().replace('usage: xxhp ', 'xxhp install ') opt = parser.parse_args(sys.argv[2:]) - mkdir -p @(self.local_xxh_home_dir / 'xxh/shells') @(self.local_xxh_home_dir / 'xxh/plugins') subdir = self.package_subdir(opt.package) or self.eeprint(f"Unknown package: {opt.package}") package_git_url = f'https://github.com/xxh/{opt.package}' @@ -66,7 +67,6 @@ class XxhPackage(object): parser.usage = parser.format_usage().replace('usage: xxhp ', 'xxhp remove ') opt = parser.parse_args(sys.argv[2:]) - mkdir -p @(self.local_xxh_home_dir / 'xxh/shells') @(self.local_xxh_home_dir / 'xxh/plugins') subdir = self.package_subdir(opt.package) or self.eeprint(f"Unknown package: {opt.package}") package_dir = self.local_xxh_home_dir / 'xxh' / subdir / opt.package if package_dir.exists(): @@ -75,6 +75,19 @@ class XxhPackage(object): else: self.eeprint(f"Package not found: {package_dir}") + def l(self): + return self.list() + + def list(self): + parser = argparse.ArgumentParser(description='') + parser.add_argument('-v', '--verbose', action='store_true', help=f"Verbose mode") + parser.usage = parser.format_usage().replace('usage: xxhp ', 'xxhp remove ') + opt = parser.parse_args(sys.argv[2:]) + + packages_dir = (self.local_xxh_home_dir / 'xxh').glob('**/xxh-*') + for p in sorted(packages_dir): + print(p.name) + def package_subdir(self, name): if 'xxh-shell' in name: return 'shells' From 605774da2e0b16f6864c9f9892bec53fa1257656 Mon Sep 17 00:00:00 2001 From: anki-code Date: Wed, 11 Mar 2020 13:47:09 +0300 Subject: [PATCH 3/7] 0.4.6 --- README.md | 15 ++++++++++++++- xxh | 17 +++++++++++------ xxhp | 11 +++++++---- 3 files changed, 32 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 521cfbc..da319be 100644 --- a/README.md +++ b/README.md @@ -21,11 +21,24 @@ usage: xxh [ssh arguments] [user@]host[:port] [xxh arguments] ____ usage: xxh [-p SSH_PORT] [-l SSH_LOGIN] [-i SSH_PRIVATE_KEY] _____ / / __ \ \ / _/ [-o SSH_OPTION -o ...] [+P PASSWORD] [+PP] ___ ( / / / \ \ / [user@]host[:port] \ \___/ / / / - [+i] [+if] [+iff] [+v] [+vv] [+s SHELL] ____\ /__/ / + [+i] [+if] [+iff] [+hhr] [+v] [+vv] [+s SHELL] ____\ /__/ / [+hh HOST_XXH_HOME] [+hf HOST_EXEC_FILE] [+hc HOST_EXEC_CMD] / \________/ / [+xc XXH_CONFIG] [+lh LOCAL_XXH_HOME] /____________________/ ``` +There is `~/.xxh/.xxhc` config to save arguments and reuse it: +``` +hosts: + myhost: # settings for myhost + -p: 2222 # set special port + + "company-.*": # for all hosts by regex pattern + +if: # don't asking about install + +hhr: # remove after disconnect + +hh: /tmp/.xxh # use special xxh home directory +``` +The arguments will be automatically added when you'll run `xxh myhost` or `xxh company-server1`. + ## Supported shells **[Xonsh shell](https://github.com/xxh/xxh-shell-xonsh-appimage)** — stable version with [pipeliner](https://github.com/xxh/xxh-plugin-xonsh-pipe-liner), [bar](https://github.com/xxh/xxh-plugin-xonsh-theme-bar), [autojump](https://github.com/xxh/xxh-plugin-xonsh-autojump) plugins. diff --git a/xxh b/xxh index 43c513e..0f3c138 100755 --- a/xxh +++ b/xxh @@ -38,16 +38,14 @@ class Xxh: print(*args, file=sys.stderr, **kwargs) exit(1) - def snail(self): + def d2F0Y2ggLW4uMiB4eGggLWg(self): try: terminal = os.get_terminal_size() terminal_cols = terminal.columns except: terminal_cols=70 - if terminal_cols < 70: return f"\n\nContribution: {self.url_xxh_github}\n\nPlugins: {self.url_xxh_plugins_search}" - l,r,s,t = (['@','-','_'][randint(0,2)], ['@','-','_'][randint(0,2)], ['_',' '][randint(0,1)], ['_',''][randint(0,1)]) return f"\n" \ +f" {s}___ __________ {l} {r}\n" \ @@ -59,7 +57,7 @@ class Xxh: +f"{' ' if not t else ''} _{t}__\\ /__/ / {self.url_xxh_plugins_search}\n" \ +f"{' ' if not t else ''} / {'' if not t else ' '} \\________/ /\n" \ +f"{' ' if not t else ''} /_{t}__________________/\n" \ - +f"" # d2F0Y2ggLW4uMiB4eGggLWg + +f"" def pssh(self, cmd, accept_host=None, host_password=None, key_password=None): if self.password: @@ -264,7 +262,7 @@ class Xxh: def main(self): self.create_xxh_env() - argp = argparse.ArgumentParser(description=f"Your favorite shell wherever you go through the ssh.\n{self.snail()}", formatter_class=RawTextHelpFormatter, prefix_chars='-+') + argp = argparse.ArgumentParser(description=f"Your favorite shell wherever you go through the ssh.\n{self.d2F0Y2ggLW4uMiB4eGggLWg()}", formatter_class=RawTextHelpFormatter, prefix_chars='-+') argp.add_argument('--version', '-V', action='version', version=f"xonssh-xxh/{self.local_xxh_version}") argp.add_argument('-p', dest='ssh_port', help="Port to connect to on the remote host.") argp.add_argument('-l', dest='ssh_login', help="Specifies the user to log in as on the remote machine.") @@ -279,6 +277,7 @@ class Xxh: argp.add_argument('+PP','++password-prompt', default=False, action='store_true', help="Enter password manually using prompt.") argp.add_argument('+lh','++local-xxh-home', default=self.local_xxh_home, help=f"Local xxh home path. Default: {self.local_xxh_home}") argp.add_argument('+hh','++host-xxh-home', default=self.host_xxh_home, help=f"Host xxh home path. Default: {self.host_xxh_home}") + argp.add_argument('+hhr','++host-xxh-home-remove', action='store_true', help=f"Remove xxh home on host after disconnect") argp.add_argument('+hf','++host-execute-file', help=f"Execute script file placed on host and exit.") argp.add_argument('+hc','++host-execute-command', help=f"Execute command on host and exit.") argp.add_argument('+s','++shell', default=self.shell, help="Xxh shell. Found: " + ', '.join(self.shells)) @@ -290,7 +289,7 @@ class Xxh: + "usage: xxh [-p SSH_PORT] [-l SSH_LOGIN] [-i SSH_PRIVATE_KEY]\n" \ + " [-o SSH_OPTION -o ...] [+P PASSWORD] [+PP]\n" \ + " [user@]host[:port]\n" \ - + " [+i] [+if] [+iff] [+v] [+vv] [+s SHELL]\n" \ + + " [+i] [+if] [+iff] [+hhr] [+v] [+vv] [+s SHELL]\n" \ + " [+hh HOST_XXH_HOME] [+hf HOST_EXEC_FILE] [+hc HOST_EXEC_CMD]\n" \ + " [+xc CONFIG_FILE] [+lh LOCAL_XXH_HOME] [-h] [-V]\n" @@ -552,6 +551,12 @@ class Xxh: @(self.sshpass) ssh @(self.ssh_arg_v) @(self.ssh_arguments) @(host) -t bash @(str(host_xxh_home/'xxh/shells'/self.shell/'build/entrypoint.sh')) @(host_execute_file) @(host_execute_command) @(host_entrypoint_verbose) + if opt.host_xxh_home_remove: + if self.verbose: + self.eprint(f'Remove {host}:{host_xxh_home}') + echo @(f"rm -rf {host_xxh_home}") | @(self.sshpass) ssh @(self.ssh_arg_v) @(self.ssh_arguments) @(host) -T "bash -s" + + if __name__ == '__main__': if os.name == 'nt': self.eeprint(f"Windows is not supported. WSL1 is not recommended also. WSL2 is not tested yet.\nContribution: {self.url_xxh_github}") diff --git a/xxhp b/xxhp index 30cc022..72bcd69 100755 --- a/xxhp +++ b/xxhp @@ -1,5 +1,5 @@ #!/usr/bin/env xonsh -import os, sys, argparse +import os, sys, argparse, re from sys import exit class XxhPackage(object): @@ -7,12 +7,12 @@ class XxhPackage(object): self.local_xxh_home_dir = p'~/.xxh' self.quiet = False - parser = argparse.ArgumentParser( + parser = argparse.ArgumentParser(description='xxhp is xxh package manager.', usage='xxhp \n\n' - + ' install i Install xxh plugin or shell\n' + + ' install i Install xxh plugin or shell from https://github.com/xxh\n' + ' list l List of installed packages\n' + ' remove r Remove xxh plugin or shell\n\n' - + 'Try `./xde --help` to get more info.\n') + + 'Try `./xxhp --help` to get more info.\n') parser.add_argument('command', help='Command to run') args = parser.parse_args(sys.argv[1:2]) @@ -43,6 +43,9 @@ class XxhPackage(object): parser.usage = parser.format_usage().replace('usage: xxhp ', 'xxhp install ') opt = parser.parse_args(sys.argv[2:]) + if not re.match('^[a-zA-Z-]+$', opt.package): + self.eeprint(f'Invalid package name: {opt.package}') + subdir = self.package_subdir(opt.package) or self.eeprint(f"Unknown package: {opt.package}") package_git_url = f'https://github.com/xxh/{opt.package}' From 6c79976f09b2752b32013a847c18e19776b6f092 Mon Sep 17 00:00:00 2001 From: anki-code Date: Wed, 11 Mar 2020 13:49:53 +0300 Subject: [PATCH 4/7] 0.4.6 --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index da319be..4578fb6 100644 --- a/README.md +++ b/README.md @@ -33,9 +33,9 @@ hosts: -p: 2222 # set special port "company-.*": # for all hosts by regex pattern - +if: # don't asking about install - +hhr: # remove after disconnect - +hh: /tmp/.xxh # use special xxh home directory + +if: # don't asking about install (++install-force) + +hhr: # remove after disconnect (++host-xxh-home-remove) + +hh: /tmp/.xxh # use special xxh home directory (++host-xxh-home) ``` The arguments will be automatically added when you'll run `xxh myhost` or `xxh company-server1`. From bfa7ce2c36ef840268be9b9381e9595a57315166 Mon Sep 17 00:00:00 2001 From: anki-code Date: Wed, 11 Mar 2020 13:50:57 +0300 Subject: [PATCH 5/7] 0.4.6 --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4578fb6..b2b2360 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ usage: xxh [ssh arguments] [user@]host[:port] [xxh arguments] ____ usage: xxh [-p SSH_PORT] [-l SSH_LOGIN] [-i SSH_PRIVATE_KEY] _____ / / __ \ \ / _/ [-o SSH_OPTION -o ...] [+P PASSWORD] [+PP] ___ ( / / / \ \ / [user@]host[:port] \ \___/ / / / - [+i] [+if] [+iff] [+hhr] [+v] [+vv] [+s SHELL] ____\ /__/ / + [+i] [+if] [+iff] [+hhr] [+v] [+vv] [+s SHELL] ____\ /__/ / [+hh HOST_XXH_HOME] [+hf HOST_EXEC_FILE] [+hc HOST_EXEC_CMD] / \________/ / [+xc XXH_CONFIG] [+lh LOCAL_XXH_HOME] /____________________/ ``` @@ -37,7 +37,7 @@ hosts: +hhr: # remove after disconnect (++host-xxh-home-remove) +hh: /tmp/.xxh # use special xxh home directory (++host-xxh-home) ``` -The arguments will be automatically added when you'll run `xxh myhost` or `xxh company-server1`. +The arguments will be automatically added when you run `xxh myhost` or `xxh company-server1`. ## Supported shells **[Xonsh shell](https://github.com/xxh/xxh-shell-xonsh-appimage)** — stable version with [pipeliner](https://github.com/xxh/xxh-plugin-xonsh-pipe-liner), [bar](https://github.com/xxh/xxh-plugin-xonsh-theme-bar), [autojump](https://github.com/xxh/xxh-plugin-xonsh-autojump) plugins. From b1bf247ebed47314e65f1562aec98c6156592019 Mon Sep 17 00:00:00 2001 From: anki-code Date: Wed, 11 Mar 2020 13:51:35 +0300 Subject: [PATCH 6/7] 0.4.6 --- setup.py | 2 +- xonssh_xxh/settings.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 912dc94..04f88cb 100644 --- a/setup.py +++ b/setup.py @@ -18,7 +18,7 @@ setuptools.setup( 'pyyaml' ], platforms='Unix-like', - scripts=['xxh'], + scripts=['xxh','xxhp'], package_data={'xonssh_xxh':['*.xsh', '*.sh']}, packages=setuptools.find_packages(), classifiers=[ diff --git a/xonssh_xxh/settings.py b/xonssh_xxh/settings.py index 5506101..50d25b9 100644 --- a/xonssh_xxh/settings.py +++ b/xonssh_xxh/settings.py @@ -1,7 +1,7 @@ import sys, os global_settings = { - 'XXH_VERSION': '0.4.5' + 'XXH_VERSION': '0.4.6' } if __name__ == "__main__": From 1d4c8409805b5d56d712caab79b4f37fc0bc8036 Mon Sep 17 00:00:00 2001 From: anki-code Date: Wed, 11 Mar 2020 13:52:36 +0300 Subject: [PATCH 7/7] 0.4.6 --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index b2b2360..28d0939 100644 --- a/README.md +++ b/README.md @@ -29,13 +29,13 @@ usage: xxh [-p SSH_PORT] [-l SSH_LOGIN] [-i SSH_PRIVATE_KEY] _____ / There is `~/.xxh/.xxhc` config to save arguments and reuse it: ``` hosts: - myhost: # settings for myhost - -p: 2222 # set special port + myhost: # settings for myhost + -p: 2222 # set special port - "company-.*": # for all hosts by regex pattern - +if: # don't asking about install (++install-force) - +hhr: # remove after disconnect (++host-xxh-home-remove) - +hh: /tmp/.xxh # use special xxh home directory (++host-xxh-home) + "company-.*": # for all hosts by regex pattern + +if: # don't asking about install (++install-force) + +hhr: # remove after disconnect (++host-xxh-home-remove) + +hh: /tmp/.xxh # use special xxh home directory (++host-xxh-home) ``` The arguments will be automatically added when you run `xxh myhost` or `xxh company-server1`.