melon 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +4 -0
 - data/features/add.feature +6 -1
 - data/lib/melon/cli.rb +13 -4
 - data/lib/melon/commands/add.rb +56 -0
 - data/lib/melon/commands/base.rb +73 -0
 - data/lib/melon/commands/check.rb +35 -0
 - data/lib/melon/commands/help.rb +23 -0
 - data/lib/melon/commands/list.rb +33 -0
 - data/lib/melon/commands/show.rb +36 -0
 - data/lib/melon/commands.rb +16 -213
 - data/lib/melon/hasher.rb +1 -0
 - data/lib/melon/helpers.rb +16 -2
 - data/lib/melon/version.rb +1 -1
 - metadata +10 -4
 
    
        data/History.txt
    CHANGED
    
    
    
        data/features/add.feature
    CHANGED
    
    | 
         @@ -51,7 +51,12 @@ Feature: Adding files to the database 
     | 
|
| 
       51 
51 
     | 
    
         
             
                """
         
     | 
| 
       52 
52 
     | 
    
         
             
                Third test file
         
     | 
| 
       53 
53 
     | 
    
         
             
                """
         
     | 
| 
       54 
     | 
    
         
            -
                 
     | 
| 
      
 54 
     | 
    
         
            +
                And a file named "test_file" with:
         
     | 
| 
      
 55 
     | 
    
         
            +
                """
         
     | 
| 
      
 56 
     | 
    
         
            +
                Test file that's not in the subfolder
         
     | 
| 
      
 57 
     | 
    
         
            +
                """
         
     | 
| 
      
 58 
     | 
    
         
            +
                When I run "melon -d test.db add -r dir test_file"
         
     | 
| 
       55 
59 
     | 
    
         
             
                Then the output should contain "dir/test1"
         
     | 
| 
       56 
60 
     | 
    
         
             
                And the output should contain "dir/test2"
         
     | 
| 
       57 
61 
     | 
    
         
             
                And the output should contain "dir/test/test3"
         
     | 
| 
      
 62 
     | 
    
         
            +
                And the output should contain "test_file"
         
     | 
    
        data/lib/melon/cli.rb
    CHANGED
    
    | 
         @@ -57,6 +57,8 @@ module Melon 
     | 
|
| 
       57 
57 
     | 
    
         
             
                def parse_options
         
     | 
| 
       58 
58 
     | 
    
         
             
                  options = self.class.default_options
         
     | 
| 
       59 
59 
     | 
    
         | 
| 
      
 60 
     | 
    
         
            +
                  # TODO: empty args should be -h
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
       60 
62 
     | 
    
         
             
                  parser = OptionParser.new do |p|
         
     | 
| 
       61 
63 
     | 
    
         
             
                    p.banner = "Usage: melon [options] COMMAND [command-options] [ARGS]"
         
     | 
| 
       62 
64 
     | 
    
         | 
| 
         @@ -64,11 +66,18 @@ module Melon 
     | 
|
| 
       64 
66 
     | 
    
         
             
                    p.separator "Commands:"
         
     | 
| 
       65 
67 
     | 
    
         
             
                    p.separator ""
         
     | 
| 
       66 
68 
     | 
    
         | 
| 
       67 
     | 
    
         
            -
                     
     | 
| 
       68 
     | 
    
         
            -
                       
     | 
| 
       69 
     | 
    
         
            -
                       
     | 
| 
       70 
     | 
    
         
            -
             
     | 
| 
      
 69 
     | 
    
         
            +
                    Commands.each do |command|
         
     | 
| 
      
 70 
     | 
    
         
            +
                      # help goes last
         
     | 
| 
      
 71 
     | 
    
         
            +
                      if command.command_name == 'help'
         
     | 
| 
      
 72 
     | 
    
         
            +
                        next
         
     | 
| 
      
 73 
     | 
    
         
            +
                      end
         
     | 
| 
       71 
74 
     | 
    
         | 
| 
      
 75 
     | 
    
         
            +
                      p.separator format_command(command.command_name,
         
     | 
| 
      
 76 
     | 
    
         
            +
                                                 command.description)
         
     | 
| 
      
 77 
     | 
    
         
            +
                    end
         
     | 
| 
      
 78 
     | 
    
         
            +
                    # TODO: add help command back into parser helptext
         
     | 
| 
      
 79 
     | 
    
         
            +
                    # p.separator format_command(Commands::Help.command_name,
         
     | 
| 
      
 80 
     | 
    
         
            +
                    #                            Commands::Help.description)
         
     | 
| 
       72 
81 
     | 
    
         
             
                    p.separator ""
         
     | 
| 
       73 
82 
     | 
    
         
             
                    p.separator "Options:"
         
     | 
| 
       74 
83 
     | 
    
         
             
                    p.separator ""
         
     | 
| 
         @@ -0,0 +1,56 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'melon/hasher'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'melon/commands/base'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module Melon
         
     | 
| 
      
 5 
     | 
    
         
            +
              module Commands
         
     | 
| 
      
 6 
     | 
    
         
            +
                class Add < Base
         
     | 
| 
      
 7 
     | 
    
         
            +
                  def self.description
         
     | 
| 
      
 8 
     | 
    
         
            +
                    "Add files to the melon database"
         
     | 
| 
      
 9 
     | 
    
         
            +
                  end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                  def parser_options(parser)
         
     | 
| 
      
 12 
     | 
    
         
            +
                    parser.on("-q", "--quiet", "Suppress printing of hash and path") do
         
     | 
| 
      
 13 
     | 
    
         
            +
                      options.quiet = true
         
     | 
| 
      
 14 
     | 
    
         
            +
                    end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                    parser.on("-r", "--recursive", "Recursively add directory contents") do
         
     | 
