stickler 0.1.1 → 2.0.0a

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 (72) hide show
  1. data/HISTORY.rdoc +5 -2
  2. data/Rakefile +31 -0
  3. data/examples/config.ru +9 -0
  4. data/examples/gemcutter_repo.ru +19 -0
  5. data/examples/index_repo.ru +15 -0
  6. data/examples/local_repo.ru +14 -0
  7. data/examples/mirror_repo.ru +16 -0
  8. data/examples/not_found.ru +8 -0
  9. data/lib/stickler/error.rb +3 -0
  10. data/lib/stickler/middleware/compression.rb +30 -0
  11. data/lib/stickler/middleware/gemcutter.rb +62 -0
  12. data/lib/stickler/middleware/helpers.rb +84 -0
  13. data/lib/stickler/middleware/index.rb +137 -0
  14. data/lib/stickler/middleware/local.rb +38 -0
  15. data/lib/stickler/middleware/mirror.rb +60 -0
  16. data/lib/stickler/middleware/not_found.rb +62 -0
  17. data/lib/stickler/middleware.rb +4 -0
  18. data/lib/stickler/repository/api.rb +167 -0
  19. data/lib/stickler/repository/index.rb +97 -0
  20. data/lib/stickler/repository/local.rb +251 -0
  21. data/lib/stickler/repository/mirror.rb +48 -0
  22. data/lib/stickler/repository/null.rb +58 -0
  23. data/lib/stickler/repository/remote.rb +235 -0
  24. data/lib/stickler/repository.rb +7 -499
  25. data/lib/stickler/spec_lite.rb +60 -14
  26. data/lib/stickler/version.rb +6 -6
  27. data/lib/stickler/web.rb +19 -0
  28. data/spec/data/gems/bar-1.0.0.gem +0 -0
  29. data/spec/data/gems/foo-1.0.0.gem +0 -0
  30. data/spec/data/specifications/bar-1.0.0.gemspec +31 -0
  31. data/spec/data/specifications/foo-1.0.0.gemspec +31 -0
  32. data/spec/middleware/common_gem_server_helpers.rb +67 -0
  33. data/spec/middleware/index_spec.rb +26 -0
  34. data/spec/middleware/legacy_gem_server_behavior.rb +33 -0
  35. data/spec/middleware/local_spec.rb +25 -0
  36. data/spec/middleware/modern_gem_server_behavior.rb +20 -0
  37. data/spec/middleware/not_found_spec.rb +25 -0
  38. data/spec/repository/api_behavior.rb +162 -0
  39. data/spec/repository/api_spec.rb +38 -0
  40. data/spec/repository/index_spec.rb +32 -0
  41. data/spec/repository/local_spec.rb +36 -0
  42. data/spec/repository/null_spec.rb +17 -0
  43. data/spec/repository/remote_spec.rb +49 -0
  44. data/spec/spec.opts +2 -0
  45. data/spec/spec_helper.rb +15 -3
  46. data/spec/spec_lite_spec.rb +62 -0
  47. data/stickler.gemspec +60 -0
  48. data/views/index.erb +19 -0
  49. data/views/layout.erb +39 -0
  50. metadata +93 -63
  51. data/COPYING +0 -339
  52. data/bin/stickler +0 -58
  53. data/data/stickler.yml +0 -14
  54. data/gemspec.rb +0 -62
  55. data/lib/stickler/cli.rb +0 -302
  56. data/lib/stickler/configuration.rb +0 -74
  57. data/lib/stickler/console.rb +0 -72
  58. data/lib/stickler/paths.rb +0 -62
  59. data/lib/stickler/source.rb +0 -75
  60. data/lib/stickler/source_group.rb +0 -365
  61. data/lib/stickler.rb +0 -19
  62. data/spec/configuration_spec.rb +0 -68
  63. data/spec/paths_spec.rb +0 -25
  64. data/spec/repository_spec.rb +0 -55
  65. data/spec/version_spec.rb +0 -17
  66. data/tasks/announce.rake +0 -39
  67. data/tasks/config.rb +0 -107
  68. data/tasks/distribution.rake +0 -45
  69. data/tasks/documentation.rake +0 -31
  70. data/tasks/rspec.rake +0 -29
  71. data/tasks/rubyforge.rake +0 -51
  72. data/tasks/utils.rb +0 -80
