hubless 0.1.3 → 0.2.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/README.markdown CHANGED
@@ -4,7 +4,7 @@ Search your local gem repository for gems installed from GitHub that have since
4
4
 
5
5
  ## Command line usage
6
6
 
7
- $ hubless
7
+ $ hubless [-i|-h]
8
8
 
9
9
  ## Sample output
10
10
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.3
1
+ 0.2.0
data/hubless.gemspec CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{hubless}
8
- s.version = "0.1.3"
8
+ s.version = "0.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Greg Sterndale"]
data/lib/application.rb CHANGED
@@ -4,14 +4,39 @@ class Hubless
4
4
  class Application
5
5
 
6
6
  def self.run(*args)
7
- hubless = Hubless.new
8
- hubless.gem_breakdown
9
- hubless.github_repos
10
- hubless.gemcutter_gems
11
- hubless.uninstall_instructions
12
- hubless.install_instructions
7
+ if help_option?(args)
8
+ display_help
9
+ else
10
+ hubless = Hubless.new
11
+ hubless.gem_breakdown
12
+ hubless.github_repos
13
+ hubless.gemcutter_gems
14
+ hubless.uninstall_instructions
15
+ if install_option?(args)
16
+ hubless.install_gems
17
+ else
18
+ hubless.install_instructions
19
+ end
20
+ end
13
21
  return 0
14
22
  end
23
+
24
+ protected
15
25
 
26
+ def self.display_help
27
+ $stdout.puts "Search your local gem repository for gems installed from GitHub that have since moved to Gemcutter"
28
+ $stdout.puts "Usage: hubless [-i|-h] "
29
+ $stdout.puts "\t-i, --install\tinstall GitHub gems that are on Gemcutter (consider running with sudo)"
30
+ $stdout.puts "\t-h, --help\tdisplay this help and exit"
31
+ end
32
+
33
+ def self.install_option?(args)
34
+ args.include?('-i') || args.include?('--install')
35
+ end
36
+
37
+ def self.help_option?(args)
38
+ args.include?('-h') || args.include?('--help')
39
+ end
40
+
16
41
  end
17
42
  end
@@ -2,141 +2,141 @@ require 'rubygems'
2
2
  require 'net/http'
3
3
 
4
4
  class Hubless
5
- ServiceError = Class.new(RuntimeError)
5
+ class ServiceError < StandardError; end
6
6
 
7
- class GemDescription
7
+ class GemDescription
8
8
 
9
- attr_reader :name
10
- attr_accessor :version
9
+ attr_reader :name
10
+ attr_accessor :version
11
11
 
12
- # GemDescriptions of all gems installed locally
13
- def self.local_gems
14
- @@local_gems ||= Gem.cache.map {|g| new(g.first) }.sort!{|x,y| y.name <=> x.name }
15
- end
12
+ # GemDescriptions of all gems installed locally
13
+ def self.local_gems
14
+ @@local_gems ||= Gem.cache.map {|g| new(g.first) }.sort!{|x,y| y.name <=> x.name }
15
+ end
16
16
 
17
- # New GemDescription from a one-liner or options Hash
18
- # Hubless::GemDescription.new('my-awesome_gem-3.4.5')
19
- # Hubless::GemDescription.new(:name => 'my-awesome_gem', :version => '3.4.5')
20
- def initialize(*args)
21
- case args.first
22
- when String
23
- self.attributes_from_one_liner(args.first)
24
- when Hash
25
- self.name = args.first[:name]
26
- self.version = args.first[:version]
17
+ # New GemDescription from a one-liner or options Hash
18
+ # Hubless::GemDescription.new('my-awesome_gem-3.4.5')
19
+ # Hubless::GemDescription.new(:name => 'my-awesome_gem', :version => '3.4.5')
20
+ def initialize(*args)
21
+ case args.first
22
+ when String
23
+ self.attributes_from_one_liner(args.first)
24
+ when Hash
25
+ self.name = args.first[:name]
26
+ self.version = args.first[:version]
27
+ end
27
28
  end