| 
      
 17 
     | 
    
         
            +
                      options.recursive = true
         
     | 
| 
      
 18 
     | 
    
         
            +
                    end
         
     | 
| 
      
 19 
     | 
    
         
            +
                  end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                  def run
         
     | 
| 
      
 22 
     | 
    
         
            +
                    parse_options!
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                    if options.recursive
         
     | 
| 
      
 25 
     | 
    
         
            +
                      self.args = recursively_expand(args)
         
     | 
| 
      
 26 
     | 
    
         
            +
                    end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                    options.database.transaction do
         
     | 
| 
      
 29 
     | 
    
         
            +
                      args.each do |arg|
         
     | 
| 
      
 30 
     | 
    
         
            +
                        filename = File.expand_path(arg)
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                        if File.directory?(filename)
         
     | 
| 
      
 33 
     | 
    
         
            +
                          error "argument is a directory: #{arg}"
         
     | 
| 
      
 34 
     | 
    
         
            +
                        end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                        if options.database[:by_path][filename]
         
     | 
| 
      
 37 
     | 
    
         
            +
                          error "path already present in database: #{arg}"
         
     | 
| 
      
 38 
     | 
    
         
            +
                        end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                        # hash strategy should be encapsulated, ergo indirection here
         
     | 
| 
      
 41 
     | 
    
         
            +
                        hash = Hasher.digest(filename)
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                        if options.database[:by_hash][hash]
         
     | 
| 
      
 44 
     | 
    
         
            +
                          error "file exists elsewhere in the database: #{arg}"
         
     | 
| 
      
 45 
     | 
    
         
            +
                        end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                        options.database[:by_hash][hash] = filename
         
     | 
| 
      
 49 
     | 
    
         
            +
                        options.database[:by_path][filename] = hash
         
     | 
| 
      
 50 
     | 
    
         
            +
                        puts "#{hash}:#{filename}" unless options.quiet
         
     | 
| 
      
 51 
     | 
    
         
            +
                      end
         
     | 
| 
      
 52 
     | 
    
         
            +
                    end
         
     | 
| 
      
 53 
     | 
    
         
            +
                  end
         
     | 
| 
      
 54 
     | 
    
         
            +
                end
         
     | 
| 
      
 55 
     | 
    
         
            +
              end
         
     | 
| 
      
 56 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,73 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'optparse'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'melon/helpers'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module Melon
         
     | 
| 
      
 5 
     | 
    
         
            +
              module Commands
         
     | 
| 
      
 6 
     | 
    
         
            +
                class Base
         
     | 
| 
      
 7 
     | 
    
         
            +
                  include Helpers
         
     | 
| 
      
 8 
     | 
    
         
            +
                  attr_accessor :args, :options
         
     | 
| 
      
 9 
     | 
    
         
            +
                  attr_reader :description
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                  def initialize(args, options)
         
     | 
| 
      
 12 
     | 
    
         
            +
                    self.args = args
         
     | 
| 
      
 13 
     | 
    
         
            +
                    self.options = options
         
     | 
| 
      
 14 
     | 
    
         
            +
                  end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                  def self.command_name
         
     | 
| 
      
 17 
     | 
    
         
            +
                    self.to_s.split("::")[-1].downcase
         
     | 
| 
      
 18 
     | 
    
         
            +
                  end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                  def parser
         
     | 
| 
      
 21 
     | 
    
         
            +
                    @parser ||= OptionParser.new do |p|
         
     | 
| 
      
 22 
     | 
    
         
            +
                      p.banner = usagebanner
         
     | 
| 
      
 23 
     | 
    
         
            +
                      p.separator ""
         
     | 
| 
      
 24 
     | 
    
         
            +
                      p.separator blockquote(self.class.description + ".", :margin => 0)
         
     | 
| 
      
 25 
     | 
    
         
            +
                      p.separator ""
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                      if helptext
         
     | 
| 
      
 28 
     | 
    
         
            +
                        p.separator blockquote(" " + helptext)
         
     | 
| 
      
 29 
     | 
    
         
            +
                        p.separator ""
         
     | 
| 
      
 30 
     | 
    
         
            +
                      end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                      if self.respond_to? :parser_options
         
     | 
| 
      
 33 
     | 
    
         
            +
                        p.separator "Options:"
         
     | 
| 
      
 34 
     | 
    
         
            +
                        p.separator ""
         
     | 
| 
      
 35 
     | 
    
         
            +
                        parser_options(p)
         
     | 
| 
      
 36 
     | 
    
         
            +
                      end
         
     | 
| 
      
 37 
     | 
    
         
            +
                    end
         
     | 
| 
      
 38 
     | 
    
         
            +
                  end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                  def usagebanner
         
     | 
| 
      
 42 
     | 
    
         
            +
                    usage = "Usage: melon #{self.class.command_name}"
         
     | 
| 
      
 43 
     | 
    
         
            +
                    usage << " [options]" if self.respond_to?(:parser_options)
         
     | 
| 
      
 44 
     | 
    
         
            +
                    usage << ' ' << usageargs if usageargs
         
     | 
| 
      
 45 
     | 
    
         
            +
                    usage
         
     | 
| 
      
 46 
     | 
    
         
            +
                  end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                  def usageargs; end
         
     | 
| 
      
 49 
     | 
    
         
            +
                  def helptext; end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                  def self.description
         
     | 
| 
      
 52 
     | 
    
         
            +
                    raise
         
     | 
| 
      
 53 
     | 
    
         
            +
                  end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                  def parse_options!
         
     | 