data/lib/stickler/cli.rb DELETED
@@ -1,302 +0,0 @@
1
- #--
2
- # Copyright (c) 2008 Jeremy Hinegardner
3
- # All rights reserved. Licensed under the same terms as Ruby. No warranty is
4
- # provided. See LICENSE and COPYING for details.
5
- #++
6
-
7
- require 'main'
8
- require 'stickler'
9
-
10
- module Stickler
11
-
12
- #
13
- # Convert the Parameters::List that exists as the parameters from Main
14
- #
15
- def self.params_to_hash( params )
16
- h = Hash.new
17
- params.each do |p|
18
- h [p.names.first ] = p.value
19
- end
20
- return h
21
- end
22
-
23
- #
24
- # ::Main.create returns a class that is instantiated with ARGV and ENV as
25
- # parameters. The Cli is then used as:
26
- #
27
- # Cli.new( ARGV, ENV ).run
28
- #
29
- CLI = ::Main.create {
30
-
31
- author "Copyright (c) 2008 Jeremy Hinegardner <jeremy@copiousfreetime.org>"
32
- version Stickler::VERSION
33
-
34
- description <<-txt
35
- Stickler is a tool to organize and maintain an internal gem
36
- distribution server. It synchronizes locally distriubted gems
37
- with their upstream version, and locks the local version to a
38
- particular version.
39
-
40
- run 'stickler help modename' for more info.
41
- txt
42
-
43
- examples <<-txt
44
- . stickler setup
45
- . stickler remove gem rails
46
- . stickler add gem ramaze
47
- . stickler add gem keybox --version 1.2.1
48
- . stickler sync
49
- . stickler info
50
- . stickler generate index
51
- txt
52
-
53
- option( :quiet, "q" ) {
54
- description 'be quiet about logging to stdout'
55
- default false
56
- }
57
-
58
- option( :debug ) {
59
- description 'be verbose about logging in general'
60
- default false
61
- }
62
-
63
- run { help! }
64
-
65
- mode( :setup ) {
66
- description 'setup a directory as a stickler repository'
67
- argument( 'directory' ) {
68
- description "the stickler repository directory"
69
- default Stickler::Repository.default_directory
70
- }
71
-
72
- examples <<-txt
73
- . stickler setup
74
- . stickler setup /tmp/stickler
75
- txt
76
-
77
- mixin :option_force
78
-
79
- run {
80
- Stickler::Repository.new( Stickler.params_to_hash( params ) ).setup
81
- }
82
- }
83
-
84
- mode( :info ) {
85
- description 'report information about the stickler repository'
86
-
87
- examples <<-txt
88
- . stickler info
89
- txt
90
-
91
- mixin :option_directory
92
-
93
- run { Stickler::Repository.new( Stickler.params_to_hash( params ) ).info }
94
- }
95
-
96
- mode( :add ) do
97
- description <<-desc
98
- Add a gem and all dependencies or a source to the repository.
99
- desc
100
-
101
- examples <<-txt
102
- . stickler add gem heel
103
- . stickler add gem ramaze -v 0.3.5
104
- . stickler add source http://gems.github.com/
105
- txt
106
-
107
- mode( :gem ) do
108
- description <<-desc
109
- Add a gem and all its dependencies to the repository. Run from
110
- within the stickler repository or use the --directory option
111
- desc
112
-
113
- examples <<-txt
114
- . stickler add gem heel
115
- . stickler add gem ramaze -v 2008.06 --directory /var/stickler
116
- txt
117
-
118
- argument( 'gem_name' ) { description "The gem to add" }
119
- mixin :option_directory
120
- mixin :option_version
121
-
122
- option( :requirements ) {
123
- desc <<-desc
124
- Satisfy dependency requirements using minimum or the maximum version
125
- that satisfies the dependency. For instance if you had a gem that
126
- dependend on rake >= 0.8.1, if you used --requirements minimum then
127
- stickler will download rake-0.8.1. If you used --requrements maximum
128
- then stickler will download the latest version of rake.
129
- desc
130
-
131
- argument( :required )
132
- validate { |r| %w[ maximum minimum ].include?( r.downcase ) }
133
- default 'maximum'
134
- }
135
-
136
- run {
137
- p = Stickler.params_to_hash( params )
138
- repo = Stickler::Repository.new( p )
139
- repo.add_gem( p['gem_name'], p['version'] || :latest )
140
- }
141
- end
142
-
143
- mode( :source ) do
144
- description <<-desc
145
- Add a source the repository. This makes that source available
146
- for use within the repository. Run from within the stickler
147
- repository or use the --directory option.
148
- desc
149
-
150
- examples <<-txt
151
- . stickler add source http://gems.github.com/
152
- txt
153
-
154
- argument( 'source_uri' ) { description "the source uri to add" }
155
-
156
- mixin :option_directory
157
-
158
- run {
159
- p = Stickler.params_to_hash( params )
160
- repo = Stickler::Repository.new( p )
161
- repo.add_source( p['source_uri'] )
162
- }
163
- end
164
- end
165
-
166
- mode( :remove ) do
167
- description 'remove a gem or source from the repository'
168
- example <<-txt
169
- . stickler remove gem mongrel
170
- . stickler remove gem rails
171
- . stickler remove source htp://gems.github.com/
172
- txt
173
-
174
- mode( :gem ) do
175
- description <<-desc
176
- Remove a gem and all other gems that depend on it from the repository.
177
- Run from within the stickler repository or use the --directory option
178
- desc
179
-
180
- example <<-txt
181
- . stickler remove gem mongrel
182
- . stickler remove gem rails
183
- txt
184
-
185
- mixin :option_directory
186
- mixin :option_version
187
-
188
- argument( 'gem_name' ) { description "The gem to remove" }
189
-
190
- run {
191
- p = Stickler.params_to_hash( params )
192
- repo = Stickler::Repository.new( p )
193
- repo.remove_gem( p['gem_name'], p['version'] || :all )
194
- }
195
- end
196
-
197
- mode( :source ) do
198
- description <<-desc
199
- Remove a source and all is gems from the repository.
200
- Run from within the stickler repository or use the --directory option
201
- desc
202
-
203
- example <<-txt
204
- . stickler remove source htp://gems.github.com/
205
- txt
206
-
207
- mixin :option_directory
208
- argument( 'source_uri' ) { description "The source to remove" }
209
-
210
- run {
211
- p = Stickler.params_to_hash( params )
212
- repo = Stickler::Repository.new( p )
213
- repo.remove_source( p['source_uri'] )
214
- }
215
- end
216
-
217
- end
218
-
219
- mode( 'sync' ) do
220
- description <<-desc
221
- check and make sure all the gems in the configuration file are available.
222
- desc
223
-
224
- example <<-txt
225
- . sticker sync --rebuild
226
- txt
227
-
228
- mixin :option_directory
229
- option( :rebuild ) {
230
- description "Rebuild the repository from scratch"
231
- default false
232
- }
233
-
234
-
235
- run {
236
- p = Stickler.params_to_hash( params )
237
- repo = Stickler::Repository.new( p )
238
- repo.sync( p['rebuild'] )
239
- }
240
- end
241
-
242
- mode( 'generate' ) do
243
- mode( 'sysconfig' ) do
244
- description <<-desc
245
- generate the system wide configuration for use by rubygem clients that should use
246
- the repository stickler creates.
247
- desc
248
-
249
- example <<-txt
250
- . stickler generate sysconfig
251
- txt
252
-
253
- mixin :option_directory
254
- run {
255
- p = Stickler.params_to_hash( params )
256
- repo = Stickler::Repository.new( p )
257
- repo.generate_sysconfig
258
- }
259
- end
260
-
261
- mode( 'index' ) do
262
- description <<-desc
263
- generate the rubygems index of the gems to distribute in this repository.
264
- This is the same as doing a 'gem generate_index' but with a scope limited
265
- to just the gems in this repository.
266
- desc
267
-
268
- example <<-txt
269
- . stickler generate index
270
- txt
271
-
272
- mixin :option_directory
273
- run {
274
- p = Stickler.params_to_hash( params )
275
- repo = Stickler::Repository.new( p )
276
- repo.generate_index
277
- }
278
- end
279
- end
280
-
281
- ##
282
- # common options used by more than one commands
283
- #
284
- mixin :option_directory do
285
- option( :directory, "d" ) {
286
- argument :required
287
- default Dir.pwd
288
- }
289
- end
290
-
291
- mixin :option_force do
292
- option( :force ) { default false }
293
- end
294
-
295
- mixin :option_version do
296
- option( :version, "v" ) {
297
- argument :required
298
- }
299
- end
300
-
301
- }
302
- end
@@ -1,74 +0,0 @@
1
- module Stickler
2
- #
3
- #
4
- #
5
- class Configuration
6
-
7
- attr_reader :config_file_name
8
-
9
- def initialize( config_file_name )
10
- @config_file_name = config_file_name
11
- @hash = YAML.load_file( config_file_name )
12
- @hash['sources'] = @hash['sources'].collect do |uri|
13
- p = uri.split("/")
14
- p.join("/") + "/" # ensure a trailing slash
15
- end
16
- end
17
-
18
- # the array of sources in this configuration
19
- def sources
20
- hash['sources']
21
- end
22
-
23
- # the downstream source this repository represents
24
- def downstream_source
25
- hash['downstream_source']
26
- end
27
-
28
- # The gem and version requirements for this repository
29
- def gem_dependencies
30
- unless @gem_dependencies
31
- @gem_dependencies = []
32
- if hash['gems'] then
33
- hash['gems'].each do |name, reqs|
34
- [ reqs ].flatten.each do |req|
35
- @gem_dependencies << ::Gem::Dependency.new( name, req )
36
- end
37
- end
38
- end
39
- end
40
- return @gem_dependencies
41
- end
42
-
43
- def write
44
- File.open( config_file_name, 'w' ) do |f|
45
- g = Hash.new { |h,k| h[k] = [] }
46
- gem_dependencies.each do |d|
47
- g[d.name] << d.requirement_list
48
- g[d.name].flatten!
49
- end
50
- hash['gems'] = g
51
- f.write hash.to_yaml
52
- end
53
- end
54
-
55
- def keys
56
- @hash.keys
57
- end
58
-
59
- def []( key )
60
- @hash[ key.to_s ]
61
- end
62
-
63
- def []=( key, value )
64
- @hash[ key.to_s ] = value
65
- end
66
-
67
- def ==( other )
68
- self.class === other and hash == other.hash
69
- end
70
-
71
- protected
72
- attr_reader :hash
73
- end
74
- end
@@ -1,72 +0,0 @@
1
-
2
- module Stickler
3
- #
4
- # containment for the output that a user should see. This uses a Logger so
5
- # that it can be throttled based on level at some point
6
- #
7
- class Console
8
- class << self
9
- #
10
- # Items that get logged to stderr for the user to see should use this logger
11
- #
12
- def logger
13
- unless @logger
14
- @logger = ::Logging::Logger['User']
15
- @logger.level = :info
16
- @logger.add_appenders(::Logging::Appender.stderr)
17
- ::Logging::Appender.stderr.layout = Logging::Layouts::Pattern.new( :pattern => "%m\n" )
18
- ::Logging::Appender.stderr.level = :info
19
- end
20
- return @logger
21
- end
22
-
23
- # force initialization
24
- Console.logger
25
-
26
- #
27
- # default logging leve
28
- #
29
- def default_level
30
- :info
31
- end
32
-
33
- #
34
- # Quick wrappers around the log levels
35
- #
36
- ::Logging::LEVELS.keys.each do |l|
37
- module_eval <<-code
38
- def #{ l }( msg )
39
- @logger.#{l} msg
40
- end
41
- code
42
- end
43
-
44
- #
45
- # Turn off the logging
46
- #
47
- def silent!
48
- logger.level = :off
49
- end
50
-
51
- #
52
- # Resume logging
53
- #
54
- def resume!
55
- logger.level = self.default_level
56
- end
57
-
58
-
59
- #
60
- # Turn off logging for the execution of a block
61
- #
62
- def silent( &block )
63
- begin
64
- silent!
65
- block.call
66
- ensure
67
- resume!
68
- end
69
- end
70
- end
71
- end
72
- end
@@ -1,62 +0,0 @@
1
- #--
2
- # Copyright (c) 2008 Jeremy Hinegardner
3
- # All rights reserved. Licensed under the same terms as Ruby. No warranty is
4
- # provided. See LICENSE and COPYING for details.
5
- #++
6
-
7
- module Stickler
8
-
9
- # Paths module used by all the other modules and classes for
10
- # determining paths and default values.
11
- #
12
- module Paths
13
-
14
- #
15
- # The root directory of the project is considered to be the parent directory
16
- # of the 'lib' directory. returns the full expanded path of the parent
17
- # directory of 'lib' going up the path from the current file. A trailing
18
- # File::SEPARATOR is guaranteed.
19
- #
20
- def self.root_dir
21
- unless @root_dir
22
- path_parts = ::File.expand_path(__FILE__).split(::File::SEPARATOR)
23
- lib_index = path_parts.rindex("lib")
24
- @root_dir = path_parts[0...lib_index].join(::File::SEPARATOR) + ::File::SEPARATOR
25
- end
26
- return @root_dir
27
- end
28
-
29
- #
30
- # return the full expanded path of the +config+ directory below +root_dir+.
31
- # All parameters passed in are joined on to the result. a Trailing
32
- # File::SEPARATOR is guaranteed if _args_ are *not* present
33
- #
34
- def self.config_path(*args)
35
- self.sub_path("config", *args)
36
- end
37
-
38
- #
39
- # return the full expanded path of the +data+ directory below +root_dir+.
40
- # All parameters passed in are joined on to the result. a Trailing
41
- # File::SEPARATOR is guaranteed if _args_ are *not* present
42
- #
43
- def self.data_path(*args)
44
- self.sub_path("data", *args)
45
- end
46
-
47
- #
48
- # return the full expanded path of the +lib+ directory below +root_dir+.
49
- # All parameters passed in are joined on to the result. a Trailing
50
- # File::SEPARATOR is guaranteed if _args_ are *not* present
51
- #
52
- def self.lib_path(*args)
53
- self.sub_path("lib", *args)
54
- end
55
-
56
- private
57
- def self.sub_path(sub,*args)
58
- sp = ::File.join(root_dir, sub) + File::SEPARATOR
59
- sp = ::File.join(sp, *args) if args
60
- end
61
- end
62
- end
@@ -1,75 +0,0 @@
1
- require 'uri'
2
- require 'base64'
3
- require 'zlib'
4
-
5
- module Stickler
6
- #
7
- # The representation of an upstream source from which stickler pulls gems.
8
- # This wraps up the contents of the upstream specs.4.8 file found in a
9
- # rubygems 1.2 or greater repository.
10
- #
11
- class Source
12
- class Error < ::StandardError; end
13
-
14
- # the uri of the source
15
- attr_reader :uri
16
-
17
- # the source_group this source belongs to
18
- attr_accessor :source_group
19
-
20
- def self.normalize_uri( uri )
21
- return uri if uri.kind_of?( URI::Generic )
22
- path_parts = uri.split( "/" )
23
- uri = path_parts.join( "/" ) + "/"
24
- uri = ::URI.parse( uri )
25
- end
26
-
27
- #
28
- # Create a new Source for a source_group.
29
- # Try and load the source from the cache if it can and if not,
30
- # load it from the uri
31
- #
32
- def initialize( uri, source_group )
33
-
34
- begin
35
- @uri = Source.normalize_uri( uri )
36
- @source_group = source_group
37
- load_source_specs
38
-
39
- rescue ::URI::Error => e
40
- raise Error, "Unable to create source from uri #{uri} : #{e}"
41
- end
42
- end
43
-
44
- #
45
- # find all matching gems and return their SpecLite
46
- #
47
- def search( dependency )
48
- found = source_specs.select do | spec |
49
- dependency =~ Gem::Dependency.new( spec.name, spec.version )
50
- end
51
- end
52
-
53
- #
54
- # load the upstream or cached specs.marshalversion file for the source.
55
- #
56
- def source_specs
57
- unless @source_specs
58
- Console.info " * loading #{uri}"
59
- @source_specs = []
60
- ::Gem::SpecFetcher.fetcher.load_specs( uri, 'specs' ).each do |name, version, platform|
61
- @source_specs << SpecLite.new( name, version, platform )
62
- end
63
- end
64
- return @source_specs
65
- end
66
-
67
- #
68
- # force a load of the source_specs
69
- #
70
- def load_source_specs
71
- @source_specs = nil
72
- return source_specs
73
- end
74
- end
75
- end