28
- end
29
29
 
30
- # Assign gem description name and clear any cached values
31
- def name=(str)
32
- self.clear
33
- @name = str
34
- end
30
+ # Assign gem description name and clear any cached values
31
+ def name=(str)
32
+ self.clear
33
+ @name = str
34
+ end
35
35
 
36
- # Does a repo exist on GitHub that matches this gem
37
- def github?
38
- if @is_github.nil?
39
- @is_github = (self.github_like? && self.github_repo_exist?)
40
- else
41
- @is_github
36
+ # Does a repo exist on GitHub that matches this gem
37
+ def github?
38
+ if @is_github.nil?
39
+ @is_github = (self.github_like? && self.github_repo_exist?)
40
+ else
41
+ @is_github
42
+ end
42
43
  end
43
- end
44
44
 
45
- # Full name of this gem including GitHub username
46
- def github_name
47
- self.name if self.github_user_name
48
- end
45
+ # Full name of this gem including GitHub username
46
+ def github_name
47
+ self.name if self.github_user_name
48
+ end
49
49
 
50
- def github_like?
51
- self.github_user_name && self.github_repo_name
52
- end
50
+ def github_like?
51
+ self.github_user_name && self.github_repo_name
52
+ end
53
53
 
54
- # Does a gem exist on Gemcutter that matches this gem
55
- def gemcutter?
56
- if @is_gemcutter.nil?
57
- @is_gemcutter = self.gemcutter_gem_exist?
58
- else
59
- @is_gemcutter
54
+ # Does a gem exist on Gemcutter that matches this gem
55
+ def gemcutter?
56
+ if @is_gemcutter.nil?
57
+ @is_gemcutter = self.gemcutter_gem_exist?
58
+ else
59
+ @is_gemcutter
60
+ end
60
61
  end
61
- end
62
62
 
63
- # Likely name of this gem on Gemcutter (without the GitHub username)
64
- def gemcutter_name
65
- self.github? ? self.github_repo_name : self.name
66
- end
63
+ # Likely name of this gem on Gemcutter (without the GitHub username)
64
+ def gemcutter_name
65
+ self.github? ? self.github_repo_name : self.name
66
+ end
67
67
 
68
- # Command to install gem from Gemcutter
69
- def install_cmd
70
- cmd = ["gem install"]
71
- cmd << self.gemcutter_name
72
- cmd << "-v #{self.version}" if self.version
73
- cmd.join(' ')
74
- end
68
+ # Command to install gem from Gemcutter
69
+ def install_cmd
70
+ cmd = ["gem install"]
71
+ cmd << self.gemcutter_name
72
+ cmd << "-v #{self.version}" if self.version
73
+ cmd.join(' ')
74
+ end
75
75
 
76
- # Command to uninstall gem
77
- def uninstall_cmd
78
- cmd = ["gem uninstall"]
79
- cmd << self.name
80
- cmd << "-v #{self.version}" if self.version
81
- cmd.join(' ')
82
- end
76
+ # Command to uninstall gem
77
+ def uninstall_cmd
78
+ cmd = ["gem uninstall"]
79
+ cmd << self.name
80
+ cmd << "-v #{self.version}" if self.version
81
+ cmd.join(' ')
82
+ end
83
83
 
84
- protected
84
+ protected
85
85
 
86
- def clear
87
- @is_gemcutter = @is_github = nil
88
- end
86
+ def clear
87
+ @is_gemcutter = @is_github = nil
88
+ end
89
89
 
90
- def github_user_name
91
- if self.name =~ /^([^-]*)-.*$/
92
- $1
90
+ def github_user_name
91
+ if self.name =~ /^([^-]*)-.*$/
92
+ $1
93
+ end
93
94
  end
94
- end
95
95
 
