Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Improved pod list #188

Merged
merged 12 commits into from

2 participants

@fabiopelosin

Inspired by Specs#79. The code is still a bit a ugly.

IMG

$ pod list --help
List all pods:

    $ pod list

      Lists all available pods.

    $ pod list [DAYS]

      Lists the pods introduced in the master repo since the given number of days.

Options
-------

    --stats     Show additional stats (like GitHub watchers and forks)
    --help      Show help information
    --silent    Print nothing
    --verbose   Print more information while working
    --version   Prints the version of CocoaPods
lib/cocoapods/command/print_pod.rb
((2 lines not shown))
+ class Command
+ module DisplayPods
+
+ def display_pod_list(array, stats = false)
+ array.each do |set|
+ puts_pod(set, stats)
+ end
+ end
+
+ def puts_pod(set, stats = false)
+ puts "\e[32m--> #{set.name} (#{set.versions.reverse.join(", ")})\e[0m"
+ puts_wrapped_text(set.specification.summary)
+
+ spec = set.specification.part_of_other_pod? ? set.specification.part_of_specification : set.specification
+
+ source = spec.source.reject {|k,_| k == :commit || k == :tag }.values.first
@alloy Owner
alloy added a note

Oops, good catch :)

@fabiopelosin Owner

Honestly, I introduced the bug... the previous code was good.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
lib/cocoapods/command.rb
@@ -1,6 +1,7 @@
module Pod
class Command
autoload :ErrorReport, 'cocoapods/command/error_report'
+ autoload :DisplayPods, 'cocoapods/command/print_pod'
@alloy Owner
alloy added a note

Can you name the file after the module? display_pods.rb

@fabiopelosin Owner

Oops, I forgot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@alloy
Owner

I like it, but I’d like to see some unit tests for the individual methods. That code is becoming more complex and could probably be refactored a bit afterwards.

@alloy

FYI Another thing I often do in cases like this is sort the list of names.

Good to now, thanks for the info.

@fabiopelosin

This was failing on Travis and the failure seems related to the following line. As I never used Travis, does somebody have an idea about why was it failing?

repo_info = `curl -s -m 2 http://github.com/api/v2/json/repos/show/#{username}/#{reponame}`
Owner

Since Travis runs on linux, there are often differences in order and sometimes with command-line options. I would start by copy-pasting the line from the Travis log that actually runs bacon and the files. Sometimes you can reproduce a bug simply by running the same command again.

If that doesn’t fix it, then you’d have to check on Travis. I have no problem with you printing out all sorts of info from the specs so that you can diagnose the problem :) Worst case scenario, you’d have to run the Travis VM locally, I already have it, so in that case I can take a loofa for you.

Mhmmm... now it works, but I didn't change anything. A network failure? (It happend only in ruby 1.9.3).

Owner

Oh yeah, that’s also very possible. Sometimes the Travis stack has an issue and the tests won’t even run, but it will still report that as a failing build… :-/

Mhmmm... I think that something more is going on. The failure reappeared again in the same line. It might be because curl is called with timeout of 2s (I didn't want to block search for too long). That should be an eternity for such a small request. @alloy what do your suggest? To remove the timeout?

Owner

It might be better to use something else than curl all together. E.g.:

require 'net/http'

stats = Net::HTTP.get('example.com', '/index.html')

This can then be stubbed in the tests like so:

Net::HTTP.expects(:get).with('example.com', '/index.html').returns("the data")
command.run
@fabiopelosin

@alloy What do you think? Is it ready?

@alloy
Owner

Yup, looks good, go gO GO! :)

