stickler 2.0.0a → 2.0.1

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 (64) hide show
  1. data/.bnsignore +14 -0
  2. data/.gitignore +17 -0
  3. data/HISTORY.asciidoc +20 -0
  4. data/README.asciidoc +126 -0
  5. data/Rakefile +22 -3
  6. data/bin/stickler +50 -0
  7. data/bin/stickler-passenger-config +112 -0
  8. data/bin/stickler-server +109 -0
  9. data/examples/config.ru +6 -3
  10. data/examples/gemcutter_repo.ru +2 -0
  11. data/examples/index_repo.ru +2 -0
  12. data/examples/local_repo.ru +6 -3
  13. data/examples/mirror_repo.ru +2 -0
  14. data/examples/not_found.ru +2 -0
  15. data/lib/stickler.rb +12 -0
  16. data/lib/stickler/client.rb +47 -0
  17. data/lib/stickler/client/config.rb +35 -0
  18. data/lib/stickler/client/config_file.rb +58 -0
  19. data/lib/stickler/client/mirror.rb +61 -0
  20. data/lib/stickler/client/push.rb +50 -0
  21. data/lib/stickler/client/yank.rb +51 -0
  22. data/lib/stickler/logable.rb +35 -0
  23. data/lib/stickler/middleware/gemcutter.rb +5 -0
  24. data/lib/stickler/middleware/helpers.rb +32 -0
  25. data/lib/stickler/middleware/index.rb +30 -4
  26. data/lib/stickler/middleware/mirror.rb +8 -3
  27. data/lib/stickler/middleware/not_found.rb +4 -2
  28. data/lib/stickler/paths.rb +53 -0
  29. data/lib/stickler/repository/local.rb +12 -12
  30. data/lib/stickler/repository/mirror.rb +13 -6
  31. data/lib/stickler/repository/null.rb +1 -0
  32. data/lib/stickler/repository/remote.rb +10 -4
  33. data/lib/stickler/repository/rubygems_authenticator.rb +32 -0
  34. data/lib/stickler/server.rb +34 -0
  35. data/lib/stickler/server/public/css/blueprint/LICENSE +22 -0
  36. data/lib/stickler/server/public/css/blueprint/ie.css +35 -0
  37. data/lib/stickler/server/public/css/blueprint/screen.css +266 -0
  38. data/lib/stickler/server/public/css/style.css +19 -0
  39. data/lib/stickler/server/public/images/apple-touch-icon.png +0 -0
  40. data/lib/stickler/server/public/images/favicon.ico +0 -0
  41. data/lib/stickler/server/public/js/modernizr-1.5.min.js +28 -0
  42. data/lib/stickler/server/views/index.erb +35 -0
  43. data/lib/stickler/server/views/layout.erb +42 -0
  44. data/lib/stickler/spec_lite.rb +16 -6
  45. data/lib/stickler/version.rb +1 -1
  46. data/man/asciidoc.conf +25 -0
  47. data/man/stickler-passenger-config.asciidoc +74 -0
  48. data/man/stickler-server.asciidoc +87 -0
  49. data/man/stickler.asciidoc +148 -0
  50. data/spec/middleware/common_gem_server_helpers.rb +4 -2
  51. data/spec/middleware/index_spec.rb +3 -3
  52. data/spec/middleware/legacy_gem_server_behavior.rb +0 -2
  53. data/spec/middleware/local_spec.rb +3 -3
  54. data/spec/middleware/modern_gem_server_behavior.rb +2 -0
  55. data/spec/paths_spec.rb +13 -0
  56. data/spec/spec_lite_spec.rb +14 -0
  57. data/tasks/man.rake +19 -0
  58. metadata +183 -56
  59. data/HISTORY.rdoc +0 -12
  60. data/README.rdoc +0 -88
  61. data/lib/stickler/web.rb +0 -19
  62. data/stickler.gemspec +0 -60
  63. data/views/index.erb +0 -19
  64. data/views/layout.erb +0 -39
