stickler 2.3.0 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +15 -0
  2. data/CONTRIBUTING.md +5 -4
  3. data/HISTORY.md +16 -9
  4. data/LICENSE +1 -1
  5. data/Manifest.txt +34 -20
  6. data/README.md +128 -0
  7. data/Rakefile +10 -9
  8. data/bin/stickler +9 -6
  9. data/bin/stickler-passenger-config +8 -8
  10. data/bin/stickler-server +12 -12
  11. data/examples/as_middleware.ru +14 -0
  12. data/examples/auth_repo.ru +1 -1
  13. data/examples/gemcutter_repo.ru +1 -1
  14. data/examples/local_repo.ru +1 -1
  15. data/lib/stickler.rb +3 -1
  16. data/lib/stickler/client.rb +2 -1
  17. data/lib/stickler/client/delete.rb +1 -1
  18. data/lib/stickler/client/latest-version.rb +40 -0
  19. data/lib/stickler/client/mirror.rb +47 -15
  20. data/lib/stickler/client/push.rb +1 -1
  21. data/lib/stickler/client/unyank.rb +1 -1
  22. data/lib/stickler/client/yank.rb +1 -1
  23. data/lib/stickler/gem_container.rb +40 -0
  24. data/lib/stickler/gemfile_lock_parser.rb +47 -0
  25. data/lib/stickler/middleware.rb +1 -0
  26. data/lib/stickler/middleware/server.rb +37 -0
  27. data/lib/stickler/repository/api.rb +16 -0
  28. data/lib/stickler/repository/index.rb +0 -3
  29. data/lib/stickler/repository/local.rb +6 -8
  30. data/lib/stickler/repository/remote.rb +29 -7
  31. data/lib/stickler/server.rb +2 -6
  32. data/man/stickler-passenger-config.1 +2 -22
  33. data/man/stickler-server.1 +9 -99
  34. data/man/stickler.1 +15 -173
  35. data/man/stickler.1.ronn +6 -0
  36. data/tasks/default.rake +16 -18
  37. data/tasks/man.rake +7 -0
  38. data/tasks/this.rb +5 -5
  39. data/test/data/Gemfile.lock.example +56 -0
  40. data/{spec → test}/data/gemcutter/gems/foo-1.0.0.gem +0 -0
  41. data/{spec → test}/data/gems/bar-1.0.0.gem +0 -0
  42. data/{spec → test}/data/gems/baz-3.1.4-java.gem +0 -0
  43. data/{spec → test}/data/gems/baz-3.1.4.gem +0 -0
  44. data/{spec → test}/data/gems/foo-1.0.0.gem +0 -0
  45. data/{spec → test}/data/gems/foo-2.0.0a.gem +0 -0
  46. data/test/data/specifications/bar-1.0.0.gemspec +31 -0
  47. data/test/data/specifications/baz-3.1.4-java.gemspec +32 -0
  48. data/test/data/specifications/baz-3.1.4.gemspec +31 -0
  49. data/test/data/specifications/foo-1.0.0.gemspec +31 -0
  50. data/test/data/specifications/foo-2.0.0a.gemspec +32 -0
  51. data/test/index_test_helpers.rb +75 -0
  52. data/test/middleware/test_local.rb +75 -0
  53. data/test/middleware/test_not_found.rb +26 -0
  54. data/test/repository/test_api.rb +49 -0
  55. data/test/repository/test_api_behavior.rb +208 -0
  56. data/test/repository/test_index.rb +48 -0
  57. data/test/repository/test_local.rb +59 -0
  58. data/test/repository/test_null.rb +15 -0
  59. data/test/repository/test_remote.rb +26 -0
  60. data/test/repository/test_remote_authenticated.rb +39 -0
  61. data/test/stickler_test_server.rb +35 -0
  62. data/test/test_gemfile_lock_parser.rb +28 -0
  63. data/test/test_paths.rb +22 -0
  64. data/test/test_spec_lite.rb +90 -0
  65. data/test/test_stickler.rb +49 -0
  66. metadata +58 -85
  67. data/README.rdoc +0 -156
  68. data/spec/index_spec_helpers.rb +0 -73
  69. data/spec/middleware/local_spec.rb +0 -72
  70. data/spec/middleware/not_found_spec.rb +0 -25
  71. data/spec/paths_spec.rb +0 -11
  72. data/spec/repository/api_behavior.rb +0 -192
  73. data/spec/repository/api_spec.rb +0 -37
  74. data/spec/repository/index_spec.rb +0 -46
  75. data/spec/repository/local_spec.rb +0 -49
  76. data/spec/repository/null_spec.rb +0 -14
  77. data/spec/repository/remote_spec.rb +0 -86
  78. data/spec/spec.opts +0 -2
  79. data/spec/spec_helper.rb +0 -24
  80. data/spec/spec_lite_spec.rb +0 -96