@fabiopelosin fabiopelosin merged commit 22e342a into from
@fabiopelosin fabiopelosin referenced this pull request from a commit
@fabiopelosin fabiopelosin [#188] Cleanup 4e6cb45
@fabiopelosin fabiopelosin referenced this pull request from a commit
@fabiopelosin fabiopelosin [#188] Further cleanup 0aa2e79
@fabiopelosin fabiopelosin referenced this pull request from a commit
@fabiopelosin fabiopelosin [#188] cleanup 66220fd
@fabiopelosin fabiopelosin referenced this pull request from a commit
@fabiopelosin fabiopelosin [#188] Added tests f5891ee
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
4 .kick
@@ -12,3 +12,7 @@ process do |files|
end
Kicker::Recipes::Ruby.run_tests(specs)
end
+
+recipe :ignore
+ignore(/.*\/?tags/)
+ignore(/.*\/?\.git/)
View
1  lib/cocoapods/command.rb
@@ -1,6 +1,7 @@
module Pod
class Command
autoload :ErrorReport, 'cocoapods/command/error_report'
+ autoload :SetPresent, 'cocoapods/command/set_present'
autoload :Install, 'cocoapods/command/install'
autoload :List, 'cocoapods/command/list'
autoload :Repo, 'cocoapods/command/repo'
View
83 lib/cocoapods/command/list.rb
@@ -6,21 +6,96 @@ def self.banner
$ pod list
- Lists all available pods.}
+ Lists all available pods.
+
+ $ pod list [DAYS]
+
+ Lists the pods introduced in the master repo since the given number of days.}
+ end
+
+ def self.options
+ SetPresent.set_present_options +
+ super
end
+ include SetPresent
+ extend Executable
+ executable :git
+
def initialize(argv)
+ parse_set_options(argv)
+ @days = argv.arguments.first
+ unless @days == nil || @days =~ /^[0-9]+$/
+ super
+ end
end
- def run
+ def dir
+ config.repos_dir + 'master'
+ end
+
+ def dir_list_from_commit(commit)
+ Dir.chdir(dir) { git("ls-tree --name-only -r #{commit}") }
+ end
+
+ def commit_from_days_ago (days)
+ Dir.chdir(dir) { git("rev-list -n1 --before=\"#{days} day ago\" master") }
+ end
+
+ def spec_names_from_commit (commit)
+ dir_list = dir_list_from_commit(commit)
+
+ # Keep only subdirectories
+ dir_list.gsub!(/^[^\/]*$/,'')
+ # Keep only subdirectories name
+ dir_list.gsub!(/(.*)\/[0-9].*/,'\1')
+
+ result = dir_list.split("\n").uniq
+ result.delete('')
+ result
+ end
+
+ def new_specs_set(commit)
+ #TODO: find the changes for all repos
+ new_specs = spec_names_from_commit('HEAD') - spec_names_from_commit(commit)
+ sets = all_specs_set.select { |set| new_specs.include?(set.name) }
+ end
+
+ def all_specs_set
+ result = []
Source.all.each do |source|
source.pod_sets.each do |set|
- puts "==> #{set.name} (#{set.versions.reverse.join(", ")})"
- puts " #{set.specification.summary.strip}"
+ result << set
+ end
+ end
+ result
+ end
+
+ def list_new
+ sets = new_specs_set(commit_from_days_ago(@days))
+ present_sets(sets)
+ if !list
+ if sets.count != 0
+ puts "#{sets.count} new pods were added in the last #{@days} days"
+ puts
+ else
+ puts "No new pods were added in the last #{@days} days"
puts
end
end
end
+
+ def list_all
+ present_sets(all_specs_set)
+ end
+
+ def run
+ if @days
+ list_new
+ else
+ list_all
+ end
+ end
end
end
end
View
49 lib/cocoapods/command/search.rb
@@ -2,7 +2,7 @@ module Pod
class Command
class Search < Command
def self.banner
- %{Search pods:
+%{Search pods:
$ pod search [QUERY]
@@ -12,13 +12,15 @@ def self.banner
end
def self.options
- " --stats Show additional stats (like GitHub watchers and forks)\n" +
" --full Search by name, summary, and description\n" +
+ SetPresent.set_present_options +
super
end
+ include SetPresent
+
def initialize(argv)
- @stats = argv.option('--stats')
+ parse_set_options(argv)
@full_text_search = argv.option('--full')
unless @query = argv.arguments.first
super
@@ -26,45 +28,8 @@ def initialize(argv)
end
def run
- Source.search_by_name(@query.strip, @full_text_search).each do |set|
- puts "\e[32m--> #{set.name} (#{set.versions.reverse.join(", ")})\e[0m"
- puts_wrapped_text(set.specification.summary)
-
- spec = set.specification.part_of_other_pod? ? set.specification.part_of_specification : set.specification
-
- source = spec.source.reject {|k,_| k == :commit || k == :tag }.values.first
- puts_detail('Homepage', spec.homepage)
- puts_detail('Source', source)
- puts_github_info(source) if @stats
-
- puts
- end
- end
-
- # adapted from http://blog.macromates.com/2006/wrapping-text-with-regular-expressions/
- def puts_wrapped_text(txt, col = 80, indentation = 4)
- indent = ' ' * indentation
- puts txt.strip.gsub(/(.{1,#{col}})( +|$)\n?|(.{#{col}})/, indent + "\\1\\3\n")
- end
-
- def puts_detail(title,string)
- return if !string
- # 8 is the length of homepage which might be displayed alone
- number_of_spaces = ((8 - title.length) > 0) ? (8 - title.length) : 0
- spaces = ' ' * number_of_spaces
- puts " - #{title}: #{spaces + string}"
- end
-
- def puts_github_info(url)
- original_url, username, reponame = *(url.match(/[:\/]([\w\-]+)\/([\w\-]+)\.git/).to_a)
-
- if original_url
- repo_info = `curl -s -m 2 http://github.com/api/v2/json/repos/show/#{username}/#{reponame}`
- watchers = repo_info.match(/\"watchers\"\W*:\W*([0-9]+)/).to_a[1]
- forks = repo_info.match(/\"forks\"\W*:\W*([0-9]+)/).to_a[1]
- puts_detail('Watchers', watchers)
- puts_detail('Forks', forks)
- end
+ sets = Source.search_by_name(@query.strip, @full_text_search)
+ present_sets(sets)
end
end
end
View
73 lib/cocoapods/command/set_present.rb
@@ -0,0 +1,73 @@
+module Pod
+ class Command
+ module SetPresent
+ def self.set_present_options
+ " --name-only Show only the names of the pods\n" +
+ " --stats Show additional stats (like GitHub watchers and forks)\n"
+ end
+
+ def list
+ @list
+ end
+
+ def parse_set_options(argv)
+ @stats = argv.option('--stats')
+ @list = argv.option('--name-only')
+ end
+
+ def present_sets(array)
+ array.each do |set|
+ present_set(set)
+ end
+ end
+
+ def present_set(set)
+ if @list
+ puts set.name
+ else
+ puts "\e[32m--> #{set.name} (#{set.versions.reverse.join(", ")})\e[0m"
+ puts_wrapped_text(set.specification.summary)
+
+ spec = set.specification.part_of_other_pod? ? set.specification.part_of_specification : set.specification
+
+ source = spec.source.reject {|k,_| k == :commit || k == :tag }.values.first
+ puts_detail('Homepage', spec.homepage)
+ puts_detail('Source', source)
+
+ if @stats
+ stats = stats(source)
+ puts_detail('Watchers', stats[:watchers])
+ puts_detail('Forks', stats[:forks])
+ end
+ puts
+ end
+ end
+
+ # adapted from http://blog.macromates.com/2006/wrapping-text-with-regular-expressions/
+ def puts_wrapped_text(txt, col = 80, indentation = 4)
+ indent = ' ' * indentation
+ puts txt.strip.gsub(/(.{1,#{col}})( +|$)\n?|(.{#{col}})/, indent + "\\1\\3\n")
+ end
+
+ def puts_detail(title,string)
+ return if !string
+ # 8 is the length of homepage
+ number_of_spaces = ((8 - title.length) > 0) ? (8 - title.length) : 0
+ spaces = ' ' * number_of_spaces
+ puts " - #{title}: #{spaces + string}"
+ end
+
+ def stats(url)
+ original_url, username, reponame = *(url.match(/[:\/]([\w\-]+)\/([\w\-]+)\.git/).to_a)
+
+ result = {}
+ if original_url
+ repo_info = `curl -s -m 2 http://github.com/api/v2/json/repos/show/#{username}/#{reponame}`
+ result[:watchers] = repo_info.match(/\"watchers\"\W*:\W*([0-9]+)/).to_a[1]
+ result[:forks] = repo_info.match(/\"forks\"\W*:\W*([0-9]+)/).to_a[1]
+ end
+ result
+ end
+ end
+ end
+end
View
48 spec/functional/command/list_spec.rb
@@ -0,0 +1,48 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+
+describe "Pod::Command::List" do
+ extend SpecHelper::Git
+
+ before do
+ config.repos_dir = fixture('spec-repos')
+ end
+
+ after do
+ config.repos_dir = tmp_repos_path
+ end
+
+ def command(arguments = argv)
+ command = Pod::Command::List.new(arguments)
+ def command.puts(msg = '')
+ (@printed ||= '') << "#{msg}\n"
+ end
+ command
+ end
+
+ it "it accepts corret inputs and runs without errors" do
+ lambda { command().run }.should.not.raise
+ lambda { command(argv('10')).run }.should.not.raise
+ end
+
+ it "complains if the days parameter is not a number" do
+ lambda { command(argv('10a')).run }.should.raise Pod::Command::Help
+ end
+
+
+ it "returns the specs know in a given commit" do
+ specs = command(argv('10')).spec_names_from_commit('cad98852103394951850f89f0efde08f9dc41830')
+ specs[00].should == 'A2DynamicDelegate'
+ specs[10].should == 'DCTTextFieldValidator'
+ specs[20].should == 'INKeychainAccess'
+ specs[30].should == 'MKNetworkKit'
+ end
+
+ it "returns the new specs introduced after a given commit" do
+ new_specs = command(argv('10')).new_specs_set('1c138d254bd39a3ccbe95a720098e2aaad5c5fc1')
+ new_specs_name = new_specs.map { |spec| spec.name }
+ new_specs_name.should.include 'iCarousel'
+ new_specs_name.should.include 'libPusher'
+ end
+end
+
+
View
38 spec/unit/command/set_present_spec.rb
@@ -0,0 +1,38 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+
+describe Pod::Command::SetPresent do
+
+ before do
+ @set = Pod::Spec::Set.new(fixture('spec-repos/master/CocoaLumberjack'))
+ @dummy = Object.new
+ @dummy.extend(Pod::Command::SetPresent)
+ def @dummy.puts(msg = '') (@printed ||= '') << "#{msg}\n" end
+ def @dummy.prinded() @printed.chomp end
+ end
+
+ it "repects the `--name-only' option" do
+ @dummy.parse_set_options(argv('--name-only'))
+ @dummy.present_set(@set)
+ @dummy.prinded.should == 'CocoaLumberjack'
+ end
+
+ it "presents the name, version, description, homepage and source of a specification set" do
+ @dummy.parse_set_options(argv())
+ @dummy.present_set(@set)
+ @dummy.prinded.should.include? 'CocoaLumberjack'
+ @dummy.prinded.should.include? '1.0'
+ @dummy.prinded.should.include? '1.1'
+ @dummy.prinded.should.include? 'A fast & simple, yet powerful & flexible logging framework for Mac and iOS.'
+ @dummy.prinded.should.include? 'https://github.com/robbiehanson/CocoaLumberjack'
+ @dummy.prinded.should.include? 'https://github.com/robbiehanson/CocoaLumberjack.git'
+ end
+
+ it "presents the stats of a specification set" do
+ @dummy.parse_set_options(argv('--stats'))
+ @dummy.present_set(@set)
+ @dummy.prinded.should.match(/Watchers:\W+[0-9]+/)
+ @dummy.prinded.should.match(/Forks:\W+[0-9]+/)
+ end
+
+end
+
Something went wrong with that request. Please try again.