claide-plugins 0.9.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.
- checksums.yaml +7 -0
 - data/.gitignore +41 -0
 - data/.rubocop.yml +4 -0
 - data/.rubocop_cocoapods.yml +116 -0
 - data/.tm_properties +2 -0
 - data/.travis.yml +24 -0
 - data/CHANGELOG.md +113 -0
 - data/Gemfile +18 -0
 - data/Gemfile.lock +82 -0
 - data/LICENSE +21 -0
 - data/README.md +44 -0
 - data/Rakefile +55 -0
 - data/claide-plugins.gemspec +32 -0
 - data/lib/claide/command/gem_helper.rb +120 -0
 - data/lib/claide/command/gem_index_cache.rb +87 -0
 - data/lib/claide/command/plugins.rb +47 -0
 - data/lib/claide/command/plugins/create.rb +121 -0
 - data/lib/claide/command/plugins/list.rb +34 -0
 - data/lib/claide/command/plugins/search.rb +60 -0
 - data/lib/claide/command/plugins_config.rb +35 -0
 - data/lib/claide/command/plugins_helper.rb +134 -0
 - data/lib/claide/executable.rb +116 -0
 - data/lib/claide_plugin.rb +1 -0
 - data/lib/claide_plugins.rb +3 -0
 - data/spec/command/gem_helper_spec.rb +41 -0
 - data/spec/command/gem_index_cache_spec.rb +38 -0
 - data/spec/command/plugins/create_spec.rb +89 -0
 - data/spec/command/plugins/list_spec.rb +29 -0
 - data/spec/command/plugins/search_spec.rb +55 -0
 - data/spec/command/plugins_helper_spec.rb +33 -0
 - data/spec/command/plugins_spec.rb +45 -0
 - data/spec/fixtures/claide-foo1.gemspec +10 -0
 - data/spec/fixtures/claide-foo2.gemspec +9 -0
 - data/spec/fixtures/plugins.json +22 -0
 - data/spec/fixtures/unprefixed.gemspec +10 -0
 - data/spec/spec_helper.rb +93 -0
 - metadata +165 -0
 
| 
         @@ -0,0 +1,34 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'claide/command/plugins_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'claide/command/gem_helper'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module CLAide
         
     | 
| 
      
 5 
     | 
    
         
            +
              class Command
         
     | 
| 
      
 6 
     | 
    
         
            +
                class Plugins
         
     | 
| 
      
 7 
     | 
    
         
            +
                  # The list subcommand. Used to list all known plugins
         
     | 
| 
      
 8 
     | 
    
         
            +
                  #
         
     | 
| 
      
 9 
     | 
    
         
            +
                  class List < Plugins
         
     | 
| 
      
 10 
     | 
    
         
            +
                    self.summary = 'List all known plugins'
         
     | 
| 
      
 11 
     | 
    
         
            +
                    self.description = <<-DESC
         
     | 
| 
      
 12 
     | 
    
         
            +
                            List all known plugins (according to the list
         
     | 
| 
      
 13 
     | 
    
         
            +
                            hosted on github.com/CocoaPods/cocoapods-plugins)
         
     | 
| 
      
 14 
     | 
    
         
            +
                    DESC
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                    def self.options
         
     | 
| 
      
 17 
     | 
    
         
            +
                      super.reject { |option, _| option == '--silent' }
         
     | 
| 
      
 18 
     | 
    
         
            +
                    end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                    def run
         
     | 
| 
      
 21 
     | 
    
         
            +
                      plugins = PluginsHelper.known_plugins
         
     | 
| 
      
 22 
     | 
    
         
            +
                      GemHelper.download_and_cache_specs if self.verbose?
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                      name = CLAide::Plugins.config.name
         
     | 
| 
      
 25 
     | 
    
         
            +
                      UI.title "Available #{name} Plugins:" do
         
     | 
| 
      
 26 
     | 
    
         
            +
                        plugins.each do |plugin|
         
     | 
| 
      
 27 
     | 
    
         
            +
                          PluginsHelper.print_plugin plugin, self.verbose?
         
     | 
| 
      
 28 
     | 
    
         
            +
                        end
         
     | 
| 
      
 29 
     | 
    
         
            +
                      end
         
     | 
| 
      
 30 
     | 
    
         
            +
                    end
         
     | 
| 
      
 31 
     | 
    
         
            +
                  end
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,60 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'claide/command/plugins_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'claide/command/gem_helper'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'claide/command'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            module CLAide
         
     | 
| 
      
 6 
     | 
    
         
            +
              class Command
         
     | 
| 
      
 7 
     | 
    
         
            +
                class Plugins
         
     | 
