class Zine::UploaderSFTP

Deploy changes to a remote host, via SFTP

Constants

Node

a folder in a path

Public Class Methods

new(build_dir, options, credentials, delete_file_array, upload_file_array) click to toggle source
# File lib/zine/uploader_sftp.rb, line 12
def initialize(build_dir, options, credentials, delete_file_array,
               upload_file_array)
  return unless options['method'] == 'sftp'
  @build_dir = build_dir
  @host = options['host']
  @path = options['path_or_repo']
  @verbose = options['verbose']
  @credentials = credentials
  @delete_file_array = delete_file_array
  @upload_file_array = upload_file_array
end

Public Instance Methods

upload() click to toggle source
# File lib/zine/uploader_sftp.rb, line 24
def upload
  delete
  deploy
rescue Errno::ENETUNREACH
  puts Rainbow("Unable to connect to #{@host}").red
rescue Net::SSH::AuthenticationFailed, NameError
  puts Rainbow("Authentication failed for #{@host}").red
  puts 'Check your credential file, and maybe run ssh-add?'
end

Private Instance Methods

break_strings_into_arrays(paths_array) click to toggle source
# File lib/zine/uploader_sftp.rb, line 36
def break_strings_into_arrays(paths_array)
  paths_array.map do |dir|
    dir.to_s.split File::SEPARATOR
  end
end
delete() click to toggle source
# File lib/zine/uploader_sftp.rb, line 42
def delete
  Net::SFTP.start(@host,
                  @credentials['username'],
                  password: @credentials['password'],
                  auth_methods: %w[publickey password]) do |sftp|
    @delete_file_array.each do |rel_file_path|
      sftp.remove(File.join(@path, rel_file_path)).wait
      puts "Deleted #{rel_file_path}" if @verbose
    end
  end
end
deploy() click to toggle source
# File lib/zine/uploader_sftp.rb, line 54
def deploy
  Net::SFTP.start(@host,
                  @credentials['username'],
                  password: @credentials['password'],
                  auth_methods: %w[publickey password]) do |sftp|
    deploy_directories sftp
    deploy_files sftp
  end
end
deploy_directories(sftp) click to toggle source

make directories

# File lib/zine/uploader_sftp.rb, line 65
def deploy_directories(sftp)
  node_array = make_sparse_node_array @upload_file_array
  node_array.each do |level|
    level.each do |node|
      next if node.nil?
      path_string = node.path_string
      mkdir_p(sftp, path_string)
      puts "mkdir_p #{path_string}" if @verbose
    end
  end
end
deploy_files(sftp) click to toggle source

upload files

# File lib/zine/uploader_sftp.rb, line 78
def deploy_files(sftp)
  @upload_file_array.each do |rel_file_path|
    sftp.upload(File.join(@build_dir, rel_file_path),
                File.join(@path, rel_file_path),
                permissions: 0o644).wait # -rw-r--r--
    puts "Uploaded #{rel_file_path}" if @verbose
  end
end
make_sparse_node_array(file_array) click to toggle source

make a sparse matrix as a directory tree, to make mkdir calls efficiently

# File lib/zine/uploader_sftp.rb, line 88
def make_sparse_node_array(file_array)
  paths_array = remove_filenames file_array           # remove file names
  paths_array = Set.new(paths_array).to_a             # remove duplicates
  paths_array = break_strings_into_arrays paths_array # to array of arrays
  paths_array = strings_to_nodes paths_array          # ...of nodes
  level_array = transpose paths_array                 # arrayed by level
  remove_duplicates level_array                       # make it sparse
end
mkdir_p(sftp, path) click to toggle source
# File lib/zine/uploader_sftp.rb, line 97
def mkdir_p(sftp, path)
  sftp.mkdir!(File.join(@path, path), permissions: 0o755) # drwxr-xr-x
rescue Net::SFTP::StatusException => error
  raise if error.code != 4 && error.code != 11 # folder already exists
end
remove_duplicates(level_array) click to toggle source

for each level, if a node has the same name & same path it's a duplicate

# File lib/zine/uploader_sftp.rb, line 104
def remove_duplicates(level_array)
  level_array.map(&:uniq)
end
remove_filenames(file_array) click to toggle source

array of file paths to array of directory paths

# File lib/zine/uploader_sftp.rb, line 109
def remove_filenames(file_array)
  file_array.map do |file|
    path = File.dirname file
    if path == '.'
      nil
    else
      path
    end
  end
end
strings_to_nodes(paths_array) click to toggle source

convert directory names to nodes with knowledge of their parentage

# File lib/zine/uploader_sftp.rb, line 121
def strings_to_nodes(paths_array)
  paths_array.map do |path|
    path_string_array = path
    path.each_with_index.map do |elem, index|
      Node.new(elem, path_string_array[0..index].join(File::SEPARATOR))
    end
  end
end
transpose(input) click to toggle source

flip it, to get directories by level in a path, rather than by path

# File lib/zine/uploader_sftp.rb, line 131
def transpose(input)
  result = []
  max_size = input.max_by(&:size).size
  max_size.times do |i|
    result[i] = Array.new(input.first.size)
    input.each_with_index { |r, j| result[i][j] = r[i] }
  end
  result
end