stickler 2.0.0a → 2.0.1

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