| 
      
 8 
     | 
    
         
            +
                  # The search subcommand.
         
     | 
| 
      
 9 
     | 
    
         
            +
                  # Used to search a plugin in the list of known plugins,
         
     | 
| 
      
 10 
     | 
    
         
            +
                  # searching into the name, author description fields
         
     | 
| 
      
 11 
     | 
    
         
            +
                  #
         
     | 
| 
      
 12 
     | 
    
         
            +
                  class Search < Plugins
         
     | 
| 
      
 13 
     | 
    
         
            +
                    self.summary = 'Search for known plugins'
         
     | 
| 
      
 14 
     | 
    
         
            +
                    self.description = <<-DESC
         
     | 
| 
      
 15 
     | 
    
         
            +
                            Searches plugins whose 'name' contains the given `QUERY`.
         
     | 
| 
      
 16 
     | 
    
         
            +
                            `QUERY` is a regular expression, ignoring case.
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                            With `--full`, it also searches by 'author' and 'description'.
         
     | 
| 
      
 19 
     | 
    
         
            +
                    DESC
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                    self.arguments = [
         
     | 
| 
      
 22 
     | 
    
         
            +
                      CLAide::Argument.new('QUERY', true),
         
     | 
| 
      
 23 
     | 
    
         
            +
                    ]
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                    def self.options
         
     | 
| 
      
 26 
     | 
    
         
            +
                      [
         
     | 
| 
      
 27 
     | 
    
         
            +
                        ['--full',  'Search by name, author, and description'],
         
     | 
| 
      
 28 
     | 
    
         
            +
                      ].concat(super.reject { |option, _| option == '--silent' })
         
     | 
| 
      
 29 
     | 
    
         
            +
                    end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                    def initialize(argv)
         
     | 
| 
      
 32 
     | 
    
         
            +
                      @full_text_search = argv.flag?('full')
         
     | 
| 
      
 33 
     | 
    
         
            +
                      @query = argv.shift_argument unless argv.arguments.empty?
         
     | 
| 
      
 34 
     | 
    
         
            +
                      super
         
     | 
| 
      
 35 
     | 
    
         
            +
                    end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                    def validate!
         
     | 
| 
      
 38 
     | 
    
         
            +
                      super
         
     | 
| 
      
 39 
     | 
    
         
            +
                      help! 'A search query is required.' if @query.nil? || @query.empty?
         
     | 
| 
      
 40 
     | 
    
         
            +
                      begin
         
     | 
| 
      
 41 
     | 
    
         
            +
                        /#{@query}/
         
     | 
| 
      
 42 
     | 
    
         
            +
                      rescue RegexpError
         
     | 
| 
      
 43 
     | 
    
         
            +
                        help! 'A valid regular expression is required.'
         
     | 
| 
      
 44 
     | 
    
         
            +
                      end
         
     | 
| 
      
 45 
     | 
    
         
            +
                    end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                    def run
         
     | 
| 
      
 48 
     | 
    
         
            +
                      plugins = PluginsHelper.matching_plugins(@query, @full_text_search)
         
     | 
| 
      
 49 
     | 
    
         
            +
                      GemHelper.download_and_cache_specs if self.verbose?
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                      name = CLAide::Plugins.config.name
         
     | 
| 
      
 52 
     | 
    
         
            +
                      UI.title "Available #{name} Plugins matching '#{@query}':"
         
     | 
| 
      
 53 
     | 
    
         
            +
                      plugins.each do |plugin|
         
     | 
| 
      
 54 
     | 
    
         
            +
                        PluginsHelper.print_plugin plugin, self.verbose?
         
     | 
| 
      
 55 
     | 
    
         
            +
                      end
         
     | 
| 
      
 56 
     | 
    
         
            +
                    end
         
     | 
| 
      
 57 
     | 
    
         
            +
                  end
         
     | 
| 
      
 58 
     | 
    
         
            +
                end
         
     | 
| 
      
 59 
     | 
    
         
            +
              end
         
     | 
| 
      
 60 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,35 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'claide'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module CLAide
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Plugins
         
     | 
| 
      
 5 
     | 
    
         
            +
                class Configuration
         
     | 
| 
      
 6 
     | 
    
         
            +
                  # name of the plugin
         
     | 
| 
      
 7 
     | 
    
         
            +
                  attr_accessor :name
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                  # prefix to use when searching for gems to load at runtime
         
     | 
| 
      
 10 
     | 
    
         
            +
                  attr_accessor :plugin_prefix
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                  # url for JSON file that holds list of plugins to show when searching
         
     | 
| 
      
 13 
     | 
    
         
            +
                  attr_accessor :plugin_list_url
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                  # url for repo that holds template to use when creating a new plugin
         
     | 
