stickler 2.0.2 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/HISTORY.asciidoc +17 -8
- data/LICENSE +13 -54
- data/README.asciidoc +29 -5
- data/Rakefile +11 -10
- data/TODO.asciidoc +6 -0
- data/bin/stickler +5 -2
- data/examples/fetch-a-gem +6 -0
- data/examples/gemcutter_repo.ru +1 -1
- data/lib/stickler.rb +1 -1
- data/lib/stickler/client.rb +1 -0
- data/lib/stickler/client/list.rb +30 -0
- data/lib/stickler/client/mirror.rb +5 -5
- data/lib/stickler/client/push.rb +1 -1
- data/lib/stickler/middleware/gemcutter.rb +2 -2
- data/lib/stickler/middleware/helpers.rb +37 -42
- data/lib/stickler/middleware/index.rb +51 -19
- data/lib/stickler/repository/index.rb +46 -9
- data/lib/stickler/repository/local.rb +75 -20
- data/lib/stickler/repository/null.rb +0 -2
- data/lib/stickler/repository/remote.rb +81 -64
- data/lib/stickler/repository/rubygems_authenticator.rb +3 -8
- data/lib/stickler/server.rb +1 -1
- data/lib/stickler/spec_lite.rb +13 -10
- data/lib/stickler/version.rb +2 -2
- data/man/stickler.asciidoc +3 -1
- data/spec/data/gems/foo-2.0.0a.gem +0 -0
- data/spec/index_spec_helpers.rb +71 -0
- data/spec/middleware/local_spec.rb +58 -10
- data/spec/middleware/not_found_spec.rb +1 -0
- data/spec/repository/index_spec.rb +15 -0
- data/spec/repository/local_spec.rb +20 -5
- data/spec/repository/remote_spec.rb +2 -3
- data/spec/spec.opts +1 -1
- data/spec/spec_helper.rb +8 -6
- data/spec/spec_lite_spec.rb +19 -6
- data/tasks/man.rake +1 -1
- metadata +74 -40
- data/spec/middleware/common_gem_server_helpers.rb +0 -69
- data/spec/middleware/index_spec.rb +0 -26
- data/spec/middleware/legacy_gem_server_behavior.rb +0 -31
- data/spec/middleware/modern_gem_server_behavior.rb +0 -22
data/.gitignore
CHANGED
data/HISTORY.asciidoc
CHANGED
@@ -2,19 +2,28 @@ Stickler Changelog
|
|
2
2
|
==================
|
3
3
|
Jeremy Hinegardner <jeremy@hinegardner.org>
|
4
4
|
|
5
|
-
Version 2.0
|
6
|
-
|
5
|
+
Version 2.1.0 - 2011-03-25
|
6
|
+
--------------------------
|
7
|
+
* Added 'list' client command
|
8
|
+
* Added support for prerelease gems
|
9
|
+
* Internal refactoring of how internal repositories are managed
|
10
|
+
* Refactored testing and updated to rspec2
|
11
|
+
* Switched underlying HTTP client to Excon
|
12
|
+
* Change to ISC License
|
13
|
+
|
14
|
+
Version 2.0.1 - 2010-09-19
|
15
|
+
--------------------------
|
7
16
|
* Complete rewrite using Rack and Sinatra
|
8
17
|
|
9
|
-
Version 0.1.2
|
10
|
-
|
18
|
+
Version 0.1.2 - 2009-02-19
|
19
|
+
--------------------------
|
11
20
|
* fix compatibility with gems 1.3.1
|
12
21
|
|
13
|
-
Version 0.1.1
|
14
|
-
|
22
|
+
Version 0.1.1 - 2008-10-12
|
23
|
+
--------------------------
|
15
24
|
* remove unnecessary require 'progressbar'
|
16
25
|
|
17
|
-
Version 0.1.0
|
18
|
-
|
26
|
+
Version 0.1.0 - 2008-10-10
|
27
|
+
--------------------------
|
19
28
|
* http://copiousfreetime.org/articles/2008/10/09/managing-a-gem-repository-with-stickler.html[Managing a Gem Repository with Stickler]
|
20
29
|
* Initial public release
|
data/LICENSE
CHANGED
@@ -1,54 +1,13 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
modifications to Usenet or an equivalent medium, or by allowing
|
15
|
-
the author to include your modifications in the software.
|
16
|
-
|
17
|
-
b) use the modified software only within your corporation or
|
18
|
-
organization.
|
19
|
-
|
20
|
-
c) rename any non-standard executables so the names do not conflict
|
21
|
-
with standard executables, which must also be provided.
|
22
|
-
|
23
|
-
d) make other distribution arrangements with the author.
|
24
|
-
|
25
|
-
3. You may distribute the software in object code or executable
|
26
|
-
form, provided that you do at least ONE of the following:
|
27
|
-
|
28
|
-
a) distribute the executables and library files of the software,
|
29
|
-
together with instructions (in the manual page or equivalent)
|
30
|
-
on where to get the original distribution.
|
31
|
-
|
32
|
-
b) accompany the distribution with the machine-readable source of
|
33
|
-
the software.
|
34
|
-
|
35
|
-
c) give non-standard executables non-standard names, with
|
36
|
-
instructions on where to get the original software distribution.
|
37
|
-
|
38
|
-
d) make other distribution arrangements with the author.
|
39
|
-
|
40
|
-
4. You may modify and include the part of the software into any other
|
41
|
-
software (possibly commercial). But some files in the distribution
|
42
|
-
are not written by the author, so that they are not under this terms.
|
43
|
-
|
44
|
-
5. The scripts and library files supplied as input to or produced as
|
45
|
-
output from the software do not automatically fall under the
|
46
|
-
copyright of the software, but belong to whomever generated them,
|
47
|
-
and may be sold commercially, and may be aggregated with this
|
48
|
-
software.
|
49
|
-
|
50
|
-
6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
|
51
|
-
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
52
|
-
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
53
|
-
PURPOSE.
|
54
|
-
|
1
|
+
Copyright (c) 2008-2010, Jeremy Hinegadner
|
2
|
+
|
3
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
4
|
+
purpose with or without fee is hereby granted, provided that the above
|
5
|
+
copyright notice and this permission notice appear in all copies.
|
6
|
+
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
8
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
9
|
+
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
10
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
11
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
12
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
13
|
+
PERFORMANCE OF THIS SOFTWARE.
|
data/README.asciidoc
CHANGED
@@ -83,12 +83,39 @@ Pushing gem(s) to http://localhost:6789/ ...
|
|
83
83
|
/Users/jeremy/tmp/gems/stickler-2.0.0.gem -> OK http://localhost:6789/gems/stickler-2.0.0.gem
|
84
84
|
------------------------------------------------------------------
|
85
85
|
|
86
|
-
.Mirror a gem
|
86
|
+
.Mirror a gem from upstream
|
87
87
|
------------------------------------------------------------------
|
88
88
|
% stickler mirror --gem-version 1.4.3 logging
|
89
89
|
Asking http://localhost:6789/ to mirror logging-1.4.3 from rubygems.org : OK -> http://localhost:6789/gems/logging-1.4.3.gem
|
90
|
+
% stickler mirror --gem-version 1.16.2 trollop
|
91
|
+
Asking http://localhost:6789/ to mirror trollop-1.16.2 from rubygems.org : OK -> http://localhost:6789/gems/trollop-1.16.2.gem
|
90
92
|
------------------------------------------------------------------
|
91
93
|
|
94
|
+
.Look at all the gems installed in your stickler server
|
95
|
+
Open your browser to http://localhost:6789
|
96
|
+
-------------------------------
|
97
|
+
% launchy http://localhost:6789
|
98
|
+
-------------------------------
|
99
|
+
|
100
|
+
.Install a gem from your new stickler gem server
|
101
|
+
------------------------------------------------------
|
102
|
+
% gem install hitimes --source http://localhost:6789/
|
103
|
+
------------------------------------------------------
|
104
|
+
|
105
|
+
.Configure your servers to globally use your internal stickler gem server
|
106
|
+
-----------------------------
|
107
|
+
% cat /etc/gemrc
|
108
|
+
---
|
109
|
+
:benchmark: false
|
110
|
+
:verbose: false
|
111
|
+
:update_sources: true
|
112
|
+
:bulk_threshold: 1000
|
113
|
+
:backtrace: false
|
114
|
+
:sources:
|
115
|
+
- http://stickler.example.com
|
116
|
+
gem: --no-rdoc --no-ri
|
117
|
+
-----------------------------
|
118
|
+
|
92
119
|
|
93
120
|
See Also
|
94
121
|
--------
|
@@ -114,10 +141,7 @@ Credits
|
|
114
141
|
License
|
115
142
|
-------
|
116
143
|
Copyright (C) 2008-2010 Jeremy Hinegardner
|
117
|
-
|
118
|
-
All rights reserved. Licensed under the same terms as Ruby. No warranty is
|
119
|
-
provided. See LICENSE and COPYING for details.
|
120
|
-
|
144
|
+
ISC License, See LICENSE for details
|
121
145
|
|
122
146
|
Appendix
|
123
147
|
--------
|
data/Rakefile
CHANGED
@@ -21,9 +21,8 @@ Bones {
|
|
21
21
|
readme_file 'README.asciidoc'
|
22
22
|
ignore_file '.bnsignore'
|
23
23
|
history_file 'HISTORY.asciidoc'
|
24
|
-
rubyforge.name 'copiousfreetime'
|
25
24
|
|
26
|
-
spec.opts << "--color" << "--format
|
25
|
+
spec.opts << "--color" << "--format documentation"
|
27
26
|
|
28
27
|
summary 'Stickler is a tool to organize and maintain an internal gem repository.'
|
29
28
|
description <<_
|
@@ -38,13 +37,15 @@ Primarily, you would want to use Stickler if:
|
|
38
37
|
_
|
39
38
|
|
40
39
|
|
41
|
-
depend_on 'sinatra', '~> 1.
|
42
|
-
depend_on 'addressable', '~> 2.
|
43
|
-
depend_on '
|
44
|
-
depend_on 'trollop', '~> 1.16.2'
|
45
|
-
depend_on 'logging', '~> 1.
|
40
|
+
depend_on 'sinatra' , '~> 1.2.1'
|
41
|
+
depend_on 'addressable', '~> 2.2.4'
|
42
|
+
depend_on 'excon' , '~> 0.5.8'
|
43
|
+
depend_on 'trollop' , '~> 1.16.2'
|
44
|
+
depend_on 'logging' , '~> 1.5.0'
|
46
45
|
|
47
|
-
depend_on 'bones' , '~> 3.
|
48
|
-
depend_on 'rack-test' , '~> 0.5.
|
49
|
-
depend_on 'bones-extras', '~> 1.
|
46
|
+
depend_on 'bones' , '~> 3.6.5', :development => true
|
47
|
+
depend_on 'rack-test' , '~> 0.5.7', :development => true
|
48
|
+
depend_on 'bones-extras', '~> 1.3.0', :development => true
|
49
|
+
depend_on 'builder' , '~> 3.0.0', :development => true
|
50
|
+
depend_on 'rspec' , '~> 2.5.0', :development => true
|
50
51
|
}
|
data/TODO.asciidoc
ADDED
@@ -0,0 +1,6 @@
|
|
1
|
+
* Add in a full transparent proxy for automatically pullilng gems from an
|
2
|
+
upstream gem server if the local gem server does not have the gem in question
|
3
|
+
* There appears to be something different about evaling the specification off
|
4
|
+
disk, and the loading the specification from the yaml in the .gem file. They
|
5
|
+
are different. It appears that @original_platform is not set when the Ruby
|
6
|
+
specification is eval'd but it is when the yaml is loaded.
|
data/bin/stickler
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
require 'stickler'
|
4
4
|
require 'stickler/client'
|
5
5
|
|
6
|
-
SUB_COMMANDS = %w[ push yank mirror config ]
|
6
|
+
SUB_COMMANDS = %w[ push yank mirror config list ].sort
|
7
7
|
exec_name = File.basename( $0 )
|
8
8
|
|
9
9
|
#----------------------------------------------------------------------
|
@@ -20,9 +20,10 @@ Stickler server interaction
|
|
20
20
|
Examples:
|
21
21
|
#{exec_name} push ./my_gem-1.0.0.gem --server http://stickler.example.com/
|
22
22
|
#{exec_name} yank my_gem --version 1.0.0 --server http://stickler.example.com/
|
23
|
-
#{exec_name} mirror
|
23
|
+
#{exec_name} mirror third_party_gem --gem-version 0.4.2 --upstream http://rubygems.org/ --server http://stickler.example.com/
|
24
24
|
#{exec_name} mirror --help
|
25
25
|
#{exec_name} config --server http://stickler.example.com --upstream http://rubygems.org/
|
26
|
+
#{exec_name} list --server http://stickler.example.com
|
26
27
|
|
27
28
|
Options:
|
28
29
|
_
|
@@ -46,5 +47,7 @@ when "mirror"
|
|
46
47
|
::Stickler::Client::Mirror.new( ARGV ).run
|
47
48
|
when "config"
|
48
49
|
::Stickler::Client::Config.new( ARGV ).run
|
50
|
+
when "list"
|
51
|
+
::Stickler::Client::List.new( ARGV ).run
|
49
52
|
end
|
50
53
|
|
data/examples/gemcutter_repo.ru
CHANGED
@@ -13,7 +13,7 @@ $:.unshift File.expand_path( File.join( File.dirname(__FILE__), "..", "lib" ) )
|
|
13
13
|
require 'stickler/middleware/gemcutter'
|
14
14
|
require 'stickler/middleware/compression'
|
15
15
|
|
16
|
-
gem_dir = File.
|
16
|
+
gem_dir = File.expand_path( "../spec/tmp", File.dirname( __FILE__ ) )
|
17
17
|
|
18
18
|
use ::Stickler::Middleware::Compression
|
19
19
|
use ::Stickler::Middleware::Gemcutter, :repo_root => gem_dir
|
data/lib/stickler.rb
CHANGED
data/lib/stickler/client.rb
CHANGED
@@ -0,0 +1,30 @@
|
|
1
|
+
module Stickler
|
2
|
+
class Client
|
3
|
+
class List < Stickler::Client
|
4
|
+
def self.banner
|
5
|
+
<<-_
|
6
|
+
List the gems in the stickler server with repository information.
|
7
|
+
|
8
|
+
Usage: stickler list
|
9
|
+
|
10
|
+
Options:
|
11
|
+
_
|
12
|
+
end
|
13
|
+
|
14
|
+
def run
|
15
|
+
opts = parse( self.argv )
|
16
|
+
repo = remote_repo_for( opts )
|
17
|
+
gems = Hash.new { |h,k| h[k] = Array.new }
|
18
|
+
|
19
|
+
repo.specs_list.each do |name, version, platform|
|
20
|
+
spec = Stickler::SpecLite.new( name, version, platform )
|
21
|
+
gems[name] << spec
|
22
|
+
end
|
23
|
+
|
24
|
+
gems.keys.sort.each do |name|
|
25
|
+
puts "#{name} (#{gems[name].collect { |s| s.version_platform }.join( ", " )})"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -45,15 +45,15 @@ _
|
|
45
45
|
$stdout.write "Asking #{repo.uri} to mirror #{spec.full_name} from #{upstream_host} : "
|
46
46
|
$stdout.flush
|
47
47
|
|
48
|
-
uri
|
49
|
-
|
48
|
+
uri = [ repo.uri.join( upstream_host ), opts[:gem_name], opts[:gem_version], opts[:platform] ].join("/")
|
49
|
+
resp = Excon.post( uri, :expects => [200] )
|
50
50
|
|
51
|
-
resp = resource.post
|
52
51
|
$stdout.puts "OK -> #{repo.uri.join(resp.headers['Location'])}"
|
53
|
-
rescue
|
54
|
-
resp = he.
|
52
|
+
rescue Excon::Errors::Error => he
|
53
|
+
resp = he.response
|
55
54
|
$stdout.puts "ERROR -> #{resp.body}"
|
56
55
|
rescue StandardError => e
|
56
|
+
puts e.backtrace.join("\n")
|
57
57
|
$stdout.puts "ERROR -> #{e.message}"
|
58
58
|
end
|
59
59
|
end
|
data/lib/stickler/client/push.rb
CHANGED
@@ -31,7 +31,7 @@ _
|
|
31
31
|
|
32
32
|
width = opts[:gemfiles].collect { |g| g.length }.sort.last
|
33
33
|
|
34
|
-
puts "Pushing gem(s) to #{repo.uri} ..."
|
34
|
+
$stdout.puts "Pushing gem(s) to #{repo.uri} ..."
|
35
35
|
opts[:gemfiles].each do |gemfile|
|
36
36
|
begin
|
37
37
|
$stdout.write " #{gemfile.ljust( width )} -> "
|
@@ -4,7 +4,7 @@ require 'stickler/middleware/local'
|
|
4
4
|
require 'stickler/repository/local'
|
5
5
|
|
6
6
|
module Stickler::Middleware
|
7
|
-
#
|
7
|
+
#
|
8
8
|
# A rack middleware for implementing the gemcutter api
|
9
9
|
#
|
10
10
|
# == Options
|
@@ -46,7 +46,7 @@ module Stickler::Middleware
|
|
46
46
|
spec = Stickler::SpecLite.new( params[:gem_name], params[:version] )
|
47
47
|
if s = @repo.yank( spec ) then
|
48
48
|
logger.info( "Yanked #{spec.full_name}" )
|
49
|
-
return "Yanked #{
|
49
|
+
return "Yanked #{spec.full_name}"
|
50
50
|
else
|
51
51
|
logger.warn( "Did not Yank #{spec.full_name}" )
|
52
52
|
error( 503, "Did not Yank #{spec.to_s}" )
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'stickler/middleware'
|
2
|
+
require 'stickler/repository/local'
|
2
3
|
module Stickler::Middleware
|
3
4
|
module Helpers
|
4
5
|
#
|
@@ -34,15 +35,44 @@ module Stickler::Middleware
|
|
34
35
|
# The specs by repository
|
35
36
|
#
|
36
37
|
def specs_by_repo
|
37
|
-
|
38
|
+
Stickler::Repository::Local.repos
|
38
39
|
end
|
39
40
|
|
40
41
|
#
|
41
|
-
# return the
|
42
|
-
# <tt>#specs_by_repo</tt>
|
42
|
+
# return the list of all the specs in all the repos
|
43
43
|
#
|
44
44
|
def specs
|
45
|
-
|
45
|
+
collect_specs_via( :specs )
|
46
|
+
end
|
47
|
+
|
48
|
+
#
|
49
|
+
# return the list of all the latest_specs in all the repos
|
50
|
+
#
|
51
|
+
def latest_specs
|
52
|
+
collect_specs_via( :latest_specs )
|
53
|
+
end
|
54
|
+
|
55
|
+
#
|
56
|
+
# return the list of all the pre-release specs
|
57
|
+
#
|
58
|
+
def prerelease_specs
|
59
|
+
collect_specs_via( :prerelease_specs )
|
60
|
+
end
|
61
|
+
|
62
|
+
#
|
63
|
+
# return just the list of the releeased specs in all the repos
|
64
|
+
#
|
65
|
+
def released_specs
|
66
|
+
collect_specs_via( :released_specs )
|
67
|
+
end
|
68
|
+
|
69
|
+
#
|
70
|
+
# Collect all the specs via a call on each Repository
|
71
|
+
#
|
72
|
+
def collect_specs_via( method )
|
73
|
+
specs_by_repo.values.collect do |idx|
|
74
|
+
idx.send( method )
|
75
|
+
end.flatten.sort
|
46
76
|
end
|
47
77
|
|
48
78
|
#
|
@@ -69,48 +99,13 @@ module Stickler::Middleware
|
|
69
99
|
#
|
70
100
|
# Given a list of specs, this will group them by name
|
71
101
|
#
|
72
|
-
def specs_grouped_by_name(
|
102
|
+
def specs_grouped_by_name( spec_list )
|
73
103
|
by_name = Hash.new{ |h,k| h[k] = Array.new }
|
74
|
-
|
104
|
+
spec_list.each do |spec|
|
75
105
|
by_name[spec.name.downcase] << spec
|
76
106
|
end
|
77
107
|
return by_name
|
78
108
|
end
|
79
|
-
|
80
|
-
#
|
81
|
-
# Append spec or array of specs to the current list of specs for this key.
|
82
|
-
#
|
83
|
-
def append_spec( key, spec_or_array_of_specs )
|
84
|
-
if Array === spec_or_array_of_specs then
|
85
|
-
specs_by_repo[key].concat( spec_or_array_of_specs )
|
86
|
-
else
|
87
|
-
specs_by_repo[key] << spec_or_array_of_specs
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
#
|
92
|
-
# Automatically append the specs from the included class into the specs
|
93
|
-
# environment variable.
|
94
|
-
#
|
95
|
-
# The Class that includes this module and wants to use +append_specs+
|
96
|
-
# MUST have a +repo+ method. The +repo+ method must +respond_to+ both
|
97
|
-
# +root_dir+ and +specs+.
|
98
|
-
#
|
99
|
-
def append_specs
|
100
|
-
append_spec( self.repo.root_dir, self.repo.specs )
|
101
|
-
end
|
102
|
-
|
103
|
-
#
|
104
|
-
# Automatically append the latest_specs from the included class into the
|
105
|
-
# specs environment variable.
|
106
|
-
#
|
107
|
-
# The Class that includes this module and wants to use +append_specs+ MUST
|
108
|
-
# have a +repo+ method. The +repo+ method must +respond_to+ both
|
109
|
-
# +root_dir+ and +specs+.
|
110
|
-
#
|
111
|
-
def append_latest_specs
|
112
|
-
append_spec( self.repo.root_dir, self.repo.latest_specs )
|
113
|
-
end
|
114
|
-
end
|
109
|
+
end
|
115
110
|
end
|
116
111
|
end
|