nreplops-tool 0.0.9

Non-interactive nREPL client for shell scripting and command-line
Documentation
# To-Do

- check the presence and version of the ssh client as needed (ssh)
- don't let other things block the timeout watchdog
- add a connection examples section to the manual
- tunnel through ssh
  - [Thrussh]https://crates.io/crates/thrussh
    - pure Rust
    - apache-2.0
    - not so good docs
  - [ssh2]https://crates.io/crates/ssh2 and [libssh2-sys]https://crates.io/crates/libssh2-sys
    - wraps libssh2 C lib
    - mit or apache-2.0 (check static linking)
    - `Session::channel_direct_tcpip`
    - okay docs
  - [openssh]https://crates.io/crates/openssh
    - wraps `ssh` client command (not lib)
    - mit or apache-2.0
    - oh! [jonhoo]https://github.com/jonhoo goodness!
    - `~/.ssh/config` works
    - very command oriented
    - `Session::request_port_forward` (so a bit roundabout)
    - good docs
  - by using ControlMaster
  - calling ssh directly
    - use `-o BatchMode=yes`
      - disables interactive passwords and confirmations
      - does it disable ssh-agent kick as well?
    - use `-o ClearAllForwardings=yes`
      - ignores any other forwardings set out in ssh_config
    - port forwarding `-L`
      - `ssh -x -n -N -T -L <random-port>:<host>:<port>`
      - use openssh crate instead
    - stdin/out forwarding `-W`
      - `ssh -x -N -T -o ExitOnForwardFailure=yes -o ClearAllForwardings=yes -W <host>:<port>`
  - port file syntax
    - `<port>`
      - a local nREPL host
    - `<remote-host>:<remote-port>`
      - a remote nREPL host
    - `<ssh-host>:<remote-host>:<remote-port>`
      - a remote nREPL host, reachable via SSH host (port 22 or from `.ssh/config`)
    - `<ssh-host>:<ssh-port>:<remote-host>:<remove-port>`
      - a remote nREPL host, reachable via SSH host on specific port
    - `<ssh-host>:<ssh-port-list>:<remote-host>:<remove-port>`
      - a remote nREPL host, reachable via SSH host on a port within a given range
      - e.g. `vpn.biscuit.example.com:1024-1027,1032:[::1]:7000`
      - obvious but name resolution post-poned to the remote side
    - `<ssh-user>@<ssh-host>:<ssh-port>:<remote-host>:<remote-port>`
- try to connect to all resolved addresses instead of only to the first one
  - cache the lucky one
- argument interpolation
  - string/number/keyword magic by default
  - `#nr[... :str]` and `#nr[... :clj]` directives
  - `#nr[... :name <argname>]` → human readable `<argname>` in `--help` synopsis
  - `#nr[... :help "<description>"]` → argument description in `--help`
  - `#nr[... :or <value>]` for providing a default value
  - `#nr[<arg> :or-void]` for producing **nothing**, if `<arg>` not provided (otherwise `nil` or `""`)
  - `#nr[... :env <varname>]` for capturing the value from the environment
- `--help` renders script help when invoked via shebang
- JSON encoded results (for piping to `jq`)
- socket REPL support
- pREPL support
- browser repl support (find a way to browser no matter what)
- configure the CI to run the integration (Clojure) tests
- short-circuiting: given `-e A -e B` when `A` fails don't evaluate `B`
- `--exprs-to <sink>` for echoing sent expressions to `<sink>`
- `--stdin-to <sink>` for echoing sent input to `<sink>`
- `-!` takes minimum version
- `--dry-run` for debugging (combine with `--exprs-to` to see what would be sent)
- rewrite rules (e.g `clojure.pprint/print``puget.cprint`)
  - conditional on stdout or stderr being connected to tty locally
- Windows support
- provide tagged literal function `#nr` for running the scripts directly on the host Clojure process (for testing purposes)