| 
      
 16 
     | 
    
         
            +
                  attr_accessor :plugin_template_url
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                  def initialize(name = 'default name',
         
     | 
| 
      
 19 
     | 
    
         
            +
                                 plugin_prefix = 'claide',
         
     | 
| 
      
 20 
     | 
    
         
            +
                                 plugin_list_url = 'https://github.com/cocoapods/claide-plugins/something.json',
         
     | 
| 
      
 21 
     | 
    
         
            +
                                 plugin_template_url = 'https://github.com/cocoapods/claide-plugins-template')
         
     | 
| 
      
 22 
     | 
    
         
            +
                    @name = name
         
     | 
| 
      
 23 
     | 
    
         
            +
                    @plugin_prefix = plugin_prefix
         
     | 
| 
      
 24 
     | 
    
         
            +
                    @plugin_list_url = plugin_list_url
         
     | 
| 
      
 25 
     | 
    
         
            +
                    @plugin_template_url = plugin_template_url
         
     | 
| 
      
 26 
     | 
    
         
            +
                  end
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                class << self
         
     | 
| 
      
 30 
     | 
    
         
            +
                  attr_accessor :config
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
                # set a default configuration that will work with claide-plugins
         
     | 
| 
      
 33 
     | 
    
         
            +
                self.config = Configuration.new
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,134 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'claide/command/gem_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module CLAide
         
     | 
| 
      
 4 
     | 
    
         
            +
              class Command
         
     | 
| 
      
 5 
     | 
    
         
            +
                # This module is used by Command::Plugins::List
         
     | 
| 
      
 6 
     | 
    
         
            +
                # and Command::Plugins::Search to download and parse
         
     | 
| 
      
 7 
     | 
    
         
            +
                # the JSON describing the plugins list and manipulate it
         
     | 
| 
      
 8 
     | 
    
         
            +
                #
         
     | 
| 
      
 9 
     | 
    
         
            +
                module PluginsHelper
         
     | 
| 
      
 10 
     | 
    
         
            +
                  def self.plugins_raw_url
         
     | 
| 
      
 11 
     | 
    
         
            +
                    CLAide::Plugins.config.plugin_list_url
         
     | 
| 
      
 12 
     | 
    
         
            +
                  end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  # Force-download the JSON
         
     | 
| 
      
 15 
     | 
    
         
            +
                  #
         
     | 
| 
      
 16 
     | 
    
         
            +
                  # @return [Hash] The hash representing the JSON with all known plugins
         
     | 
| 
      
 17 
     | 
    
         
            +
                  #
         
     | 
| 
      
 18 
     | 
    
         
            +
                  def self.download_json
         
     | 
| 
      
 19 
     | 
    
         
            +
                    UI.puts 'Downloading Plugins list...'
         
     | 
| 
      
 20 
     | 
    
         
            +
                    response = REST.get(plugins_raw_url)
         
     | 
| 
      
 21 
     | 
    
         
            +
                    if response.ok?
         
     | 
| 
      
 22 
     | 
    
         
            +
                      parse_json(response.body)
         
     | 
| 
      
 23 
     | 
    
         
            +
                    else
         
     | 
| 
      
 24 
     | 
    
         
            +
                      raise Informative, 'Could not download plugins list ' \
         
     | 
| 
      
 25 
     | 
    
         
            +
                        "from cocoapods-plugins: #{response.inspect}"
         
     | 
| 
      
 26 
     | 
    
         
            +
                    end
         
     | 
| 
      
 27 
     | 
    
         
            +
                  end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                  # The list of all known plugins, according to
         
     | 
| 
      
 30 
     | 
    
         
            +
                  # the JSON hosted on github's cocoapods-plugins
         
     | 
| 
      
 31 
     | 
    
         
            +
                  #
         
     | 
| 
      
 32 
     | 
    
         
            +
                  # @return [Array] all known plugins, as listed in the downloaded JSON
         
     | 
| 
      
 33 
     | 
    
         
            +
                  #
         
     | 
| 
      
 34 
     | 
    
         
            +
                  def self.known_plugins
         
     | 
| 
      
 35 
     | 
    
         
            +
                    json = download_json
         
     | 
| 
      
 36 
     | 
    
         
            +
                    json['plugins']
         
     | 
| 
      
 37 
     | 
    
         
            +
                  end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                  # Filter plugins to return only matching ones
         
     | 
| 
      
 40 
     | 
    
         
            +
                  #
         
     | 
| 
      
 41 
     | 
    
         
            +
                  # @param [String] query
         
     | 
| 
      
 42 
     | 
    
         
            +
                  #        A query string that corresponds to a valid RegExp pattern.
         
     | 