@@ -0,0 +1,14 @@
1
+ *~
2
+ pkg
3
+ log
4
+ doc
5
+ coverage
6
+ *.swp
7
+ *.swo
8
+ .*.swp
9
+ announcement.txt
10
+ spec/tmp
11
+ version.txt
12
+ *.pid
13
+ tmp
14
+ *.html
@@ -0,0 +1,17 @@
1
+ *~
2
+ pkg
3
+ log
4
+ doc
5
+ coverage
6
+ *.swp
7
+ *.swo
8
+ .*.swp
9
+ announcement.txt
10
+ spec/tmp
11
+ version.txt
12
+ *.pid
13
+ tmp
14
+ *.html
15
+ man/*.xml
16
+ man/*.1
17
+ *.gemspec
@@ -0,0 +1,20 @@
1
+ Stickler Changelog
2
+ ==================
3
+ Jeremy Hinegardner <jeremy@hinegardner.org>
4
+
5
+ Version 2.0.1
6
+ -------------
7
+ * Complete rewrite using Rack and Sinatra
8
+
9
+ Version 0.1.2
10
+ -------------
11
+ * fix compatibility with gems 1.3.1
12
+
13
+ Version 0.1.1
14
+ -------------
15
+ * remove unnecessary require 'progressbar'
16
+
17
+ Version 0.1.0
18
+ -------------
19
+ * http://copiousfreetime.org/articles/2008/10/09/managing-a-gem-repository-with-stickler.html[Managing a Gem Repository with Stickler]
20
+ * Initial public release
@@ -0,0 +1,126 @@
1
+ Stickler
2
+ ========
3
+ Jeremy Hinegardner <jeremy@hinegardner.org>
4
+
5
+
6
+ Overview
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
+ --------------------
23
+ gem install stickler
24
+ --------------------
25
+
26
+ Or downloaded from http://github.com/copiousfreetime/stickler/downloads
27
+
28
+
29
+ Usage
30
+ -----
31
+ Stickler is broken up into a few commandline programs.
32
+
33
+ .Command line programs
34
+ ******************************************************************
35
+ [horizontal]
36
+ link:man/stickler.html[stickler]::
37
+ Used to add gems to and remove gems from the
38
+ link:man/stickler-server.html[stickler-server]
39
+
40
+ link:man/stickler-server.html[stickler-server]::
41
+ The server process that holds the gems.
42
+
43
+ link:man/stickler-passenger-config.html[stickler-passenger-config]::
44
+ A helper process to generate Passenger configurations for
45
+ link:man/stickler-server.html[stickler-server]
46
+ ******************************************************************
47
+
48
+ The easiest way to get up and running with stickler is to run the
49
+ standalone server link:man/stickler-server.html[stickler-server] and
50
+ then use link:man/stickler.html[stickler] to interact with it.
51
+
52
+ .Start up a standalone stickler server
53
+ ------------------------------------------------------------------
54
+ % mkdir -p /tmp/stickler-test
55
+ % stickler-server start --daemonize /tmp/stickler-test
56
+ ------------------------------------------------------------------
57
+
58
+ .Set some sane defaults
59
+ ------------------------------------------------------------------
60
+ % stickler config --add --server http://localhost:6789 --upstream https://rubygems.org
61
+ server : http://localhost:6789
62
+ upstream : https://rubygems.org
63
+
64
+ % cat ~/.gem/stickler
65
+ ---
66
+ :server: http://localhost:6789
67
+ :upstream: https://rubygems.org
68
+ ------------------------------------------------------------------
69
+
70
+ .Take a few gems and push them to the server
71
+ ------------------------------------------------------------------
72
+ % ls -1
73
+ heel-2.0.0.gem
74
+ hitimes-1.1.1.gem
75
+ launchy-0.3.5.gem
76
+ stickler-2.0.0.gem
77
+
78
+ % stickler push *.gem
79
+ Pushing gem(s) to http://localhost:6789/ ...
80
+ /Users/jeremy/tmp/gems/heel-2.0.0.gem -> OK http://localhost:6789/gems/heel-2.0.0.gem
81
+ /Users/jeremy/tmp/gems/hitimes-1.1.1.gem -> OK http://localhost:6789/gems/hitimes-1.1.1.gem
82
+ /Users/jeremy/tmp/gems/launchy-0.3.5.gem -> OK http://localhost:6789/gems/launchy-0.3.5.gem
83
+ /Users/jeremy/tmp/gems/stickler-2.0.0.gem -> OK http://localhost:6789/gems/stickler-2.0.0.gem
84
+ ------------------------------------------------------------------
85
+
86
+ .Mirror a gem
87
+ ------------------------------------------------------------------
88
+ % stickler mirror --gem-version 1.4.3 logging
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
+ ------------------------------------------------------------------
91
+
92
+
93
+ See Also
94
+ --------
95
+ The man pages that ship with the gem. They may be viewed if you also install
96
+ the link:http://defunkt.github.com/gem-man/[gem-man] gem.
97
+
98
+ ---------------------------------
99
+ % gem install gem-man
100
+ % gem man stickler
101
+ View which manual?
102
+ 1. stickler-passenger-config(1)
103
+ 2. stickler-server(1)
104
+ 3. stickler(1)
105
+ >
106
+ ---------------------------------
107
+
108
+
109
+ Credits
110
+ -------
111
+ * http://rubyforge.org/projects/rubygems/[The Rubygems Team]
112
+
113
+
114
+ License
115
+ -------
116
+ 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
+
121
+
122
+ Appendix
123
+ --------
124
+ * http://github.com/copiousfreetime/stickler[Github Project]
125
+ * http://copiousfreetime.rubyforge.org/stickler/
126
+
data/Rakefile CHANGED
@@ -7,23 +7,42 @@ end
7
7
  task :default => 'spec:run'
8
8
  task 'gem:release' => 'spec:run'
9
9
 
10
+ $: << "lib"
11
+ require 'stickler/version'
12
+
10
13
  Bones {
11
14
  name 'stickler'
12
15
  authors 'Jeremy Hinegardner'
13
16
  email 'jeremy@hinegardner.org'
14
17
  url 'http://rubygems.org/gems/stickler'
18
+ version Stickler::VERSION
15
19
 
16
20
  ruby_opts %w[-W0 -rubygems]
17
- readme_file 'README.rdoc'
18
- ignore_file '.gitignore'
19
- history_file 'HISTORY.rdoc'
21
+ readme_file 'README.asciidoc'
22
+ ignore_file '.bnsignore'
23
+ history_file 'HISTORY.asciidoc'
20
24
  rubyforge.name 'copiousfreetime'
21
25
 
22
26
  spec.opts << "--color" << "--format specdoc"
23
27
 
28
+ summary 'Stickler is a tool to organize and maintain an internal gem repository.'
29
+ description <<_
30
+ Stickler is a tool to organize and maintain an internal gem repository.
31
+ Primarily, you would want to use Stickler if:
32
+
33
+ 1. You have proprietary gems that you want to have available via a gem server so
34
+ you may +gem install+ them.
35
+ 2. You would like to have a local mirror of third party gems from either
36
+ http://rubygems.org or some other gem server.
37
+ 3. You want both (1) and (2) in the same server.
38
+ _
39
+
40
+
24
41
  depend_on 'sinatra', '~> 1.0.0'
25
42
  depend_on 'addressable', '~> 2.1.2'
26
43
  depend_on 'resourceful', '~> 1.0.1'
44
+ depend_on 'trollop', '~> 1.16.2'
45
+ depend_on 'logging', '~> 1.4.3'
27
46
 
28
47
  depend_on 'bones' , '~> 3.4.6', :development => true
29
48
  depend_on 'rack-test' , '~> 0.5.4', :development => true
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'stickler'
4
+ require 'stickler/client'
5
+
6
+ SUB_COMMANDS = %w[ push yank mirror config ]
7
+ exec_name = File.basename( $0 )
8
+
9
+ #----------------------------------------------------------------------
10
+ # parse through the top level global options, this is intercept
11
+ # --version and --help
12
+ #----------------------------------------------------------------------
13
+ global_options = Trollop::options do
14
+ version "Stickler #{Stickler::VERSION}"
15
+ banner <<-_
16
+ Stickler server interaction
17
+
18
+ Usage: #{exec_name} #{SUB_COMMANDS.join("|")} [options]
19
+
20
+ Examples:
21
+ #{exec_name} push ./my_gem-1.0.0.gem --server http://stickler.example.com/
22
+ #{exec_name} yank my_gem --version 1.0.0 --server http://stickler.example.com/
23
+ #{exec_name} mirror third_party --version 0.4.2 --upstream http://rubygems.org/ --server http://stickler.example.com/
24
+ #{exec_name} mirror --help
25
+ #{exec_name} config --server http://stickler.example.com --upstream http://rubygems.org/
26
+
27
+ Options:
28
+ _
29
+
30
+ stop_on SUB_COMMANDS
31
+ end
32
+
33
+ #----------------------------------------------------------------------
34
+ # sub command processing
35
+ #----------------------------------------------------------------------
36
+ cmd = ARGV.shift
37
+ Trollop::die "unknown sub command #{cmd.inspect}" unless SUB_COMMANDS.include?( cmd )
38
+
39
+
40
+ case cmd
41
+ when "push"
42
+ ::Stickler::Client::Push.new( ARGV ).run
43
+ when "yank"
44
+ ::Stickler::Client::Yank.new( ARGV ).run
45
+ when "mirror"
46
+ ::Stickler::Client::Mirror.new( ARGV ).run
47
+ when "config"
48
+ ::Stickler::Client::Config.new( ARGV ).run
49
+ end
50
+
@@ -0,0 +1,112 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'fileutils'
4
+ require 'trollop'
5
+ require 'stickler'
6
+
7
+ SUB_COMMANDS = %w[ apache2 nginx ]
8
+ exec_name = File.basename( $0 )
9
+
10
+ #----------------------------------------------------------------------
11
+ # parse through the top level global options, this is intercept
12
+ # --version and --help
13
+ #----------------------------------------------------------------------
14
+ global_options = Trollop::options do
15
+ version "Stickler #{::Stickler::VERSION}"
16
+ banner <<-_
17
+ Stickler passenger config
18
+
19
+ Usage: #{exec_name} #{SUB_COMMANDS.join("|")} /path/to/stickler/root
20
+
21
+ Examples:
22
+ #{exec_name} apache2 /var/lib/stickler
23
+ #{exec_name} nginx /opt/stickler
24
+
25
+ Options:
26
+ _
27
+ stop_on SUB_COMMANDS
28
+ end
29
+
30
+ #----------------------------------------------------------------------
31
+ # sub command processing
32
+ #----------------------------------------------------------------------
33
+ cmd = ARGV.shift
34
+ Trollop::die "unknown sub command #{cmd.inspect}" unless SUB_COMMANDS.include?( cmd )
35
+
36
+ #----------------------------------------------------------------------
37
+ # validate the sole argument, the stickler root directory
38
+ #----------------------------------------------------------------------
39
+ stickler_root = ARGV.shift
40
+ Trollop::die "Stickler root argument required" unless stickler_root
41
+ stickler_root = File.expand_path( stickler_root )
42
+
43
+ puts "I assume you already have passenger installed and working."
44
+ puts ""
45
+
46
+ begin
47
+ # make the passenger require directory structure
48
+ %w[ public tmp ].each do |dir|
49
+ dir = File.join( stickler_root, dir )
50
+ FileUtils.mkdir_p dir
51
+ puts ">> Created directory #{dir}"
52
+ end
53
+
54
+ # and write the config.ru file
55
+ config_ru = File.join( stickler_root, "config.ru" )
56
+ File.open( config_ru, "w+" ) do |f|
57
+ f.puts <<-__config_ru__
58
+ #-----------------------------------------------------------------------
59
+ # config.ru for use with passenger deployed Stickler
60
+ #-----------------------------------------------------------------------
61
+ require 'rubygems' if RUBY_VERSION < "1.9"
62
+ require 'stickler'
63
+ run ::Stickler::Server.new( "#{stickler_root}" ).app
64
+
65
+ __config_ru__
66
+ end
67
+ puts ">> Wrote #{config_ru}"
68
+ puts
69
+ rescue => e
70
+ Trollop::die "Unable to create stickler directory structure: #{e}"
71
+ end
72
+
73
+ doc_root = File.join( stickler_root, "public" )
74
+ server_name = Socket.gethostname
75
+ case cmd
76
+ when "apache2"
77
+ puts "Place the follwing configuration options into an appropriate"
78
+ puts "Apache configuration file. Try `/etc/httpd/conf.d/stickler.conf'."
79
+
80
+ puts <<-__apache__
81
+
82
+ <VirtualHost *:80>
83
+ ServerName #{server_name}
84
+ # if you need some other hostname to add
85
+ #ServerAlias somethingelse.example.com
86
+
87
+ DocumentRoot #{doc_root}
88
+ <Directory #{doc_root}>
89
+ Allow from all
90
+ Options -MultiViews
91
+ </Directory>
92
+ </VirtualHost>
93
+
94
+ __apache__
95
+ when "nginx"
96
+ puts "Integrate the following configuration option into your Nginx configuration file."
97
+ puts <<-__nginx__
98
+
99
+ server {
100
+ listen 80;
101
+ server_name #{server_name};
102
+ root #{doc_root};
103
+ passenger_enabled on;
104
+ }
105
+
106
+ __nginx__
107
+ end
108
+
109
+ puts "Thank you for choosing Stickler."
110
+ puts
111
+
112
+
@@ -0,0 +1,109 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'stickler'
4
+ require 'trollop'
5
+
6
+ SUB_COMMANDS = %w[ start stop ]
7
+ exec_name = File.basename( $0 )
8
+
9
+ #----------------------------------------------------------------------
10
+ # parse through the top level global options, this is intercept
11
+ # --version and --help
12
+ #----------------------------------------------------------------------
13
+ global_options = Trollop::options do
14
+ version "Stickler #{Stickler::VERSION}"
15
+ banner <<-_
16
+ Stickler server control
17
+
18
+ Usage: #{exec_name} #{SUB_COMMANDS.join("|")} [options] /path/to/stickler/root
19
+
20
+ Examples:
21
+ #{exec_name} start /var/lib/stickler
22
+ #{exec_name} stop --pid /var/run/stickler
23
+
24
+ Options:
25
+ _
26
+ stop_on SUB_COMMANDS
27
+ end
28
+
29
+ #----------------------------------------------------------------------
30
+ # sub command processing
31
+ #----------------------------------------------------------------------
32
+ cmd = ARGV.shift
33
+ Trollop::die "unknown sub command #{cmd.inspect}" unless SUB_COMMANDS.include?( cmd )
34
+
35
+ #----------------------------------------------------------------------
36
+ # All for the display of a default
37
+ #----------------------------------------------------------------------
38
+ DEFAULT_HANDLERS = %w[ thin mongrel webrick ]
39
+ def rack_handler( handlers = DEFAULT_HANDLERS )
40
+ handlers = Array( handlers )
41
+ handlers.each do |name|
42
+ begin
43
+ klass = Rack::Handler.get( name.downcase )
44
+ return klass.name.gsub(/.*::/, '').downcase
45
+ rescue LoadError
46
+ rescue NameError
47
+ end
48
+ end
49
+ Trollop::die "No Server handler (#{handlers.join(",")}) found."
50
+ end
51
+
52
+ #----------------------------------------------------------------------
53
+ # option parsing of the sub command, all subcommands have the same
54
+ # options
55
+ #----------------------------------------------------------------------
56
+ rack_options = Trollop::options do
57
+ banner <<-_
58
+ Usage: #{exec_name} #{cmd} [options] /path/to/stickler/root
59
+
60
+ Options:
61
+ _
62
+ opt :daemonize, "Daemonize the server", :default => false
63
+ opt :host, "The host address to bind to", :type => :string, :default =>'0.0.0.0'
64
+ opt :pid, "Path to write a pid file to after daemonizing", :type => :int
65
+ opt :port, "The port to bind to", :type => :int, :default => 6789
66
+ opt :server, "The rack handler: thin, mongrel, webrick, etc", :type => String, :default => rack_handler
67
+ end
68
+
69
+ # case changes for rack handlers, don't ask my why. I'm keeping the
70
+ # options on the commandline all the same for consistency.
71
+ rack_options[:Host] = rack_options.delete(:host)
72
+ rack_options[:Port] = rack_options.delete(:port)
73
+
74
+ #----------------------------------------------------------------------
75
+ # validate the sole argument, the stickler root directory
76
+ #----------------------------------------------------------------------
77
+ stickler_root = ARGV.shift
78
+ Trollop::die "Stickler root argument required" unless stickler_root
79
+
80
+ stickler_root = File.expand_path( stickler_root )
81
+ Trollop::die "Stickler root directory '#{stickler_root}' must already exist" unless File.directory?( stickler_root )
82
+ Trollop::die "Stickler root directory '#{stickler_root}' must be writable" unless File.writable?( stickler_root )
83
+
84
+ rack_handler( rack_options[:server] )
85
+ rack_options[:pid] ||= File.join(stickler_root, "#{exec_name}.pid" )
86
+ rack_options[:app] = ::Stickler::Server.new( stickler_root ).app
87
+
88
+ case cmd
89
+ when "start"
90
+ # work around until
91
+ # http://github.com/rack/rack/commit/c73b474525bace3f059a130b15413abd4d917086
92
+ # makes it into a release.
93
+ r = ::Rack::Server.new(rack_options)
94
+ r.instance_variable_set('@app', rack_options[:app])
95
+ r.start
96
+ when "stop"
97
+ pid = Float( File.read( rack_options[:pid] ) ).to_i
98
+ Process.kill( "INT", pid )
99
+ 20.times do
100
+ begin
101
+ Process.kill( 0, pid )
102
+ sleep 0.1
103
+ rescue Errno::ESRCH
104
+ exit 0
105
+ end
106
+ end
107
+ Process.kill( "KILL", pid )
108
+ end
109
+ exit 0