96
- def github_repo_name
97
- if self.name =~ /^[^-]*-(.*)$/
98
- $1
96
+ def github_repo_name
97
+ if self.name =~ /^[^-]*-(.*)$/
98
+ $1
99
+ end
99
100
  end
100
- end
101
101
 
102
- def github_uri
103
- URI.parse("http://github.com/api/v2/yaml/repos/show/#{self.github_user_name}/#{self.github_repo_name}")
104
- end
102
+ def github_uri
103
+ URI.parse("http://github.com/api/v2/yaml/repos/show/#{self.github_user_name}/#{self.github_repo_name}")
104
+ end
105
105
 
106
- def github_repo_exist?
107
- response = Net::HTTP.get(self.github_uri)
108
- case
109
- when response =~ /error: repository not found/
110
- false
111
- when response =~ /error: too many requests/
112
- raise ServiceError
113
- else
114
- true
106
+ def github_repo_exist?
107
+ response = Net::HTTP.get(self.github_uri)
108
+ case
109
+ when response =~ /error: repository not found/
110
+ false
111
+ when response =~ /error: too many requests/
112
+ raise ServiceError
113
+ else
114
+ true
115
+ end
115
116
  end
116
- end
117
117
 
118
- def gemcutter_uri
119
- URI.parse("http://gemcutter.org/api/v1/gems/#{self.name}.json")
120
- end
118
+ def gemcutter_uri
119
+ URI.parse("http://gemcutter.org/api/v1/gems/#{self.name}.json")
120
+ end
121
121
 
122
- def gemcutter_gem_exist?
123
- response = Net::HTTP.get(self.gemcutter_uri)
124
- case
125
- when response =~ /This rubygem could not be found./
126
- false
127
- when response =~ /error: too many requests/
128
- raise ServiceError
129
- else
130
- true
122
+ def gemcutter_gem_exist?
123
+ response = Net::HTTP.get(self.gemcutter_uri)
124
+ case
125
+ when response =~ /This rubygem could not be found./
126
+ false
127
+ when response =~ /error: too many requests/
128
+ raise ServiceError
129
+ else
130
+ true
131
+ end
131
132
  end
132
- end
133
133
 
134
- def attributes_from_one_liner(one_liner)
135
- if one_liner =~ /^(.*)-([\d\.]+)$/
136
- self.name = $1
137
- self.version = $2
134
+ def attributes_from_one_liner(one_liner)
135
+ if one_liner =~ /^(.*)-([\d\.]+)$/
136
+ self.name = $1
137
+ self.version = $2
138
+ end
138
139
  end
139
- end
140
140
 
141
- end
141
+ end
142
142
  end
data/lib/hubless.rb CHANGED
@@ -1,6 +1,10 @@
1
1
  require File.dirname(__FILE__) + '/gem_description'
2
2
 
3
+
4
+
3
5
  class Hubless
6
+ class GemInstallError < StandardError; end
7
+
4
8
  @@io = $stdout
5
9
  @@timeout = 1
6
10
 
@@ -55,14 +59,16 @@ class Hubless
55
59
  self.gems.each {|g| @@io.puts(g.install_cmd) if g.github? && g.gemcutter? }
56
60
  end
57
61
 
58
- # def self.reinstall_gems
59
- # self.gems.each do |g|
60
- # if g.github? && g.gemcutter?
61
- # @@io.puts %x(#{g.uninstall_cmd})
62
- # @@io.puts %x(#{g.install_cmd})
63
- # end
64
- # end
65
- # end
62
+ def install_gems
63
+ @@io.puts("\nInstalling gems:")
64
+ self.gems.each do |g|
65
+ if g.github? && g.gemcutter?
66
+ cmd = g.install_cmd
67
+ @@io.puts cmd
68
+ raise GemInstallError unless Kernel.system(cmd)
69
+ end
70
+ end
71
+ end
66
72
 
67
73
  protected
68
74
 
@@ -71,5 +77,3 @@ protected
71
77
  end
72
78
 
73
79
  end
