stickler 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/bin/stickler ADDED
@@ -0,0 +1,58 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ begin
4
+ require 'stickler'
5
+ rescue LoadError
6
+ require 'rubygems'
7
+ $: << File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
8
+ require 'stickler'
9
+ end
10
+
11
+ cli = Stickler::CLI.new(ARGV, ENV)
12
+ begin
13
+ cli.run
14
+ rescue => e
15
+ $stderr.puts "ERROR: #{e}"
16
+ $stderr.puts cli.usage.to_s
17
+ end
18
+
19
+ __END__
20
+ gem = ARGV.shift
21
+ ver = ARGV.shift || Gem::Requirement.default
22
+
23
+ require 'rubygems/source_info_cache'
24
+ require 'rubygems/dependency_list'
25
+
26
+ original_dep = Gem::Dependency.new( gem, ver )
27
+
28
+ # actually search through and find the ones for this platform
29
+ def spec_from_dependency(dep)
30
+ spec_and_source = Gem::SourceInfoCache.search_with_source(dep).reverse.first
31
+ spec = spec_and_source.first
32
+ return spec
33
+ end
34
+
35
+ dep_stack = []
36
+ dep_stack.push(spec_from_dependency(original_dep))
37
+ dep_list = Gem::DependencyList.new
38
+ seen = {}
39
+
40
+ until dep_stack.empty?
41
+ spec = dep_stack.pop
42
+ next if spec.nil? or seen[spec.name]
43
+ puts "---> #{spec.full_name}"
44
+ seen[spec.name] = true
45
+
46
+ spec.dependencies.each do |dep|
47
+ d = spec_from_dependency(dep)
48
+ next if seen[d.name]
49
+ puts "<--- #{d.full_name}"
50
+ dep_stack.push(d)
51
+ end
52
+ dep_list.add spec
53
+ end
54
+
55
+
56
+ dep_list.dependency_order.reverse.each do |s|
57
+ puts "Install #{s.full_name}"
58
+ end
data/data/stickler.yml ADDED
@@ -0,0 +1,14 @@
1
+ #
2
+ # Stickler Respository configuration, this is a superset of a Gem configuration
3
+ # file so it has the same keys as Gem::ConfigFile plus some more used by
4
+ # Stickler
5
+ #
6
+
7
+ # The source that other rubygems installations will use to access the gems
8
+ # collected and managed by stickler.
9
+ downstream_source: "http://gems.example.com/"
10
+
11
+ # The upstream locations that stickler should look for gems.
12
+ sources:
13
+ - http://gems.rubyforge.org
14
+
data/gemspec.rb ADDED
@@ -0,0 +1,62 @@
1
+ require 'rubygems'
2
+ require 'stickler/version'
3
+ require 'tasks/config'
4
+
5
+ Stickler::GEM_SPEC = Gem::Specification.new do |spec|
6
+ proj = Configuration.for('project')
7
+ spec.name = proj.name
8
+ spec.version = Stickler::VERSION
9
+
10
+ spec.author = proj.author
11
+ spec.email = proj.email
12
+ spec.homepage = proj.homepage
13
+ spec.summary = proj.summary
14
+ spec.description = proj.description
15
+ spec.platform = Gem::Platform::RUBY
16
+
17
+ spec.post_install_message = <<-msg
18
+ ============================================================
19
+
20
+ Thank you for installing Stickler!
21
+
22
+ * Create a new stickler repository:
23
+ stickler setup /path/to/repo
24
+
25
+ * Look at the help:
26
+ stickler help
27
+
28
+ ============================================================
29
+ msg
30
+
31
+
32
+ spec.required_rubygems_version = [ ">= 1.2.0" ]
33
+
34
+ spec.add_runtime_dependency( 'highline', "~> 1.4" )
35
+ spec.add_runtime_dependency( 'logging', "~> 0.9" )
36
+ spec.add_runtime_dependency( 'main', "~> 2.8" )
37
+
38
+ spec.add_development_dependency( 'rake', "~> 0.8" )
39
+ spec.add_development_dependency( 'rspec', "~> 1.1" )
40
+ spec.add_development_dependency( 'configuration', "~> 0.0" )
41
+
42
+ pkg = Configuration.for('packaging')
43
+ spec.files = pkg.files.all
44
+ spec.executables = pkg.files.bin.collect { |b| File.basename(b) }
45
+
46
+ if rdoc = Configuration.for_if_exist?('rdoc') then
47
+ spec.has_rdoc = true
48
+ spec.extra_rdoc_files = pkg.files.rdoc
49
+ spec.rdoc_options = rdoc.options + [ "--main" , rdoc.main_page ]
50
+ else
51
+ spec.has_rdoc = false
52
+ end
53
+
54
+ if test = Configuration.for_if_exist?('testing') then
55
+ spec.test_files = test.files
56
+ end
57
+
58
+
59
+ if rf = Configuration.for_if_exist?('rubyforge') then
60
+ spec.rubyforge_project = rf.project
61
+ end
62
+ end
data/lib/stickler.rb ADDED
@@ -0,0 +1,19 @@
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 'logging'
8
+
9
+ module Stickler
10
+ end
11
+
12
+ require 'stickler/paths'
13
+ require 'stickler/version'
14
+ require 'stickler/console'
15
+ require 'stickler/source'
16
+ require 'stickler/repository'
17
+ require 'stickler/spec_lite'
18
+ require 'stickler/configuration'
19
+ require 'stickler/cli'
@@ -0,0 +1,302 @@
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