| 
      
 56 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 57 
     | 
    
         
            +
                      parser.parse!(args)
         
     | 
| 
      
 58 
     | 
    
         
            +
                    rescue OptionParser::ParseError => e
         
     | 
| 
      
 59 
     | 
    
         
            +
                      error "#{self.class.command_name}: #{e}"
         
     | 
| 
      
 60 
     | 
    
         
            +
                    end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                    # verify remaining args are files - overrideable
         
     | 
| 
      
 63 
     | 
    
         
            +
                    verify_args
         
     | 
| 
      
 64 
     | 
    
         
            +
                  end
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                  def verify_args
         
     | 
| 
      
 67 
     | 
    
         
            +
                    args.each do |arg|
         
     | 
| 
      
 68 
     | 
    
         
            +
                      error "no such file: #{arg}" unless File.exists?(arg)
         
     | 
| 
      
 69 
     | 
    
         
            +
                    end
         
     | 
| 
      
 70 
     | 
    
         
            +
                  end
         
     | 
| 
      
 71 
     | 
    
         
            +
                end
         
     | 
| 
      
 72 
     | 
    
         
            +
              end
         
     | 
| 
      
 73 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,35 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'melon/commands/base'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Melon
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Commands
         
     | 
| 
      
 5 
     | 
    
         
            +
                class Check < Base
         
     | 
| 
      
 6 
     | 
    
         
            +
                  def self.description
         
     | 
| 
      
 7 
     | 
    
         
            +
                    "Determine whether or not a copy of a file resides in the database"
         
     | 
| 
      
 8 
     | 
    
         
            +
                  end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                  def helptext
         
     | 
| 
      
 11 
     | 
    
         
            +
                    <<EOS
         
     | 
| 
      
 12 
     | 
    
         
            +
            If the file's hash matches a hash in the database, nothing is
         
     | 
| 
      
 13 
     | 
    
         
            +
            printed.  Otherwise, the full path to the file is printed.
         
     | 
| 
      
 14 
     | 
    
         
            +
            EOS
         
     | 
| 
      
 15 
     | 
    
         
            +
                  end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                  def usageargs
         
     | 
| 
      
 18 
     | 
    
         
            +
                    "file [file [file ...]"
         
     | 
| 
      
 19 
     | 
    
         
            +
                  end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                  def run
         
     | 
| 
      
 22 
     | 
    
         
            +
                    parse_options!
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                    options.database.transaction do
         
     | 
| 
      
 25 
     | 
    
         
            +
                      args.each do |filename|
         
     | 
| 
      
 26 
     | 
    
         
            +
                        hash = Hasher.digest(filename)
         
     | 
| 
      
 27 
     | 
    
         
            +
                        unless options.database[:by_hash][hash]
         
     | 
| 
      
 28 
     | 
    
         
            +
                          puts File.expand_path(filename)
         
     | 
| 
      
 29 
     | 
    
         
            +
                        end
         
     | 
| 
      
 30 
     | 
    
         
            +
                      end
         
     | 
| 
      
 31 
     | 
    
         
            +
                    end
         
     | 
| 
      
 32 
     | 
    
         
            +
                  end
         
     | 
| 
      
 33 
     | 
    
         
            +
                end
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,23 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'melon/commands/base'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'melon/commands'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module Melon
         
     | 
| 
      
 5 
     | 
    
         
            +
              module Commands
         
     | 
| 
      
 6 
     | 
    
         
            +
                class Help < Base
         
     | 
| 
      
 7 
     | 
    
         
            +
                  def self.description
         
     | 
| 
      
 8 
     | 
    
         
            +
                    "Get help with a specific command"
         
     | 
| 
      
 9 
     | 
    
         
            +
                  end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                  def run
         
     | 
| 
      
 12 
     | 
    
         
            +
                    help = args.shift
         
     | 
| 
      
 13 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 14 
     | 
    
         
            +
                      puts Commands[help.capitalize].new(args, options).parser
         
     | 
| 
      
 15 
     | 
    
         
            +
                    rescue NameError => e
         
     | 
| 
      
 16 
     | 
    
         
            +
                      # don't swallow NoMethodErrors
         
     | 
| 
      
 17 
     | 
    
         
            +
                      raise e unless e.instance_of?(NameError)
         
     | 
| 
      
 18 
     | 
    
         
            +
                      error "unrecognized command: #{help}"
         
     | 
| 
      
 19 
     | 
    
         
            +
                    end
         
     | 
| 
      
 20 
     | 
    
         
            +
                  end
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
              end
         
     | 
| 
      
 23 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,33 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'melon/commands/base'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Melon
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Commands
         
     | 
| 
      
 5 
     | 
    
         
            +
                class List < Base
         
     | 
| 
      
 6 
     | 
    
         
            +
                  def self.description
         
     | 
| 
      
 7 
     | 
    
         
            +
                    "List the files tracked by the database"
         
     | 
| 
      
 8 
     | 
    
         
            +
                  end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                  def parser_options(parser)
         
     | 
| 
      
 11 
     | 
    
         
            +
                      parser.on("-p", "--paths", "print only paths") do
         
     | 
| 
      
 12 
     | 
    
         
            +
                        options.only_paths = true
         
     | 
| 
      
 13 
     | 
    
         
            +
                      end
         
     | 
| 
      
 14 
     | 
    
         
            +
                      # TODO: re-enable this as -h after help command goes in
         
     | 
| 
      
 15 
     | 
    
         
            +
                      # parser.on("--hashes", "print only hashes") { options.only_hashes = true }
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                  def verify_args
         
     | 
| 
      
 19 
     | 
    
         
            +
                    error "invalid argument: #{args.shift}" unless args.empty?
         
     | 