74
-
75
- # Hubless.local_gems_on_github.each{|g| puts g.inspect }
@@ -14,4 +14,28 @@ class TestApplication < Test::Unit::TestCase
14
14
  Hubless::Application.run
15
15
  end
16
16
 
17
+ def test_run_with_i
18
+ hubless = mock(
19
+ :gem_breakdown => true,
20
+ :github_repos => true,
21
+ :gemcutter_gems => true,
22
+ :uninstall_instructions => true,
23
+ :install_gems => true
24
+ )
25
+ Hubless.expects(:new).returns(hubless)
26
+ Hubless::Application.run('-i')
27
+ end
28
+
29
+ def test_run_with_h
30
+ original_stdout = $stdout
31
+ fake_stdout = mock
32
+ fake_stdout.stubs(:write)
33
+ $stdout = fake_stdout
34
+ fake_stdout.expects(:puts).at_least_once
35
+ Hubless.expects(:new).never
36
+ Hubless::Application.run('-h')
37
+ ensure
38
+ $stdout = original_stdout
39
+ end
40
+
17
41
  end
data/test/test_hubless.rb CHANGED
@@ -98,99 +98,34 @@ class TestHubless < Test::Unit::TestCase
98
98
  hubless.install_instructions
99
99
  end
100
100
 
