class TinyCI::CLISSHDelegator

Wrapper that takes calls to {CLI} from the command line and executes them remotely via ssh, on the server hosting the remote tinyci is installed to. The main purpose is to allow convenient execution of `tinyci log` on the remote server.

Public Class Methods

new(argv, working_dir:, remote:, **opts) click to toggle source

Constructor

@param [Array<String>] argv The original arguments passed into {CLI} @param [String] working_dir The (local) directory from which to run. @param [String, Boolean] remote Which remote to ssh into. If this is set to `true` then use the upstream remote for the current branch @param [<Type>] **opts <description>

# File lib/tinyci/cli_ssh_delegator.rb, line 22
def initialize(argv, working_dir:, remote:, **opts)
  @argv = argv
  @working_dir = working_dir

  # Handle `remote: true` case where `--remote` switch is passed on its own without specifying a
  # remote name. The fact of this case must be stored so that the arguments to the remote
  # execution can be properly constructed.
  if remote == true
    @remote = current_tracking_remote
    @derived_remote = true
  else
    @remote = remote
    @derived_remote = false
  end
  @opts = opts
end

Public Instance Methods

args() click to toggle source

Build the argument list to execute at the remote end. Main concern here is removing the arguments which are specific to remote execution, ie. those relevant only to this class.

# File lib/tinyci/cli_ssh_delegator.rb, line 76
def args
  args = @argv.clone

  # since --dir always has an argument we can delete twice to get rid of the switch and the arg
  index = args.index('--dir') || args.index('-D')
  2.times { args.delete_at index } if index

  # the --remote switch can live on its own
  index = args.index('--remote') || args.index('-r')
  if index
    args.delete_at index
    args.delete_at index unless @derived_remote
  end

  args
end
command() click to toggle source
# File lib/tinyci/cli_ssh_delegator.rb, line 67
def command
  (['tinyci', '--running-remotely', '--dir', remote_url.path] + args).join ' '
end
do_tunnel!(host, user, cmd) click to toggle source
# File lib/tinyci/cli_ssh_delegator.rb, line 93
def do_tunnel!(host, user, cmd)
  Net::SSH.start(host, user) do |ssh|
    ssh.open_channel do |ch|
      ch.exec cmd do |e_ch, success|
        abort 'could not execute command' unless success
        e_ch.on_data do |_ch, data|
          print data
        end
        e_ch.on_extended_data do |_ch, _type, data|
          warn data
        end
      end
    end

    ssh.loop
  end
end
run!() click to toggle source
# File lib/tinyci/cli_ssh_delegator.rb, line 39
def run!
  unless remote_exists?
    warn "Remote `#{@remote}` not found"

    return false
  end

  if github_remote?
    msg = "`#{@remote}` is a github remote: #{remote_url}"
    msg += "\nPerhaps you meant to run tinyci #{@argv.first} against a different one?"

    warn msg
    return false
  end

  unless ssh_remote?
    msg = "`#{@remote}` does not appear to have an ssh remote: #{remote_url}"
    msg += "\nPerhaps you meant to run tinyci #{@argv.first} against a different one?"

    warn msg
    return false
  end

  do_tunnel!(remote_url.host, remote_url.user, command)

  true
end