| 
      
 20 
     | 
    
         
            +
                  end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                  def run
         
     | 
| 
      
 23 
     | 
    
         
            +
                    parse_options!
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                    options.database.transaction do
         
     | 
| 
      
 26 
     | 
    
         
            +
                      options.database[:by_hash].each_pair do |hash, path|
         
     | 
| 
      
 27 
     | 
    
         
            +
                        puts "#{path}:#{hash}"
         
     | 
| 
      
 28 
     | 
    
         
            +
                      end
         
     | 
| 
      
 29 
     | 
    
         
            +
                    end
         
     | 
| 
      
 30 
     | 
    
         
            +
                  end
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
              end
         
     | 
| 
      
 33 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,36 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'melon/commands/base'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Melon
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Commands
         
     | 
| 
      
 5 
     | 
    
         
            +
                class Show < Base
         
     | 
| 
      
 6 
     | 
    
         
            +
                  def self.description
         
     | 
| 
      
 7 
     | 
    
         
            +
                    "Show where the database thinks a file is located"
         
     | 
| 
      
 8 
     | 
    
         
            +
                  end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                  def usageargs
         
     | 
| 
      
 11 
     | 
    
         
            +
                    "file [file [file ...]]"
         
     | 
| 
      
 12 
     | 
    
         
            +
                  end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  def helptext
         
     | 
| 
      
 15 
     | 
    
         
            +
                    <<EOS
         
     | 
| 
      
 16 
     | 
    
         
            +
              If the file's hash matches a hash in the database, then
         
     | 
| 
      
 17 
     | 
    
         
            +
            the associated path in the database is printed.  Otherwise,
         
     | 
| 
      
 18 
     | 
    
         
            +
            nothing is printed.
         
     | 
| 
      
 19 
     | 
    
         
            +
            EOS
         
     | 
| 
      
 20 
     | 
    
         
            +
                  end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                  def run
         
     | 
| 
      
 23 
     | 
    
         
            +
                    parse_options!
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                    options.database.transaction do
         
     | 
| 
      
 26 
     | 
    
         
            +
                      args.each do |filename|
         
     | 
| 
      
 27 
     | 
    
         
            +
                        hash = Hasher.digest(filename)
         
     | 
| 
      
 28 
     | 
    
         
            +
                        if path = options.database[:by_hash][hash]
         
     | 
| 
      
 29 
     | 
    
         
            +
                          puts path
         
     | 
| 
      
 30 
     | 
    
         
            +
                        end
         
     | 
| 
      
 31 
     | 
    
         
            +
                      end
         
     | 
| 
      
 32 
     | 
    
         
            +
                    end
         
     | 
| 
      
 33 
     | 
    
         
            +
                  end
         
     | 
| 
      
 34 
     | 
    
         
            +
                end
         
     | 
| 
      
 35 
     | 
    
         
            +
              end
         
     | 
| 
      
 36 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/melon/commands.rb
    CHANGED
    
    | 
         @@ -1,14 +1,13 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require  
     | 
| 
       2 
     | 
    
         
            -
            require 'melon/helpers'
         
     | 
| 
      
 1 
     | 
    
         
            +
            Dir[File.join(File.dirname(__FILE__), "commands/*.rb")].each {|f| require f}
         
     | 
| 
       3 
2 
     | 
    
         | 
| 
       4 
3 
     | 
    
         
             
            module Melon
         
     | 
| 
       5 
4 
     | 
    
         
             
              module Commands
         
     | 
| 
       6 
5 
     | 
    
         
             
                def self.each
         
     | 
| 
       7 
6 
     | 
    
         
             
                  consts = []
         
     | 
| 
       8 
     | 
    
         
            -
                   
     | 
| 
       9 
     | 
    
         
            -
                  self.constants.each do |c|
         
     | 
| 
      
 7 
     | 
    
         
            +
                  self.constants.sort.each do |c|
         
     | 
| 
       10 
8 
     | 
    
         
             
                    const = self.const_get(c)
         
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                    if const.superclass == Base
         
     | 
| 
       12 
11 
     | 
    
         
             
                      consts << const
         
     | 
| 
       13 
12 
     | 
    
         
             
                      yield const 
         
     | 
| 
       14 
13 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -20,215 +19,19 @@ module Melon 
     | 
|
| 
       20 
19 
     | 
    
         
             
                  alias :[] :const_get
         
     | 
| 
       21 
20 
     | 
    
         
             
                end
         
     | 
| 
       22 
21 
     | 
    
         | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                # 1.0 list
         
     | 
| 
      
 24 
     | 
    
         
            +
                # TODO: needs a 'verify' command to check integrity of database
         
     | 
| 
       24 
25 
     | 
    
         
             
                #   both internal 2-hash consistency (consistency) and db<->filesystem
         
     | 
| 
       25 
26 
     | 
    
         
             
                #   matching up (integrity) [file exists, hashes match]
         
     | 
| 
       26 
     | 
    
         
            -
                # needs a 'remove' command, or some way to deal with deletes/renames
         
     | 
| 
       27 
     | 
    
         
            -
                #  
     | 
| 
       28 
     | 
    
         
            -
                 
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
                    self.options = options
         
     | 
| 
       36 
     | 
    
         
            -
                  end
         
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
     | 
    
         
            -
                  def parser
         
     | 
| 
       39 
     | 
    
         
            -
                    raise
         
     | 
| 
       40 
     | 
    
         
            -
                  end
         
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
                  def self.description
         
     | 
| 
       43 
     | 
    
         
            -
                    raise
         
     | 
| 
       44 
     | 
    
         
            -
                  end
         
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
                  def parse_options!
         
     | 