101
-
102
- # def setup
103
- # @gems = [
104
- # [ 'my-github_and_gemcutter_gem-0.1.2', mock ],
105
- # [ 'my-github_only_gem-1.2.3', mock ],
106
- # [ 'my-github_look_a_like_on_gemcutter_gem-2.3.4', mock ],
107
- # [ 'my_non_github_gem-3.4.5', mock ]
108
- # ]
109
- # Gem.stubs(:cache).returns(@gems)
110
- # end
111
- #
112
- # def teardown
113
- # Hubless.clear
114
- # end
115
- #
116
- # def test_local_gems
117
- # local_gems = Hubless.local_gems
118
- # assert local_gems.detect{|gem_description| gem_description.name == 'my-github_and_gemcutter_gem' }
119
- # assert local_gems.detect{|gem_description| gem_description.name == 'my-github_only_gem' }
120
- # assert local_gems.detect{|gem_description| gem_description.name == 'my-github_look_a_like_on_gemcutter_gem' }
121
- # assert local_gems.detect{|gem_description| gem_description.name == 'my_non_github_gem' }
122
- # assert_equal @gems.length, local_gems.length
123
- # end
124
- #
125
- # def test_local_github_like_gems
126
- # local_github_like_gems = Hubless.local_github_like_gems
127
- # assert local_github_like_gems.detect{|gem_description| gem_description.name == 'my-github_and_gemcutter_gem' }
128
- # assert local_github_like_gems.detect{|gem_description| gem_description.name == 'my-github_only_gem' }
129
- # assert local_github_like_gems.detect{|gem_description| gem_description.name == 'my-github_look_a_like_on_gemcutter_gem' }
130
- # assert ! local_github_like_gems.detect{|gem_description| gem_description.name == 'my_non_github_gem' }
131
- # end
132
- #
133
- # def test_local_gems_on_github
134
- # Net::HTTP.expects(:get).times(3).
135
- # returns("--- \nrepository: \n :description: Description here\n :forks: 0\n :url: http://github.com/some_user/some_repo\n :fork: false\n :open_issues: 0\n :watchers: 1\n :private: false\n :name: some_repo\n :owner: some_user\n").
136
- # returns("--- \nrepository: \n :description: Description here\n :forks: 0\n :url: http://github.com/some_user/some_repo\n :fork: false\n :open_issues: 0\n :watchers: 1\n :private: false\n :name: some_repo\n :owner: some_user\n").
137
- # returns("--- \nerror: \n- error: repository not found\n")
138
- # local_gems_on_github = Hubless.local_gems_on_github
139
- # assert local_gems_on_github.detect{|gem_description| gem_description.name == 'my-github_and_gemcutter_gem' }
140
- # assert local_gems_on_github.detect{|gem_description| gem_description.name == 'my-github_only_gem' }
141
- # assert ! local_gems_on_github.detect{|gem_description| gem_description.name == 'my-github_look_a_like_on_gemcutter_gem' }
142
- # assert ! local_gems_on_github.detect{|gem_description| gem_description.name == 'my_non_github_gem' }
143
- # end
144
- #
145
- # def test_local_gems_on_github_with_github_error
146
- # Net::HTTP.expects(:get).times(2).
147
- # returns("--- \nrepository: \n :description: Description here\n :forks: 0\n :url: http://github.com/some_user/some_repo\n :fork: false\n :open_issues: 0\n :watchers: 1\n :private: false\n :name: some_repo\n :owner: some_user\n").
148
- # returns("--- \nerror: \n- error: too many requests\n")
149
- # assert_raise(ServiceError) { Hubless.local_gems_on_github }
150
- # end
151
- #
152
- # def test_local_gems_on_github_and_gemcutter
153
- # Net::HTTP.expects(:get).times(5).
154
- # returns("--- \nrepository: \n :description: Description here\n :forks: 0\n :url: http://github.com/some_user/some_repo\n :fork: false\n :open_issues: 0\n :watchers: 1\n :private: false\n :name: some_repo\n :owner: some_user\n").
155
- # returns("--- \nrepository: \n :description: Description here\n :forks: 0\n :url: http://github.com/some_user/some_repo\n :fork: false\n :open_issues: 0\n :watchers: 1\n :private: false\n :name: some_repo\n :owner: some_user\n").
156
- # returns("--- \nerror: \n- error: repository not found\n").
157
- # returns(%Q{{"version_downloads":137674,"info":" Rails is a framework for building web-application using CGI, FCGI, mod_ruby, or WEBrick\n on top of either MySQL, PostgreSQL, SQLite, DB2, SQL Server, or Oracle with eRuby- or Builder-based templates.\n","project_uri":"http://gemcutter.org/gems/rails","name":"rails","version":"2.3.5","gem_uri":"http://gemcutter.org/gems/rails-2.3.5.gem","downloads":218523,"authors":"David Heinemeier Hansson"}}).
158
- # returns("This rubygem could not be found.")
159
- # local_gems_on_github_and_gemcutter = Hubless.local_gems_on_github_and_gemcutter
160
- # assert local_gems_on_github_and_gemcutter.detect{|gem_description| gem_description.name == 'my-github_and_gemcutter_gem' }
161
- # assert ! local_gems_on_github_and_gemcutter.detect{|gem_description| gem_description.name == 'my-github_only_gem' }
162
- # assert ! local_gems_on_github_and_gemcutter.detect{|gem_description| gem_description.name == 'my-github_look_a_like_on_gemcutter_gem' }
163
- # assert ! local_gems_on_github_and_gemcutter.detect{|gem_description| gem_description.name == 'my_non_github_gem' }
164
- # end
165
- #
166
- # def test_clear
167
- # Net::HTTP.expects(:get).times(5).
168
- # returns("--- \nrepository: \n :description: Description here\n :forks: 0\n :url: http://github.com/some_user/some_repo\n :fork: false\n :open_issues: 0\n :watchers: 1\n :private: false\n :name: some_repo\n :owner: some_user\n").
169
- # returns("--- \nrepository: \n :description: Description here\n :forks: 0\n :url: http://github.com/some_user/some_repo\n :fork: false\n :open_issues: 0\n :watchers: 1\n :private: false\n :name: some_repo\n :owner: some_user\n").
170
- # returns("--- \nerror: \n- error: repository not found\n").
171
- # returns(%Q{{"version_downloads":137674,"info":" Rails is a framework for building web-application using CGI, FCGI, mod_ruby, or WEBrick\n on top of either MySQL, PostgreSQL, SQLite, DB2, SQL Server, or Oracle with eRuby- or Builder-based templates.\n","project_uri":"http://gemcutter.org/gems/rails","name":"rails","version":"2.3.5","gem_uri":"http://gemcutter.org/gems/rails-2.3.5.gem","downloads":218523,"authors":"David Heinemeier Hansson"}}).
172
- # returns("This rubygem could not be found.")
173
- #
174
- # Hubless.local_gems_on_github_and_gemcutter
175
- #
176
- # Net::HTTP.expects(:get).times(0)
177
- #
178
- # Hubless.local_gems_on_github_and_gemcutter
179
- #
180
- # Hubless.clear
181
- #
182
- # Net::HTTP.expects(:get).times(5).
183
- # returns("--- \nrepository: \n :description: Description here\n :forks: 0\n :url: http://github.com/some_user/some_repo\n :fork: false\n :open_issues: 0\n :watchers: 1\n :private: false\n :name: some_repo\n :owner: some_user\n").
184
- # returns("--- \nrepository: \n :description: Description here\n :forks: 0\n :url: http://github.com/some_user/some_repo\n :fork: false\n :open_issues: 0\n :watchers: 1\n :private: false\n :name: some_repo\n :owner: some_user\n").
185
- # returns("--- \nerror: \n- error: repository not found\n").
186
- # returns(%Q{{"version_downloads":137674,"info":" Rails is a framework for building web-application using CGI, FCGI, mod_ruby, or WEBrick\n on top of either MySQL, PostgreSQL, SQLite, DB2, SQL Server, or Oracle with eRuby- or Builder-based templates.\n","project_uri":"http://gemcutter.org/gems/rails","name":"rails","version":"2.3.5","gem_uri":"http://gemcutter.org/gems/rails-2.3.5.gem","downloads":218523,"authors":"David Heinemeier Hansson"}}).
187
- # returns("This rubygem could not be found.")
188
- #
189
- # Hubless.local_gems_on_github_and_gemcutter
190
- # end
191
- def test_nothin
192
- assert true
193
- end
194
-
101
+ def test_install_gems
102
+ local_gems = [
103
+ mock(:install_cmd => 'foo', :github? => true, :gemcutter? => true),
104
+ mock(:install_cmd => 'bar', :github? => true, :gemcutter? => true),
105
+ mock(:install_cmd => 'abc', :github? => true, :gemcutter? => true),
106
+ mock(:github? => true, :gemcutter? => false),
107
+ mock(:github? => false)
108
+ ]
109
+ Hubless::GemDescription.expects(:local_gems).once.returns(local_gems)
110
+ @io.expects(:puts).with{|s| s =~ /Installing gems:/ }
111
+ @io.expects(:puts).once.with{|s| s =~ /foo/ }
112
+ @io.expects(:puts).once.with{|s| s =~ /bar/ }
113
+ @io.expects(:puts).once.with{|s| s =~ /abc/ }
114
+ Kernel.expects(:system).once.with{|s| s =~ /foo/ }.returns(true)
115
+ Kernel.expects(:system).once.with{|s| s =~ /bar/ }.returns(true)
116
+ Kernel.expects(:system).once.with{|s| s =~ /abc/ }.returns(true)
117
+ hubless = Hubless.new
118
+ hubless.install_gems
119
+
120
+ local_gems = [
121
+ mock(:install_cmd => 'foo', :github? => true, :gemcutter? => true)
122
+ ]
123
+ Hubless::GemDescription.expects(:local_gems).once.returns(local_gems)
124
+ @io.expects(:puts).with{|s| s =~ /Installing gems:/ }
125
+ @io.expects(:puts).once.with{|s| s =~ /foo/ }
126
+ Kernel.expects(:system).once.with{|s| s =~ /foo/ }.returns(false)
127
+ hubless = Hubless.new
128
+ assert_raise(Hubless::GemInstallError) { hubless.install_gems }
129
+ end
195
130
 
196
131
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hubless
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Greg Sterndale