| 
      
 43 
     | 
    
         
            +
                  #
         
     | 
| 
      
 44 
     | 
    
         
            +
                  # @param [Bool] full_text_search
         
     | 
| 
      
 45 
     | 
    
         
            +
                  #        false only searches in the plugin's name.
         
     | 
| 
      
 46 
     | 
    
         
            +
                  #        true searches in the plugin's name, author and description.
         
     | 
| 
      
 47 
     | 
    
         
            +
                  #
         
     | 
| 
      
 48 
     | 
    
         
            +
                  # @return [Array] all plugins matching the query
         
     | 
| 
      
 49 
     | 
    
         
            +
                  #
         
     | 
| 
      
 50 
     | 
    
         
            +
                  def self.matching_plugins(query, full_text_search)
         
     | 
| 
      
 51 
     | 
    
         
            +
                    query_regexp = /#{query}/i
         
     | 
| 
      
 52 
     | 
    
         
            +
                    known_plugins.reject do |plugin|
         
     | 
| 
      
 53 
     | 
    
         
            +
                      texts = [plugin['name']]
         
     | 
| 
      
 54 
     | 
    
         
            +
                      if full_text_search
         
     | 
| 
      
 55 
     | 
    
         
            +
                        texts << plugin['author'] if plugin['author']
         
     | 
| 
      
 56 
     | 
    
         
            +
                        texts << plugin['description'] if plugin['description']
         
     | 
| 
      
 57 
     | 
    
         
            +
                      end
         
     | 
| 
      
 58 
     | 
    
         
            +
                      texts.grep(query_regexp).empty?
         
     | 
| 
      
 59 
     | 
    
         
            +
                    end
         
     | 
| 
      
 60 
     | 
    
         
            +
                  end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                  # Display information about a plugin
         
     | 
| 
      
 63 
     | 
    
         
            +
                  #
         
     | 
| 
      
 64 
     | 
    
         
            +
                  # @param [Hash] plugin
         
     | 
| 
      
 65 
     | 
    
         
            +
                  #        The hash describing the plugin
         
     | 
| 
      
 66 
     | 
    
         
            +
                  #
         
     | 
| 
      
 67 
     | 
    
         
            +
                  # @param [Bool] verbose
         
     | 
| 
      
 68 
     | 
    
         
            +
                  #        If true, will also print the author of the plugins.
         
     | 
| 
      
 69 
     | 
    
         
            +
                  #        Defaults to false.
         
     | 
| 
      
 70 
     | 
    
         
            +
                  #
         
     | 
| 
      
 71 
     | 
    
         
            +
                  def self.print_plugin(plugin, verbose = false)
         
     | 
| 
      
 72 
     | 
    
         
            +
                    plugin_colored_name = plugin_title(plugin)
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
                    UI.title(plugin_colored_name, '', 1) do
         
     | 
| 
      
 75 
     | 
    
         
            +
                      UI.puts_indented plugin['description']
         
     | 
| 
      
 76 
     | 
    
         
            +
                      ljust = verbose ? 16 : 11
         
     | 
| 
      
 77 
     | 
    
         
            +
                      UI.labeled('Gem', plugin['gem'], ljust)
         
     | 
| 
      
 78 
     | 
    
         
            +
                      UI.labeled('URL', plugin['url'], ljust)
         
     | 
| 
      
 79 
     | 
    
         
            +
                      print_verbose_plugin(plugin, ljust) if verbose
         
     | 
| 
      
 80 
     | 
    
         
            +
                    end
         
     | 
| 
      
 81 
     | 
    
         
            +
                  end
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
                  #----------------#
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
                  private
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
                  # Smaller helper to print out the verbose details
         
     | 
| 
      
 88 
     | 
    
         
            +
                  # for a plugin.
         
     | 
| 
      
 89 
     | 
    
         
            +
                  #
         
     | 
| 
      
 90 
     | 
    
         
            +
                  # @param [Hash] plugin
         
     | 
| 
      
 91 
     | 
    
         
            +
                  #        The hash describing the plugin
         
     | 
| 
      
 92 
     | 
    
         
            +
                  #
         
     | 
| 
      
 93 
     | 
    
         
            +
                  # @param [Integer] ljust
         
     | 
| 
      
 94 
     | 
    
         
            +
                  #        The left justification that is passed into UI.labeled
         
     | 
| 
      
 95 
     | 
    
         
            +
                  #
         
     | 
| 
      
 96 
     | 
    
         
            +
                  def self.print_verbose_plugin(plugin, ljust)
         
     | 