| 
       47 
     | 
    
         
            -
                    begin
         
     | 
| 
       48 
     | 
    
         
            -
                      parser.parse!(args)
         
     | 
| 
       49 
     | 
    
         
            -
                    rescue OptionParser::ParseError => e
         
     | 
| 
       50 
     | 
    
         
            -
                      error "#{self.class.to_s.split("::").last.downcase}: #{e}"
         
     | 
| 
       51 
     | 
    
         
            -
                    end
         
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
     | 
    
         
            -
                    # verify remaining args are files - overrideable
         
     | 
| 
       54 
     | 
    
         
            -
                    verify_args
         
     | 
| 
       55 
     | 
    
         
            -
                  end
         
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
       57 
     | 
    
         
            -
                  def verify_args
         
     | 
| 
       58 
     | 
    
         
            -
                    args.each do |arg|
         
     | 
| 
       59 
     | 
    
         
            -
                      error "no such file: #{arg}" unless File.exists?(arg)
         
     | 
| 
       60 
     | 
    
         
            -
                    end
         
     | 
| 
       61 
     | 
    
         
            -
                  end
         
     | 
| 
       62 
     | 
    
         
            -
                end
         
     | 
| 
       63 
     | 
    
         
            -
             
     | 
| 
       64 
     | 
    
         
            -
                class Add < Base
         
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
       66 
     | 
    
         
            -
                  def self.description
         
     | 
| 
       67 
     | 
    
         
            -
                    "Add files to the melon database"
         
     | 
| 
       68 
     | 
    
         
            -
                  end
         
     | 
| 
       69 
     | 
    
         
            -
             
     | 
| 
       70 
     | 
    
         
            -
                  def parser
         
     | 
| 
       71 
     | 
    
         
            -
                    @parser ||= OptionParser.new do |p|
         
     | 
| 
       72 
     | 
    
         
            -
                      p.banner = "Usage: melon add [options] file [file [file ...]]"
         
     | 
| 
       73 
     | 
    
         
            -
                      p.separator ""
         
     | 
| 
       74 
     | 
    
         
            -
                      p.separator blockquote(Add.description + ".")
         
     | 
| 
       75 
     | 
    
         
            -
             
     | 
| 
       76 
     | 
    
         
            -
                      p.separator ""
         
     | 
| 
       77 
     | 
    
         
            -
                      p.separator "Options:"
         
     | 
| 
       78 
     | 
    
         
            -
                      p.separator ""
         
     | 
| 
       79 
     | 
    
         
            -
             
     | 
| 
       80 
     | 
    
         
            -
                      p.on("-q", "--quiet", "Suppress printing of hash and path") do
         
     | 
| 
       81 
     | 
    
         
            -
                        options.quiet = true
         
     | 
| 
       82 
     | 
    
         
            -
                      end
         
     | 
| 
       83 
     | 
    
         
            -
             
     | 
| 
       84 
     | 
    
         
            -
                      p.on("-r", "--recursive", "Recursively add directory contents") do
         
     | 
| 
       85 
     | 
    
         
            -
                        options.recursive = true
         
     | 
| 
       86 
     | 
    
         
            -
                      end
         
     | 
| 
       87 
     | 
    
         
            -
             
     | 
| 
       88 
     | 
    
         
            -
                      # p.on("-f", "--force",
         
     | 
| 
       89 
     | 
    
         
            -
                      #      "Force the recalculation of the path that",
         
     | 
| 
       90 
     | 
    
         
            -
                      #      " already exists in the database") do
         
     | 
| 
       91 
     | 
    
         
            -
                      #   options.force = true
         
     | 
| 
       92 
     | 
    
         
            -
                      #      end
         
     | 
| 
       93 
     | 
    
         
            -
                    end
         
     | 
| 
       94 
     | 
    
         
            -
                  end
         
     | 
| 
       95 
     | 
    
         
            -
             
     | 
| 
       96 
     | 
    
         
            -
                  def run
         
     | 
| 
       97 
     | 
    
         
            -
                    parse_options!
         
     | 
| 
       98 
     | 
    
         
            -
             
     | 
| 
       99 
     | 
    
         
            -
                    if options.recursive
         
     | 
| 
       100 
     | 
    
         
            -
                      self.args = args.collect do |arg|
         
     | 
| 
       101 
     | 
    
         
            -
                        if File.directory?(arg)
         
     | 
| 
       102 
     | 
    
         
            -
                          Dir["#{arg}/**/*"]
         
     | 
| 
       103 
     | 
    
         
            -
                        else
         
     | 
| 
       104 
     | 
    
         
            -
                          arg
         
     | 
| 
       105 
     | 
    
         
            -
                        end
         
     | 
| 
       106 
     | 
    
         
            -
                      end.flatten.reject { |arg| File.directory?(arg) }
         
     | 
| 
       107 
     | 
    
         
            -
                    end
         
     | 
| 
       108 
     | 
    
         
            -
             
     | 
| 
       109 
     | 
    
         
            -
                    options.database.transaction do
         
     | 
| 
       110 
     | 
    
         
            -
                      args.each do |arg|
         
     | 
| 
       111 
     | 
    
         
            -
                        filename = File.expand_path(arg)
         
     | 
| 
       112 
     | 
    
         
            -
             
     | 
| 
       113 
     | 
    
         
            -
                        if File.directory?(filename)
         
     | 
| 
       114 
     | 
    
         
            -
                          error "argument is a directory: #{arg}"
         
     | 
| 
       115 
     | 
    
         
            -
                        end
         
     | 
| 
       116 
     | 
    
         
            -
             
     | 
| 
       117 
     | 
    
         
            -
                        if options.database[:by_path][filename]# and !options.force
         
     | 