@@ -1,156 +0,0 @@
1
- = Stickler
2
-
3
- * Jeremy Hinegardner <jeremy@hinegardner.org>
4
- * http://github.com/copiousfreetime/qup
5
-
6
- == DESCRIPTION
7
-
8
- Stickler is a tool to organize and maintain an internal gem repository.
9
- Primarily, you would want to use Stickler if:
10
-
11
- 1. You have proprietary gems that you want to have available via a gem server so
12
- you may +gem install+ them.
13
- 2. You would like to have a local mirror of third party gems from either
14
- http://rubygems.org or some other gem server.
15
- 3. You want both (1) and (2) in the same server.
16
-
17
-
18
- == INSTALLATION
19
-
20
- Installing stickler may be done via the standard gem installation
21
-
22
- gem install stickler
23
-
24
- Or downloaded from http://github.com/copiousfreetime/stickler/downloads
25
-
26
-
27
- == USAGE
28
-
29
- Stickler is broken up into a few commandline programs.
30
-
31
- .Command line programs
32
- ******************************************************************
33
- [horizontal]
34
- link:man/stickler.html[stickler]::
35
- Used to add gems to and remove gems from the
36
- link:man/stickler-server.html[stickler-server]
37
-
38
- link:man/stickler-server.html[stickler-server]::
39
- The server process that holds the gems.
40
-
41
- link:man/stickler-passenger-config.html[stickler-passenger-config]::
42
- A helper process to generate Passenger configurations for
43
- link:man/stickler-server.html[stickler-server]
44
- ******************************************************************
45
-
46
- The easiest way to get up and running with stickler is to run the
47
- standalone server link:man/stickler-server.html[stickler-server] and
48
- then use link:man/stickler.html[stickler] to interact with it.
49
-
50
- .Start up a standalone stickler server
51
- ------------------------------------------------------------------
52
- % mkdir -p /tmp/stickler-test
53
- % stickler-server start --daemonize /tmp/stickler-test
54
- ------------------------------------------------------------------
55
-
56
- .Set some sane defaults
57
- ------------------------------------------------------------------
58
- % stickler config --add --server http://localhost:6789 --upstream https://rubygems.org
59
- server : http://localhost:6789
60
- upstream : https://rubygems.org
61
-
62
- % cat ~/.gem/stickler
63
- ---
64
- :server: http://localhost:6789
65
- :upstream: https://rubygems.org
66
- ------------------------------------------------------------------
67
-
68
- .Take a few gems and push them to the server
69
- ------------------------------------------------------------------
70
- % ls -1
71
- heel-2.0.0.gem
72
- hitimes-1.1.1.gem
73
- launchy-0.3.5.gem
74
- stickler-2.0.0.gem
75
-
76
- % stickler push *.gem
77
- Pushing gem(s) to http://localhost:6789/ ...
78
- /Users/jeremy/tmp/gems/heel-2.0.0.gem -> OK http://localhost:6789/gems/heel-2.0.0.gem
79
- /Users/jeremy/tmp/gems/hitimes-1.1.1.gem -> OK http://localhost:6789/gems/hitimes-1.1.1.gem
80
- /Users/jeremy/tmp/gems/launchy-0.3.5.gem -> OK http://localhost:6789/gems/launchy-0.3.5.gem
81
- /Users/jeremy/tmp/gems/stickler-2.0.0.gem -> OK http://localhost:6789/gems/stickler-2.0.0.gem
82
- ------------------------------------------------------------------
83
-
84
- .Mirror a gem from upstream
85
- ------------------------------------------------------------------
86
- % stickler mirror --gem-version 1.4.3 logging
87
- Asking http://localhost:6789/ to mirror logging-1.4.3 from rubygems.org : OK -> http://localhost:6789/gems/logging-1.4.3.gem
88
- % stickler mirror --gem-version 1.16.2 trollop
89
- Asking http://localhost:6789/ to mirror trollop-1.16.2 from rubygems.org : OK -> http://localhost:6789/gems/trollop-1.16.2.gem
90
- ------------------------------------------------------------------
91
-
92
- .Look at all the gems installed in your stickler server
93
- Open your browser to http://localhost:6789
94
- -------------------------------
95
- % launchy http://localhost:6789
96
- -------------------------------
97
-
98
- .Install a gem from your new stickler gem server
99
- ------------------------------------------------------
100
- % gem install hitimes --source http://localhost:6789/
101
- ------------------------------------------------------
102
-
103
- .Configure your servers to globally use your internal stickler gem server
104
- -----------------------------
105
- % cat /etc/gemrc
106
- ---
107
- :benchmark: false
108
- :verbose: false
109
- :update_sources: true
110
- :bulk_threshold: 1000
111
- :backtrace: false
112
- :sources:
113
- - http://stickler.example.com
114
- gem: --no-rdoc --no-ri
115
- -----------------------------
116
-
117
-
118
- See Also
119
- --------
120
- The man pages that ship with the gem. They may be viewed if you also install
121
- the link:http://defunkt.github.com/gem-man/[gem-man] gem.
122
-
123
- ---------------------------------
124
- % gem install gem-man
125
- % gem man stickler
126
- View which manual?
127
- 1. stickler-passenger-config(1)
128
- 2. stickler-server(1)
129
- 3. stickler(1)
130
- >
131
- ---------------------------------
132
-
133
- == DEVELOPMENT
134
-
135
- If you want to do development on stickler, I suggest using
136
- https://rvm.beginrescueend.com/[RVM] and creating a gemset for stickler.
137
-
138
- Then run 'rake how_to_contribute'
139
-
140
-
141
- == CREDITS
142
-
143
- * http://rubyforge.org/projects/rubygems/[The Rubygems Team]
144
-
145
-
146
- == LICENSE
147
-
148
- Copyright (C) 2008-2010 Jeremy Hinegardner
149
- ISC License, See LICENSE for details
150
-
151
-
152
- == APPENDIX
153
-
154
- * http://github.com/copiousfreetime/stickler[Github Project]
155
- * link:HISTORY.html[History]
156
- * http://www.copiousfreetime.org/projects/stickler/
@@ -1,73 +0,0 @@
1
- require 'rack/test'
2
- require 'rubygems/user_interaction'
3
- require 'rubygems/indexer'
4
-
5
- module IndexSpecHelpers
6
- include Rack::Test::Methods
7
-
8
- def define_directories
9
- # pristine spec data location
10
- @idx_spec_dir = File.expand_path( File.dirname( __FILE__ ) )
11
- @idx_spec_datadir = File.join( @idx_spec_dir, "data" )
12
-
13
- # scratch location
14
- @scratch_dir = File.join( @idx_spec_dir, "scratch" )
15
- @scratch_datadir = File.join( @scratch_dir, 'data' )
16
- @scratch_specdir = File.join( @scratch_datadir, "specifications" )
17
- @scratch_gemsdir = File.join( @scratch_datadir, "gems" )
18
- end
19
-
20
- # put in the before clause for setup
21
- def mirror_spec_gemdir
22
- define_directories
23
- FileUtils.mkdir_p( @scratch_dir )
24
- FileUtils.cp_r( @idx_spec_datadir, @scratch_dir )
25
- end
26
-
27
- # Do a legacy index of the scratch location
28
- def make_legacy_index
29
- indexer = Gem::Indexer.new( @scratch_datadir, :build_legacy => true, :build_modern => false )
30
- with_quieter_rubygems { indexer.generate_index }
31
- end
32
-
33
- # Do a modern index of the scratch location
34
- def make_modern_index
35
- indexer = Gem::Indexer.new( @scratch_datadir, :build_legacy => false, :build_modern => true )
36
- with_quieter_rubygems { indexer.generate_index }
37
- end
38
-
39
- # put in the after clause for cleanup
40
- def destroy_scratch_dir
41
- FileUtils.rm_rf( @scratch_dir )
42
- end
43
-
44
- def with_quieter_rubygems( &block )
45
- previous = Gem.configuration.verbose
46
- Gem.configuration.verbose = nil
47
- yield
48
- Gem.configuration.verbose = previous
49
- end
50
-
51
- def validate_contents( got, expected, content_type)
52
- case content_type
53
- when 'application/x-gzip'
54
- response_un = Gem.gunzip( got )
55
- expected_un = Gem.gunzip( expected )
56
- when 'application/x-deflate'
57
- response_un = Gem.inflate( got )
58
- expected_un = Gem.inflate( expected )
59
- when 'application/octet-stream'
60
- response_un = got
61
- expected_un = expected
62
- else
63
- fail "Unkonwn content type #{content_type} with data #{got}"
64
- end
65
-
66
- got = Marshal.load( response_un )
67
- got.sort! if got.kind_of?( Array )
68
-
69
- need = Marshal.load( expected_un )
70
- need.sort! if need.kind_of?( Array )
71
- got.should == need
72
- end
73
- end
@@ -1,72 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Stickler::Middleware::Local do
4
-
5
- include IndexSpecHelpers
6
- include Rack::Test::Methods
7
-
8
- def app
9
- repo_root = @idx_spec_datadir
10
- ::Rack::Builder.new do
11
- use ::Stickler::Middleware::Compression
12
- use ::Stickler::Middleware::Local, :repo_root => repo_root
13
- run ::Sinatra::Base
14
- end
15
- end
16
-
17
- describe "When serving a modern index" do
18
- before( :all ) do
19
- mirror_spec_gemdir
20
- make_modern_index
21
- end
22
-
23
- after( :all ) do
24
- destroy_scratch_dir
25
- end
26
-
27
- [
28
- "/specs.#{Gem.marshal_version}",
29
- "/specs.#{Gem.marshal_version}.gz",
30
- "/latest_specs.#{Gem.marshal_version}",
31
- "/latest_specs.#{Gem.marshal_version}.gz",
32
- "/prerelease_specs.#{Gem.marshal_version}",
33
- "/prerelease_specs.#{Gem.marshal_version}.gz",
34
- "/quick/Marshal.#{Gem.marshal_version}/foo-1.0.0.gemspec.rz",
35
- "/quick/Marshal.#{Gem.marshal_version}/bar-1.0.0.gemspec.rz",
36
- "/quick/Marshal.#{Gem.marshal_version}/foo-2.0.0a.gemspec.rz",
37
- "/quick/Marshal.#{Gem.marshal_version}/baz-3.1.4-java.gemspec.rz",
38
- "/quick/Marshal.#{Gem.marshal_version}/baz-3.1.4.gemspec.rz",
39
- ].each do |path|
40
- it "should return the same bytes as Gem::Indexer for '#{path}'" do
41
- response = get( path )
42
- validate_contents( response.body,
43
- IO.read( File.join(@scratch_datadir, path) ),
44
- response.content_type )
45
- end
46
- end
47
- end
48
-
49
- describe "When serving a legacy index" do
50
- before( :all ) do
51
- mirror_spec_gemdir
52
- make_legacy_index
53
- end
54
-
55
- after( :all ) do
56
- destroy_scratch_dir
57
- end
58
-
59
- [
60
- "/Marshal.#{Gem.marshal_version}",
61
- "/Marshal.#{Gem.marshal_version}.Z",
62
- ].each do |path|
63
- it "should return the same bytes as Gem::Indexer for '#{path}'" do
64
- pending
65
- response = get( path )
66
- validate_contents( response.body,
67
- IO.read( File.join(@scratch_datadir, path) ),
68
- response.content_type )
69
- end
70
- end
71
- end
72
- end
@@ -1,25 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe ::Stickler::Middleware::NotFound do
4
- include Rack::Test::Methods
5
- def app
6
- ::Stickler::Middleware::NotFound.new
7
- end
8
-
9
- before do
10
- get "/"
11
- end
12
-
13
- it "should respond to a 404 on everything" do
14
- get '/'
15
- last_response.status.should == 404
16
- end
17
-
18
- it "should return a 'text/html' page" do
19
- last_response.content_type.should == 'text/html'
20
- end
21
-
22
- it "should say to go look somewhere else" do
23
- last_response.body.should =~ /Not Found/m
24
- end
25
- end
@@ -1,11 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Stickler::Paths do
4
- it "can access the root dir of the project" do
5
- Stickler::Paths.root_dir.should == File.expand_path( File.join( File.dirname( __FILE__ ), ".." ) ) + ::File::SEPARATOR
6
- end
7
-
8
- it "can access the lib path of the project" do
9
- Stickler::Paths.lib_path.should == File.expand_path( File.join( File.dirname( __FILE__ ), "..", "lib" ) ) + ::File::SEPARATOR
10
- end
11
- end
@@ -1,192 +0,0 @@
1
- shared_examples_for "includes Repository::Api" do
2
- describe "responds to all the api methods" do
3
- Stickler::Repository::Api.api_methods.each do |method|
4
- it "responds to ##{method}" do
5
- @repo.respond_to?( method ).should == true
6
- end
7
- end
8
- end
9
- end
10
-
11
- require 'digest/sha1'
12
- shared_examples_for "implements Repository::Api" do
13
- before( :each ) do
14
- @foo_gem_local_path = File.join( @gems_dir, "foo-1.0.0.gem" )
15
- @foo_spec = Stickler::SpecLite.new( 'foo', '1.0.0' )
16
- @foo_digest = Digest::SHA1.hexdigest( IO.read( @foo_gem_local_path ) )
17
- @missing_spec = Stickler::SpecLite.new( "does_not_exist", "0.1.0" )
18
- end
19
-
20
- # removed specifications_uri
21
- %w[ uri gems_uri ].each do |method|
22
- it "returns a URI like object from #{method}" do
23
- result = @repo.send( method )
24
- [ ::URI, ::Addressable::URI ].include?( result.class ).should == true
25
- end
26
- end
27
-
28
- # removed specification
29
- %w[ gem ].each do |thing|
30
- describe "#uri_for_#{thing}" do
31
- before( :each ) do
32
- @repo.push( @foo_gem_local_path )
33
- @method = "uri_for_#{thing}"
34
- end
35
-
36
- it "returns URI for a #{thing} that exists" do
37
- uri = @repo.send( @method, @foo_spec )
38
- [ ::URI, ::Addressable::URI ].include?( uri.class ).should == true
39
- end
40
-
41
- it "returns nil for a #{thing} that does not exist" do
42
- @repo.send( @method, @missing_spec ).should be_nil
43
- end
44
- end
45
- end
46
-
47
- describe "#push" do
48
- it "pushes a gem from a .gem file" do
49
- @repo.push( @foo_gem_local_path )
50
- @repo.search_for( Stickler::SpecLite.new( "foo", "1.0.0" ) )
51
- end
52
-
53
- it "raises an error when pushing a gem if the gem already exists" do
54
- @repo.push( @foo_gem_local_path )
55
- lambda { @repo.push( @foo_gem_local_path ) }.should raise_error( Stickler::Repository::Error, /gem foo-1.0.0 already exists/ )
56
- end
57
- end
58
-
59
- describe "#delete" do
60
- it "deletes a gem from the repo" do
61
- @repo.search_for( @foo_spec ).should be_empty
62
- @repo.push( @foo_gem_local_path )
63
- @repo.search_for( @foo_spec ).size.should eq 1
64
- @repo.delete( @foo_spec ).should eq true
65
- @repo.search_for( @foo_spec ).should be_empty
66
- end
67
-
68
- it "returns false if it is unable to delete a gem from the repo" do
69
- @repo.search_for( @foo_spec ).should be_empty
70
- @repo.delete( @foo_spec ).should == false
71
- end
72
- end
73
-
74
- describe "#yank" do
75
- before( :each ) do
76
- @repo.search_for( @foo_spec ).should be_empty
77
- @repo.push( @foo_gem_local_path )
78
- @response_uri = @repo.yank( @foo_spec )
79
- end
80
-
81
- it "returns the uri in which to get the gem" do
82
- [ ::URI, ::Addressable::URI ].include?( @response_uri.class ).should == true
83
- end
84
-
85
- it "returns nil if the gem to yank does not exist or is already yanked" do
86
- @repo.yank( @missing_spec ).should == nil
87
- end
88
-
89
- it "does not find the gem in a search" do
90
- @repo.search_for( @foo_spec ).should be_empty
91
- end
92
-
93
- it "does have the #uri_for_gem" do
94
- @repo.uri_for_gem( @foo_spec ).should == @response_uri
95
- end
96
-
97
- it "can still return the gem" do
98
- data = @repo.get( @foo_spec )
99
- sha1 = Digest::SHA1.hexdigest( data )
100
- sha1.should == @foo_digest
101
- end
102
-
103
- end
104
-
105
- describe "#unyank" do
106
- before( :each ) do
107
- @repo.search_for( @foo_spec ).should be_empty
108
- @repo.push( @foo_gem_local_path )
109
- end
110
-
111
- it "returns nil if the gem to unyank does not exist" do
112
- non_existing_gem = @missing_spec
113
- @repo.unyank( non_existing_gem ).should be_nil
114
- end
115
-
116
- #Do we even care about this?
117
- xit "returns nil if the gem to unyank has not been yanked" do
118
- @repo.unyank( @foo_spec ).should be_nil
119
- end
120
-
121
- context " when file has been yanked" do
122
- before :each do
123
- @repo.yank( @foo_spec )
124
- end
125
-
126
- it "return true if the gem is successfully unyanked" do
127
- @repo.unyank( @foo_spec ).should be_true
128
- end
129
-
130
- it "finds the gem in a search" do
131
- @repo.unyank( @foo_spec )
132
- @repo.search_for( @foo_spec ).should_not be_empty
133
- end
134
- end
135
- end
136
-
137
- describe "#search_for" do
138
- it "returns specs for items that are found" do
139
- @repo.push( @foo_gem_local_path )
140
- @repo.search_for( @foo_spec ).should_not be_empty
141
- end
142
-
143
- it "returns an empty array when nothing is found" do
144
- @repo.search_for( @missing_spec ).should be_empty
145
- end
146
- end
147
-
148
- describe "#get" do
149
- it "returns the bytes of the gem for a gem that exists" do
150
- @repo.push( @foo_gem_local_path )
151
- data = @repo.get( @foo_spec )
152
- sha1 = Digest::SHA1.hexdigest( data )
153
- sha1.should == @foo_digest
154
- end
155
-
156
- it "returns nil if the gem does not exist" do
157
- @repo.get( @missing_spec ).should be_nil
158
- end
159
- end
160
-
161
- describe "#open" do
162
- before( :each ) do
163
- @repo.push( @foo_gem_local_path )
164
- end
165
- it "reads a gem via a returned output stream" do
166
- io = @repo.open( @foo_spec )
167
- sha1 = Digest::SHA1.hexdigest( io.read )
168
- sha1.should == @foo_digest
169
- end
170
-
171
- it "can be called with a block" do
172
- sha1 = Digest::SHA1.new
173
- @repo.open( @foo_spec ) do |io|
174
- sha1 << io.read
175
- end
176
- sha1.hexdigest.should == @foo_digest
177
- end
178
-
179
- it "returns nil if the gem does not exist" do
180
- @repo.open( @missing_spec ).should == nil
181
- end
182
-
183
- it "does not call the block if the gem does not exist" do
184
- called = false
185
- @repo.open( @missing_spec ) do |io|
186
- called = true
187
- end
188
- called.should == false
189
- end
190
- end
191
-
192
- end