stickler 2.3.0 → 2.4.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.
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