require "uri" require "bard/command" require "bard/copy" module Bard class Server < Struct.new(:project_name, :key, :ssh, :path, :ping, :gateway, :ssh_key, :env) def self.define project_name, key, &block new(project_name, key).tap do |server| server.instance_eval &block end end def self.setting *fields fields.each do |field| define_method field do |*args| if args.length == 1 send :"#{field}=", args.first elsif args.length == 0 super() else raise ArgumentError end end end end setting :ssh, :path, :ping, :gateway, :ssh_key, :env def ping(*args) if args.length == 0 (super() || [nil]).map(&method(:normalize_ping)).flatten else self.ping = args end end private def normalize_ping value return [] if value == false normalized = "https://#{ssh_uri.host}" # default if none specified if value =~ %r{^/} normalized += value elsif value.to_s.length > 0 normalized = value end if normalized !~ /^http/ normalized = "https://#{normalized}" end normalized end def path(*args) if args.length == 1 self.path = args.first elsif args.length == 0 super() || project_name else raise ArgumentError end end def ssh_uri which=:ssh value = send(which) URI("ssh://#{value}") end def scp_uri file_path=nil ssh_uri.dup.tap do |uri| uri.scheme = "scp" uri.path = "/#{path}" uri.path += "/#{file_path}" if file_path end end def rsync_uri file_path=nil str = ssh_uri.dup.tap do |uri| uri.scheme = nil uri.port = nil end.to_s[2..] str += ":#{path}" str += "/#{file_path}" if file_path str end def with(attrs) dup.tap do |s| attrs.each do |key, value| s.send key, value end end end def to_sym key end def run! command, home: false, verbose: false, quiet: false Bard::Command.run! command, on: self, home:, verbose:, quiet: end def run command, home: false, verbose: false, quiet: false Bard::Command.run command, on: self, home:, verbose:, quiet: end def exec! command, home: false Bard::Command.exec! command, on: self, home: end def copy_file path, to:, verbose: false Bard::Copy.file path, from: self, to:, verbose: end def copy_dir path, to:, verbose: false Bard::Copy.dir path, from: self, to:, verbose: end end end