| 
      
 97 
     | 
    
         
            +
                    UI.labeled('Author', plugin['author'], ljust)
         
     | 
| 
      
 98 
     | 
    
         
            +
                    unless GemHelper.cache.specs.empty?
         
     | 
| 
      
 99 
     | 
    
         
            +
                      versions = GemHelper.versions_string(plugin['gem'])
         
     | 
| 
      
 100 
     | 
    
         
            +
                      UI.labeled('Versions', versions, ljust)
         
     | 
| 
      
 101 
     | 
    
         
            +
                    end
         
     | 
| 
      
 102 
     | 
    
         
            +
                  end
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
                  # Parse the given JSON data, handling parsing errors if any
         
     | 
| 
      
 105 
     | 
    
         
            +
                  #
         
     | 
| 
      
 106 
     | 
    
         
            +
                  # @param [String] json_str
         
     | 
| 
      
 107 
     | 
    
         
            +
                  #        The string representation of the JSON to parse
         
     | 
| 
      
 108 
     | 
    
         
            +
                  #
         
     | 
| 
      
 109 
     | 
    
         
            +
                  def self.parse_json(json_str)
         
     | 
| 
      
 110 
     | 
    
         
            +
                    JSON.parse(json_str)
         
     | 
| 
      
 111 
     | 
    
         
            +
                  rescue JSON::ParserError => e
         
     | 
| 
      
 112 
     | 
    
         
            +
                    raise Informative, "Invalid plugins list from cocoapods-plugins: #{e}"
         
     | 
| 
      
 113 
     | 
    
         
            +
                  end
         
     | 
| 
      
 114 
     | 
    
         
            +
             
     | 
| 
      
 115 
     | 
    
         
            +
                  # Format the title line to print the plugin info with print_plugin
         
     | 
| 
      
 116 
     | 
    
         
            +
                  # coloring it according to whether the plugin is installed or not
         
     | 
| 
      
 117 
     | 
    
         
            +
                  #
         
     | 
| 
      
 118 
     | 
    
         
            +
                  # @param [Hash] plugin
         
     | 
| 
      
 119 
     | 
    
         
            +
                  #               The hash describing the plugin
         
     | 
| 
      
 120 
     | 
    
         
            +
                  #
         
     | 
| 
      
 121 
     | 
    
         
            +
                  # @return [String] The formatted and colored title
         
     | 
| 
      
 122 
     | 
    
         
            +
                  #
         
     | 
| 
      
 123 
     | 
    
         
            +
                  def self.plugin_title(plugin)
         
     | 
| 
      
 124 
     | 
    
         
            +
                    plugin_name = "-> #{plugin['name']}"
         
     | 
| 
      
 125 
     | 
    
         
            +
                    if GemHelper.gem_installed?(plugin['gem'])
         
     | 
| 
      
 126 
     | 
    
         
            +
                      plugin_name += " (#{GemHelper.installed_version(plugin['gem'])})"
         
     | 
| 
      
 127 
     | 
    
         
            +
                      plugin_name.green
         
     | 
| 
      
 128 
     | 
    
         
            +
                    else
         
     | 
| 
      
 129 
     | 
    
         
            +
                      plugin_name.yellow
         
     | 
| 
      
 130 
     | 
    
         
            +
                    end
         
     | 
| 
      
 131 
     | 
    
         
            +
                  end
         
     | 
| 
      
 132 
     | 
    
         
            +
                end
         
     | 
| 
      
 133 
     | 
    
         
            +
              end
         
     | 
| 
      
 134 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,116 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module CLAide
         
     | 
| 
      
 2 
     | 
    
         
            +
              # Module which provides support for running executables.
         
     | 
| 
      
 3 
     | 
    
         
            +
              #
         
     | 
| 
      
 4 
     | 
    
         
            +
              # In a class it can be used as:
         
     | 
| 
      
 5 
     | 
    
         
            +
              #
         
     | 
| 
      
 6 
     | 
    
         
            +
              #     extend Executable
         
     | 
| 
      
 7 
     | 
    
         
            +
              #     executable :git
         
     | 
| 
      
 8 
     | 
    
         
            +
              #
         
     | 
| 
      
 9 
     | 
    
         
            +
              # This will create two methods `git` and `git!` both accept a command but
         
     | 
| 
      
 10 
     | 
    
         
            +
              # the latter will raise on non successful executions. The methods return the
         
     | 
| 
      
 11 
     | 
    
         
            +
              # output of the command.
         
     | 
| 
      
 12 
     | 
    
         
            +
              #
         
     | 
| 
      
 13 
     | 
    
         
            +
              module Executable
         
     | 
| 
      
 14 
     | 
    
         
            +
                # Creates the methods for the executable with the given name.
         
     | 