| 
       118 
     | 
    
         
            -
                          error "path already present in database: #{arg}"
         
     | 
| 
       119 
     | 
    
         
            -
                        end
         
     | 
| 
       120 
     | 
    
         
            -
             
     | 
| 
       121 
     | 
    
         
            -
                        # hash strategy should be encapsulated, ergo indirection here
         
     | 
| 
       122 
     | 
    
         
            -
                        hash = Hasher.digest(filename)
         
     | 
| 
       123 
     | 
    
         
            -
             
     | 
| 
       124 
     | 
    
         
            -
                        if options.database[:by_hash][hash]
         
     | 
| 
       125 
     | 
    
         
            -
                          error "file exists elsewhere in the database: #{arg}"
         
     | 
| 
       126 
     | 
    
         
            -
                        end
         
     | 
| 
       127 
     | 
    
         
            -
             
     | 
| 
       128 
     | 
    
         
            -
             
     | 
| 
       129 
     | 
    
         
            -
                        options.database[:by_hash][hash] = filename
         
     | 
| 
       130 
     | 
    
         
            -
                        options.database[:by_path][filename] = hash
         
     | 
| 
       131 
     | 
    
         
            -
                        puts "#{hash}:#{filename}" unless options.quiet
         
     | 
| 
       132 
     | 
    
         
            -
                      end
         
     | 
| 
       133 
     | 
    
         
            -
                    end
         
     | 
| 
       134 
     | 
    
         
            -
                  end
         
     | 
| 
       135 
     | 
    
         
            -
                end
         
     | 
| 
       136 
     | 
    
         
            -
             
     | 
| 
       137 
     | 
    
         
            -
                class Show < Base
         
     | 
| 
       138 
     | 
    
         
            -
                  def self.description
         
     | 
| 
       139 
     | 
    
         
            -
                    "Show where the database thinks a file is located"
         
     | 
| 
       140 
     | 
    
         
            -
                  end
         
     | 
| 
       141 
     | 
    
         
            -
             
     | 
| 
       142 
     | 
    
         
            -
                  def parser
         
     | 
| 
       143 
     | 
    
         
            -
                    @parser ||= OptionParser.new do |p|
         
     | 
| 
       144 
     | 
    
         
            -
                      p.banner = "Usage: melon show file [file [file ...]]"
         
     | 
| 
       145 
     | 
    
         
            -
                      p.separator ""
         
     | 
| 
       146 
     | 
    
         
            -
                      p.separator blockquote(self.class.description + <<EOS
         
     | 
| 
       147 
     | 
    
         
            -
            .  If the file's hash matches a hash in the database, then
         
     | 
| 
       148 
     | 
    
         
            -
            the associated path in the database is printed.  Otherwise,
         
     | 
| 
       149 
     | 
    
         
            -
            nothing is printed.
         
     | 
| 
       150 
     | 
    
         
            -
            EOS
         
     | 
| 
       151 
     | 
    
         
            -
                                            )
         
     | 
| 
       152 
     | 
    
         
            -
                      p.separator ""
         
     | 
| 
       153 
     | 
    
         
            -
                      
         
     | 
| 
       154 
     | 
    
         
            -
                    end
         
     | 
| 
       155 
     | 
    
         
            -
                  end
         
     | 
| 
       156 
     | 
    
         
            -
             
     | 
| 
       157 
     | 
    
         
            -
                  def run
         
     | 
| 
       158 
     | 
    
         
            -
                    parse_options!
         
     | 
| 
       159 
     | 
    
         
            -
             
     | 
| 
       160 
     | 
    
         
            -
                    options.database.transaction do
         
     | 
| 
       161 
     | 
    
         
            -
                      args.each do |filename|
         
     | 
| 
       162 
     | 
    
         
            -
                        hash = Hasher.digest(filename)
         
     | 
| 
       163 
     | 
    
         
            -
                        if path = options.database[:by_hash][hash]
         
     | 
| 
       164 
     | 
    
         
            -
                          puts path
         
     | 
| 
       165 
     | 
    
         
            -
                        end
         
     | 
| 
       166 
     | 
    
         
            -
                      end
         
     | 
| 
       167 
     | 
    
         
            -
                    end
         
     | 
| 
       168 
     | 
    
         
            -
                  end
         
     | 
| 
       169 
     | 
    
         
            -
                end
         
     | 
| 
       170 
     | 
    
         
            -
             
     | 
| 
       171 
     | 
    
         
            -
                class Check < Base
         
     | 
| 
       172 
     | 
    
         
            -
                  def self.description
         
     | 
| 
       173 
     | 
    
         
            -
                    "Determine whether or not a copy of a file resides in the database"
         
     | 
| 
       174 
     | 
    
         
            -
                  end
         
     | 
| 
       175 
     | 
    
         
            -
             
     | 
| 
       176 
     | 
    
         
            -
                  def parser
         
     | 
| 
       177 
     | 
    
         
            -
                    @parser ||= OptionParser.new do |p|
         
     | 
| 
       178 
     | 
    
         
            -
                      p.banner = "Usage: melon check file [file [file ...]]"
         
     | 
| 
       179 
     | 
    
         
            -
                      p.separator ""
         
     | 
| 
       180 
     | 
    
         
            -
                      p.separator blockquote(self.class.description + <<EOS
         
     | 
| 
       181 
     | 
    
         
            -
            .  If the file's hash matches a hash in the database, nothing is
         
     | 
| 
       182 
     | 
    
         
            -
            printed.  Otherwise, the full path to the file is printed.
         
     | 
| 
       183 
     | 
    
         
            -
            EOS
         
     | 
| 
       184 
     | 
    
         
            -
                                            )
         
     | 
