stickler 0.1.1 → 2.0.0a

Sign up to get free protection for your applications and to get access to all the features.
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