| 
      
 15 
     | 
    
         
            +
                #
         
     | 
| 
      
 16 
     | 
    
         
            +
                # @param  [Symbol] name
         
     | 
| 
      
 17 
     | 
    
         
            +
                #         the name of the executable.
         
     | 
| 
      
 18 
     | 
    
         
            +
                #
         
     | 
| 
      
 19 
     | 
    
         
            +
                # @return [void]
         
     | 
| 
      
 20 
     | 
    
         
            +
                #
         
     | 
| 
      
 21 
     | 
    
         
            +
                def executable(name)
         
     | 
| 
      
 22 
     | 
    
         
            +
                  define_method(name) do |*command|
         
     | 
| 
      
 23 
     | 
    
         
            +
                    Executable.execute_command(name, Array(command).flatten, false)
         
     | 
| 
      
 24 
     | 
    
         
            +
                  end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                  define_method(name.to_s + '!') do |*command|
         
     | 
| 
      
 27 
     | 
    
         
            +
                    Executable.execute_command(name, Array(command).flatten, true)
         
     | 
| 
      
 28 
     | 
    
         
            +
                  end
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                # Executes the given command. Displays output if in verbose mode.
         
     | 
| 
      
 32 
     | 
    
         
            +
                #
         
     | 
| 
      
 33 
     | 
    
         
            +
                # @param  [String] bin
         
     | 
| 
      
 34 
     | 
    
         
            +
                #         The binary to use.
         
     | 
| 
      
 35 
     | 
    
         
            +
                #
         
     | 
| 
      
 36 
     | 
    
         
            +
                # @param  [Array<#to_s>] command
         
     | 
| 
      
 37 
     | 
    
         
            +
                #         The command to send to the binary.
         
     | 
| 
      
 38 
     | 
    
         
            +
                #
         
     | 
| 
      
 39 
     | 
    
         
            +
                # @param  [Bool] raise_on_failure
         
     | 
| 
      
 40 
     | 
    
         
            +
                #         Whether it should raise if the command fails.
         
     | 
| 
      
 41 
     | 
    
         
            +
                #
         
     | 
| 
      
 42 
     | 
    
         
            +
                # @raise  If the executable could not be located.
         
     | 
| 
      
 43 
     | 
    
         
            +
                #
         
     | 
| 
      
 44 
     | 
    
         
            +
                # @raise  If the command fails and the `raise_on_failure` is set to true.
         
     | 
| 
      
 45 
     | 
    
         
            +
                #
         
     | 
| 
      
 46 
     | 
    
         
            +
                # @return [String] the output of the command (STDOUT and STDERR).
         
     | 
| 
      
 47 
     | 
    
         
            +
                #
         
     | 
| 
      
 48 
     | 
    
         
            +
                # @todo   Find a way to display the live output of the commands.
         
     | 
| 
      
 49 
     | 
    
         
            +
                #
         
     | 
| 
      
 50 
     | 
    
         
            +
                def self.execute_command(exe, command, raise_on_failure)
         
     | 
| 
      
 51 
     | 
    
         
            +
                  bin = `which #{exe}`.strip
         
     | 
| 
      
 52 
     | 
    
         
            +
                  raise Informative, "Unable to locate `#{exe}`" if bin.empty?
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                  require 'open4'
         
     | 
| 
      
 55 
     | 
    
         
            +
                  require 'shellwords'
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                  command = command.map(&:to_s)
         
     | 
| 
      
 58 
     | 
    
         
            +
                  full_command = \
         
     | 
| 
      
 59 
     | 
    
         
            +
                    "#{bin.shellescape} #{command.map(&:shellescape).join(' ')}"
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                  # if Config.instance.verbose?
         
     | 
| 
      
 62 
     | 
    
         
            +
                  # UI.message("$ #{full_command}")
         
     | 
| 
      
 63 
     | 
    
         
            +
                  # stdout, stderr = Indenter.new(STDOUT), Indenter.new(STDERR)
         
     | 
| 
      
 64 
     | 
    
         
            +
                  # else
         
     | 
| 
      
 65 
     | 
    
         
            +
                  stdout, stderr = Indenter.new, Indenter.new
         
     | 
| 
      
 66 
     | 
    
         
            +
                  # end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                  options = { :stdout => stdout, :stderr => stderr, :status => true }
         
     | 
| 
      
 69 
     | 
    
         
            +
                  status  = Open4.spawn(bin, command, options)
         
     | 
| 
      
 70 
     | 
    
         
            +
                  output  = stdout.join("\n") + stderr.join("\n")
         
     | 
| 
      
 71 
     | 
    
         
            +
                  unless status.success?
         
     | 
