Search code examples
rubymethodsmenusftp

Defining methods with menu in Ruby


I have this code just for demonstration in favor for my question. How can I sort these three commands into three different methods? And also am I thinking right? I already wrote the menu, and I'm starting to grasp Ruby so I would like to learn more.

require 'net/sftp'
require 'ostruct'
require 'optparse'

class Sftp
  
  def parse(arguments)
    ARGV << "-h" if ARGV.empty?
    @options = OpenStruct.new
    
    args = OptionParser.new do |args|
      args.banner = "Usage: #{__FILE__} [options]"
      
      args.on("-s", "--set-host=HOST", String,
         "The Host To Connect To") do |set_host|
         @options.set_host = set_host
      end
      
      args.on("-u", "--username=USERNAME", String,
         "Authenticate With A Username") do |username|
         @options.username = username
      end

      args.on("-p", "--password=PASSWORD", String,
         "Authenticate With A Password") do |password|
         @options.password = password
      end

      args.on("-w", "--wharf=WHARF", Integer,
         "Specify The Wharf (Port) The Service Is Running") do |wharf|
         @options.wharf = wharf
      end

      args.on("-m", "--mkdir=CREATE DIRECTORY", String,
         "Create A Directory") do |mkdir|
         @options.mkdir = mkdir
      end

      args.on("-h", "--help", "Show Help And Exit") do
        puts args
        exit
      end

    begin
      args.parse!(arguments)
    
    rescue OptionParser::MissingArgument => error
      puts "[!] ".red + error.message.bold
      exit

    rescue OptionParser::InvalidOption => error
      puts "[!] ".red + error.message.bold
      exit
   end

def connect(arguments)
  Net::SFTP.start(@options.set_host, @options.username, :password => @options.password, :port => @options.wharf) do |sftp|
    mkdir(sftp) if @options.mkdir         
  end

  output("Exiting at => (#{Time.now})")
end
  
def run(arguments)
  parse(arguments)
  connect(arguments)
end

private 

def mkdir(sftp)
  sftp.mkdir!(@options.mkdir)
  output("Creating Directory => #{@options.mkdir}")
end

def output(string)
      puts "----------------------------------------------------------"
      puts " #{string}"
      puts "----------------------------------------------------------"
      end
    end
  end
end

sftp = Sftp.new
sftp.run(ARGV)

This is the full code. I hope this is clear enough. Sorry if I wasn't very specific.


Solution

  • My first refactoring step would look like this:

    require 'net/sftp'
    require 'ostruct'
    require 'optparse'
    
    class Sftp
      def run(arguments)
        parse(arguments)
        connect(arguments)
      end
    
      private
    
      def parse(arguments)
        ARGV << "-h" if ARGV.empty?
        @options = OpenStruct.new
        
        args = OptionParser.new do |args|
          args.banner = "Usage: #{__FILE__} [options]"
          
          args.on("-s", "--set-host=HOST", String, "The Host To Connect To") do |set_host|
            @options.set_host = set_host
          end
          
          args.on("-u", "--username=USERNAME", String, "Authenticate With A Username") do |username|
            @options.username = username
          end
    
          args.on("-p", "--password=PASSWORD", String, "Authenticate With A Password") do |password|
            @options.password = password
          end
    
          args.on("-w", "--wharf=WHARF", Integer, "Specify The Wharf (Port) The Service Is Running") do |wharf|
            @options.wharf = wharf
          end
    
          args.on("-m", "--mkdir=CREATE DIRECTORY", String, "Create A Directory") do |mkdir|
            @options.mkdir = mkdir
          end
    
          args.on("-h", "--help", "Show Help And Exit") do
            puts args
            exit
          end
    
          begin
            args.parse!(arguments)
          
          rescue OptionParser::MissingArgument => error
            puts "[!] ".red + error.message.bold
            exit
    
          rescue OptionParser::InvalidOption => error
            puts "[!] ".red + error.message.bold
            exit
          end
        end
      end
    
      def connect(arguments)
        Net::SFTP.start(@options.set_host, @options.username, :password => @options.password, :port => @options.wharf) do |sftp|
          mkddir(sftp) if @options.mkdir
          rmdir(sftp) if @options.rmdir
          erase(sftp) if @options.erase         
        end
    
        output("Exiting at => (#{Time.now})")
      end
    
      def mkdir(sftp)
        sftp.mkdir!(@options.mkdir)
        output("Creating Directory => #{@options.mkdir}")
      end
    
      def rmdir(sftp)
        sftp.rmdir!(@options.rmdir)     
        output("Deleting Directory => #{@options.rmdir}")
      end
    
      def erase(sftp)
        sftp.remove!(@options.erase)
        output("Deleting File => #{@options.erase}")
      end
    
      def output(string)
        puts "----------------------------------------------------------"
        puts " #{string}"
        puts "----------------------------------------------------------"
      end
    end
    
    sftp = Sftp.new
    sftp.run(ARGV)