| 
       185 
     | 
    
         
            -
                      p.separator ""
         
     | 
| 
       186 
     | 
    
         
            -
                      
         
     | 
| 
       187 
     | 
    
         
            -
                    end
         
     | 
| 
       188 
     | 
    
         
            -
                  end
         
     | 
| 
       189 
     | 
    
         
            -
             
     | 
| 
       190 
     | 
    
         
            -
                  def run
         
     | 
| 
       191 
     | 
    
         
            -
                    parse_options!
         
     | 
| 
       192 
     | 
    
         
            -
             
     | 
| 
       193 
     | 
    
         
            -
                    options.database.transaction do
         
     | 
| 
       194 
     | 
    
         
            -
                      args.each do |filename|
         
     | 
| 
       195 
     | 
    
         
            -
                        hash = Hasher.digest(filename)
         
     | 
| 
       196 
     | 
    
         
            -
                        unless options.database[:by_hash][hash]
         
     | 
| 
       197 
     | 
    
         
            -
                          puts File.expand_path(filename)
         
     | 
| 
       198 
     | 
    
         
            -
                        end
         
     | 
| 
       199 
     | 
    
         
            -
                      end
         
     | 
| 
       200 
     | 
    
         
            -
                    end
         
     | 
| 
       201 
     | 
    
         
            -
                  end
         
     | 
| 
       202 
     | 
    
         
            -
                end
         
     | 
| 
       203 
     | 
    
         
            -
             
     | 
| 
       204 
     | 
    
         
            -
                class List < Base
         
     | 
| 
       205 
     | 
    
         
            -
                  def self.description
         
     | 
| 
       206 
     | 
    
         
            -
                    "List the files tracked by the database"
         
     | 
| 
       207 
     | 
    
         
            -
                  end
         
     | 
| 
       208 
     | 
    
         
            -
             
     | 
| 
       209 
     | 
    
         
            -
                  def parser
         
     | 
| 
       210 
     | 
    
         
            -
                    @parser ||= OptionParser.new do |p|
         
     | 
| 
       211 
     | 
    
         
            -
                      p.banner = "Usage: melon list"
         
     | 
| 
       212 
     | 
    
         
            -
                      p.separator ""
         
     | 
| 
       213 
     | 
    
         
            -
                      p.separator blockquote(self.class.description)
         
     | 
| 
       214 
     | 
    
         
            -
                      p.separator ""
         
     | 
| 
       215 
     | 
    
         
            -
                      
         
     | 
| 
       216 
     | 
    
         
            -
                    end
         
     | 
| 
       217 
     | 
    
         
            -
                  end
         
     | 
| 
       218 
     | 
    
         
            -
             
     | 
| 
       219 
     | 
    
         
            -
                  def verify_args
         
     | 
| 
       220 
     | 
    
         
            -
                    error "invalid argument: #{args.shift}" unless args.empty?
         
     | 
| 
       221 
     | 
    
         
            -
                  end
         
     | 
| 
       222 
     | 
    
         
            -
             
     | 
| 
       223 
     | 
    
         
            -
                  def run
         
     | 
| 
       224 
     | 
    
         
            -
                    parse_options!
         
     | 
| 
       225 
     | 
    
         
            -
             
     | 
| 
       226 
     | 
    
         
            -
                    options.database.transaction do
         
     | 
| 
       227 
     | 
    
         
            -
                      options.database[:by_hash].each_pair do |hash, path|
         
     | 
| 
       228 
     | 
    
         
            -
                        puts "#{path}:#{hash}"
         
     | 
| 
       229 
     | 
    
         
            -
                      end
         
     | 
| 
       230 
     | 
    
         
            -
                    end
         
     | 
| 
       231 
     | 
    
         
            -
                  end
         
     | 
| 
       232 
     | 
    
         
            -
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
                # TODO: needs a 'remove' command, or some way to deal with deletes/renames
         
     | 
| 
      
 28 
     | 
    
         
            +
                #   remove: given a tracked file, removes it
         
     | 
| 
      
 29 
     | 
    
         
            +
                #           given an untracked file, it hashes it
         
     | 
| 
      
 30 
     | 
    
         
            +
                #             and removes it by hash
         
     | 
| 
      
 31 
     | 
    
         
            +
                # TODO: list needs --paths(only) and --hashes(only)
         
     | 
| 
      
 32 
     | 
    
         
            +
                #            --count
         
     | 
| 
      
 33 
     | 
    
         
            +
                # TODO: check needs -r
         
     | 
| 
      
 34 
     | 
    
         
            +
                # TODO: update- a function of add, ignore files that are already present in the db
         
     | 
| 
      
 35 
     | 
    
         
            +
                # TODO: handle moving a file somehow -- hopefully a function of update
         
     | 
| 
       233 
36 
     | 
    
         
             
              end
         
     | 
| 
       234 
37 
     | 
    
         
             
            end
         
     | 
    
        data/lib/melon/hasher.rb
    CHANGED
    
    
    
        data/lib/melon/helpers.rb
    CHANGED
    
    | 
         @@ -6,7 +6,7 @@ module Melon 
     | 
|
| 
       6 
6 
     | 
    
         
             
                    :width => 22,
         
     | 
| 
       7 
7 
     | 
    
         
             
                    :wrap => 80
         
     | 
| 
       8 
8 
     | 
    
         
             
                  }.update(options)
         
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
       10 
10 
     | 
    
         
             
                  pad = "\n" + ' ' * options[:width]
         
     | 
| 
       11 
11 
     | 
    
         
             
                  desc = self.wrap_text(desc, options[:wrap] - options[:width])
         
     | 