| 
      
 72 
     | 
    
         
            +
                    if raise_on_failure
         
     | 
| 
      
 73 
     | 
    
         
            +
                      raise Informative, "#{full_command}\n\n#{output}"
         
     | 
| 
      
 74 
     | 
    
         
            +
                    else
         
     | 
| 
      
 75 
     | 
    
         
            +
                      UI.message("[!] Failed: #{full_command}".red)
         
     | 
| 
      
 76 
     | 
    
         
            +
                    end
         
     | 
| 
      
 77 
     | 
    
         
            +
                  end
         
     | 
| 
      
 78 
     | 
    
         
            +
                  output
         
     | 
| 
      
 79 
     | 
    
         
            +
                end
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                #-------------------------------------------------------------------------#
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
                # Helper class that allows to write to an {IO} instance taking into account
         
     | 
| 
      
 84 
     | 
    
         
            +
                # the UI indentation level.
         
     | 
| 
      
 85 
     | 
    
         
            +
                #
         
     | 
| 
      
 86 
     | 
    
         
            +
                class Indenter < ::Array
         
     | 
| 
      
 87 
     | 
    
         
            +
                  # @return [Fixnum] The indentation level of the UI.
         
     | 
| 
      
 88 
     | 
    
         
            +
                  #
         
     | 
| 
      
 89 
     | 
    
         
            +
                  attr_accessor :indent
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
                  # @return [IO] the {IO} to which the output should be printed.
         
     | 
| 
      
 92 
     | 
    
         
            +
                  #
         
     | 
| 
      
 93 
     | 
    
         
            +
                  attr_accessor :io
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
                  # @param [IO] io @see io
         
     | 
| 
      
 96 
     | 
    
         
            +
                  #
         
     | 
| 
      
 97 
     | 
    
         
            +
                  def initialize(io = nil)
         
     | 
| 
      
 98 
     | 
    
         
            +
                    @io = io
         
     | 
| 
      
 99 
     | 
    
         
            +
                    @indent = ' ' * UI.indentation_level
         
     | 
| 
      
 100 
     | 
    
         
            +
                  end
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
                  # Stores a portion of the output and prints it to the {IO} instance.
         
     | 
| 
      
 103 
     | 
    
         
            +
                  #
         
     | 
| 
      
 104 
     | 
    
         
            +
                  # @param  [String] value
         
     | 
| 
      
 105 
     | 
    
         
            +
                  #         the output to print.
         
     | 
| 
      
 106 
     | 
    
         
            +
                  #
         
     | 
| 
      
 107 
     | 
    
         
            +
                  # @return [void]
         
     | 
| 
      
 108 
     | 
    
         
            +
                  #
         
     | 
| 
      
 109 
     | 
    
         
            +
                  def <<(value)
         
     | 
| 
      
 110 
     | 
    
         
            +
                    super
         
     | 
| 
      
 111 
     | 
    
         
            +
                  ensure
         
     | 
| 
      
 112 
     | 
    
         
            +
                    @io << "#{ indent }#{ value }" if @io
         
     | 
| 
      
 113 
     | 
    
         
            +
                  end
         
     | 
| 
      
 114 
     | 
    
         
            +
                end
         
     | 
| 
      
 115 
     | 
    
         
            +
              end
         
     | 
| 
      
 116 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'claide/command/plugins'
         
     | 
| 
         @@ -0,0 +1,41 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require File.expand_path('../spec_helper', File.dirname(__FILE__))
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'claide/command/gem_helper'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            # The CLAide namespace
         
     | 
| 
      
 5 
     | 
    
         
            +
            #
         
     | 
| 
      
 6 
     | 
    
         
            +
            module CLAide
         
     | 
| 
      
 7 
     | 
    
         
            +
              describe Command::GemHelper do
         
     | 
| 
      
 8 
     | 
    
         
            +
                before do
         
     | 
| 
      
 9 
     | 
    
         
            +
                  UI_OUT.reopen
         
     | 
| 
      
 10 
     | 
    
         
            +
                end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                after do
         
     | 
| 
      
 13 
     | 
    
         
            +
                  mocha_teardown
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                it 'detects if a gem is installed' do
         
     | 
| 
      
 17 
     | 
    
         
            +
                  Command::GemHelper.gem_installed?('bacon').should.be.true
         
     | 
| 
      
 18 
     | 
    
         
            +
                  Command::GemHelper.gem_installed?('fake-fake-fake-gem').should.be.false
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                it 'detects if a specific version of a gem is installed' do
         
     | 
| 
      
 22 
     | 
    
         
            +
                  Command::GemHelper.gem_installed?('bacon', Bacon::VERSION).should.be.true
         
     | 