| 
       12 
12 
     | 
    
         
             
                  desc = desc.split("\n").join(pad)
         
     | 
| 
         @@ -25,8 +25,12 @@ module Melon 
     | 
|
| 
       25 
25 
     | 
    
         
             
                    :margin => 4,
         
     | 
| 
       26 
26 
     | 
    
         
             
                    :wrap => 70
         
     | 
| 
       27 
27 
     | 
    
         
             
                  }.update(options)
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
       28 
29 
     | 
    
         
             
                  options[:width] = options.delete(:margin)
         
     | 
| 
       29 
     | 
    
         
            -
                   
     | 
| 
      
 30 
     | 
    
         
            +
                  options[:margin] = 0
         
     | 
| 
      
 31 
     | 
    
         
            +
                  format_command('', string.gsub(/\s+/,' ').
         
     | 
| 
      
 32 
     | 
    
         
            +
                                 gsub(/\. /, '.  ').
         
     | 
| 
      
 33 
     | 
    
         
            +
                                 gsub(/^ /, '  '), options)
         
     | 
| 
       30 
34 
     | 
    
         
             
                end
         
     | 
| 
       31 
35 
     | 
    
         | 
| 
       32 
36 
     | 
    
         
             
                def error(error_obj_or_str, code = 1)
         
     | 
| 
         @@ -39,5 +43,15 @@ module Melon 
     | 
|
| 
       39 
43 
     | 
    
         
             
                  $stderr.puts "melon: #{error_str}"
         
     | 
| 
       40 
44 
     | 
    
         
             
                  exit code
         
     | 
| 
       41 
45 
     | 
    
         
             
                end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                def recursively_expand(filelist)
         
     | 
| 
      
 48 
     | 
    
         
            +
                  filelist.collect do |arg|
         
     | 
| 
      
 49 
     | 
    
         
            +
                    if File.directory?(arg)
         
     | 
| 
      
 50 
     | 
    
         
            +
                      Dir["#{arg}/**/*"]
         
     | 
| 
      
 51 
     | 
    
         
            +
                    else
         
     | 
| 
      
 52 
     | 
    
         
            +
                      arg
         
     | 
| 
      
 53 
     | 
    
         
            +
                    end
         
     | 
| 
      
 54 
     | 
    
         
            +
                  end.flatten.reject { |arg| File.directory?(arg) }
         
     | 
| 
      
 55 
     | 
    
         
            +
                end
         
     | 
| 
       42 
56 
     | 
    
         
             
              end
         
     | 
| 
       43 
57 
     | 
    
         
             
            end
         
     | 
    
        data/lib/melon/version.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | 
         @@ -1,13 +1,13 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification 
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: melon
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version 
         
     | 
| 
       4 
     | 
    
         
            -
              hash:  
     | 
| 
      
 4 
     | 
    
         
            +
              hash: 19
         
     | 
| 
       5 
5 
     | 
    
         
             
              prerelease: false
         
     | 
| 
       6 
6 
     | 
    
         
             
              segments: 
         
     | 
| 
       7 
7 
     | 
    
         
             
              - 0
         
     | 
| 
       8 
     | 
    
         
            -
              -  
     | 
| 
      
 8 
     | 
    
         
            +
              - 3
         
     | 
| 
       9 
9 
     | 
    
         
             
              - 0
         
     | 
| 
       10 
     | 
    
         
            -
              version: 0. 
     | 
| 
      
 10 
     | 
    
         
            +
              version: 0.3.0
         
     | 
| 
       11 
11 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       12 
12 
     | 
    
         
             
            authors: 
         
     | 
| 
       13 
13 
     | 
    
         
             
            - Andrew Roberts
         
     | 
| 
         @@ -15,7 +15,7 @@ autorequire: 
     | 
|
| 
       15 
15 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       16 
16 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       17 
17 
     | 
    
         | 
| 
       18 
     | 
    
         
            -
            date: 2011-01- 
     | 
| 
      
 18 
     | 
    
         
            +
            date: 2011-01-28 00:00:00 -05:00
         
     | 
| 
       19 
19 
     | 
    
         
             
            default_executable: melon
         
     | 
| 
       20 
20 
     | 
    
         
             
            dependencies: 
         
     | 
| 
       21 
21 
     | 
    
         
             
            - !ruby/object:Gem::Dependency 
         
     | 
| 
         @@ -88,6 +88,12 @@ files: 
     | 
|
| 
       88 
88 
     | 
    
         
             
            - lib/melon.rb
         
     | 
| 
       89 
89 
     | 
    
         
             
            - lib/melon/cli.rb
         
     | 
| 
       90 
90 
     | 
    
         
             
            - lib/melon/commands.rb
         
     | 
| 
      
 91 
     | 
    
         
            +
            - lib/melon/commands/add.rb
         
     | 
| 
      
 92 
     | 
    
         
            +
            - lib/melon/commands/base.rb
         
     | 
| 
      
 93 
     | 
    
         
            +
            - lib/melon/commands/check.rb
         
     | 
| 
      
 94 
     | 
    
         
            +
            - lib/melon/commands/help.rb
         
     | 
| 
      
 95 
     | 
    
         
            +
            - lib/melon/commands/list.rb
         
     | 
| 
      
 96 
     | 
    
         
            +
            - lib/melon/commands/show.rb
         
     | 
| 
       91 
97 
     | 
    
         
             
            - lib/melon/example.rb
         
     | 
| 
       92 
98 
     | 
    
         
             
            - lib/melon/hasher.rb
         
     | 
| 
       93 
99 
     | 
    
         
             
            - lib/melon/helpers.rb
         
     |