| 
      
 23 
     | 
    
         
            +
                  impossibacon = Gem::Version.new(Bacon::VERSION).bump
         
     | 
| 
      
 24 
     | 
    
         
            +
                  Command::GemHelper.gem_installed?('bacon', impossibacon).should.be.false
         
     | 
| 
      
 25 
     | 
    
         
            +
                end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                it 'creates a version list that includes all versions of a single gem' do
         
     | 
| 
      
 28 
     | 
    
         
            +
                  spec2 = Gem::NameTuple.new('cocoapods-plugins', Gem::Version.new('0.2.0'))
         
     | 
| 
      
 29 
     | 
    
         
            +
                  spec1 = Gem::NameTuple.new('cocoapods-plugins', Gem::Version.new('0.1.0'))
         
     | 
| 
      
 30 
     | 
    
         
            +
                  response = [{ 1 => [spec2, spec1] }, []]
         
     | 
| 
      
 31 
     | 
    
         
            +
                  Gem::SpecFetcher.any_instance.stubs(:available_specs).returns(response)
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                  @cache = Command::GemIndexCache.new
         
     | 
| 
      
 34 
     | 
    
         
            +
                  @cache.download_and_cache_specs
         
     | 
| 
      
 35 
     | 
    
         
            +
                  versions_string =
         
     | 
| 
      
 36 
     | 
    
         
            +
                    Command::GemHelper.versions_string('cocoapods-plugins', @cache)
         
     | 
| 
      
 37 
     | 
    
         
            +
                  versions_string.should.include('0.2.0')
         
     | 
| 
      
 38 
     | 
    
         
            +
                  versions_string.should.include('0.1.0')
         
     | 
| 
      
 39 
     | 
    
         
            +
                end
         
     | 
| 
      
 40 
     | 
    
         
            +
              end
         
     | 
| 
      
 41 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,38 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require File.expand_path('../spec_helper', File.dirname(__FILE__))
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            # The CocoaPods namespace
         
     | 
| 
      
 4 
     | 
    
         
            +
            #
         
     | 
| 
      
 5 
     | 
    
         
            +
            module CLAide
         
     | 
| 
      
 6 
     | 
    
         
            +
              describe Command::GemIndexCache do
         
     | 
| 
      
 7 
     | 
    
         
            +
                before do
         
     | 
| 
      
 8 
     | 
    
         
            +
                  @cache = Command::GemIndexCache.new
         
     | 
| 
      
 9 
     | 
    
         
            +
                  UI_OUT.reopen
         
     | 
| 
      
 10 
     | 
    
         
            +
                end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                after do
         
     | 
| 
      
 13 
     | 
    
         
            +
                  mocha_teardown
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                it 'notifies the user that it is downloading the spec index' do
         
     | 
| 
      
 17 
     | 
    
         
            +
                  response = [{}, []]
         
     | 
| 
      
 18 
     | 
    
         
            +
                  Gem::SpecFetcher.any_instance.stubs(:available_specs).returns(response)
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                  @cache.download_and_cache_specs
         
     | 
| 
      
 21 
     | 
    
         
            +
                  out = UI_OUT.string
         
     | 
| 
      
 22 
     | 
    
         
            +
                  out.should.include('Downloading Rubygem specification index...')
         
     | 
| 
      
 23 
     | 
    
         
            +
                  out.should.not.include('Error downloading Rubygem specification')
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                it 'notifies the user when getting the spec index fails' do
         
     | 
| 
      
 27 
     | 
    
         
            +
                  error = Gem::RemoteFetcher::FetchError.new('no host', 'bad url')
         
     | 
| 
      
 28 
     | 
    
         
            +
                  wrapper_error = stub(:error => error)
         
     | 
| 
      
 29 
     | 
    
         
            +
                  response = [[], [wrapper_error]]
         
     | 
| 
      
 30 
     | 
    
         
            +
                  Gem::SpecFetcher.any_instance.stubs(:available_specs).returns(response)
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                  @cache.download_and_cache_specs
         
     | 
| 
      
 33 
     | 
    
         
            +
                  @cache.specs.should.be.empty?
         
     | 
| 
      
 34 
     | 
    
         
            +
                  UI_OUT.string.should.include('Downloading Rubygem specification index...')
         
     | 
| 
      
 35 
     | 
    
         
            +
                  UI_OUT.string.should.include('Error downloading Rubygem specification')
         
     | 
| 
      
 36 
     | 
    
         
            +
                end
         
     | 
| 
      
 37 
     | 
    
         
            +
              end
         
     | 
| 
      
 38 
     | 
    
         
            +
            end
         
     |