geminabox-jgraichen 0.12.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 00f38a41be22997b62d4341e5d68fc1ae280d437
4
+ data.tar.gz: 032882e5bbe65a04f23bf6451dce7d0a082cfbce
5
+ SHA512:
6
+ metadata.gz: 43ef7e700a853dadcc6b2aac1d47b3edbf8af7db278995c2ebf42dabee01c55e6188db8b8165141215379e5c7ba01b37382586fea88eafe2a78ad7272dcbec3d
7
+ data.tar.gz: 4c3b246dd5984e805f2dd21e8f798d049e046072c103c6e02377aca9b79fb8af0456f5755f0165ff8781b85f2b47310f5be53676fa6f5d4dae26904f3ad651d7
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2012 Tom Lea, Jack Foy, and Rob Nichols
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.markdown ADDED
@@ -0,0 +1,109 @@
1
+ # Gem in a Box – Really simple rubygem hosting
2
+ [![Build Status](https://secure.travis-ci.org/geminabox/geminabox.png)](http://travis-ci.org/geminabox/geminabox)
3
+ [![Gem Version](https://badge.fury.io/rb/geminabox.png)](http://badge.fury.io/rb/geminabox)
4
+
5
+ Geminabox lets you host your own gems, and push new gems to it just like with rubygems.org.
6
+ The bundler dependencies API is supported out of the box.
7
+ Authentication is left up to either the web server, or the Rack stack.
8
+ For basic auth, try [Rack::Auth](http://rack.rubyforge.org/doc/Rack/Auth/Basic.html).
9
+
10
+ ![screen shot](http://pics.tomlea.co.uk/bbbba6/geminabox.png)
11
+
12
+ ## System Requirements
13
+
14
+ Tested on Mac OS X 10.8.2
15
+ Ruby 1.9.3-392
16
+
17
+ Tests fail on Ruby 2.0.0-p0
18
+
19
+ ## Server Setup
20
+
21
+ gem install geminabox
22
+
23
+ Create a config.ru as follows:
24
+
25
+ require "rubygems"
26
+ require "geminabox"
27
+
28
+ Geminabox.data = "/var/geminabox-data" # ... or wherever
29
+ run Geminabox::Server
30
+
31
+ Start your gem server with 'rackup' to run WEBrick or hook up the config.ru as you normally would ([passenger][passenger], [thin][thin], [unicorn][unicorn], whatever floats your boat).
32
+
33
+ ## Legacy RubyGems index
34
+
35
+ RubyGems supports generating indexes for the so called legacy versions (< 1.2), and since it is very rare to use such versions nowadays, it can be disabled, thus improving indexing times for large repositories. If it's safe for your application, you can disable support for these legacy versions by adding the following configuration to your config.ru file:
36
+
37
+ Geminabox.build_legacy = false
38
+
39
+ ## RubyGems Proxy
40
+
41
+ Geminabox can be configured to pull gems, it does not currently have, from rubygems.org. To enable this mode you can either:
42
+
43
+ Set RUBYGEM_PROXY to true in the environment:
44
+
45
+ RUBYGEMS_PROXY=true rackup
46
+
47
+ Or in config.ru (before the run command), set:
48
+
49
+ Geminabox.rubygems_proxy = true
50
+
51
+ ## Client Usage
52
+
53
+ Since version 0.10, Geminabox supports the standard gemcutter push API:
54
+
55
+ gem push pkg/my-awesome-gem-1.0.gem --host HOST
56
+
57
+ You can also use the gem plugin:
58
+
59
+ gem install geminabox
60
+
61
+ gem inabox pkg/my-awesome-gem-1.0.gem
62
+
63
+ Configure Gem in a box (interactive prompt to specify where to upload to):
64
+
65
+ gem inabox -c
66
+
67
+ Change the host to upload to:
68
+
69
+ gem inabox -g HOST
70
+
71
+ Simples!
72
+
73
+ ## Command Line Help
74
+
75
+ Usage: gem inabox GEM [options]
76
+
77
+ Options:
78
+ -c, --configure Configure GemInABox
79
+ -g, --host HOST Host to upload to.
80
+ -o, --overwrite Overwrite Gem.
81
+
82
+
83
+ Common Options:
84
+ -h, --help Get help on this command
85
+ -V, --[no-]verbose Set the verbose level of output
86
+ -q, --quiet Silence commands
87
+ --config-file FILE Use this config file instead of default
88
+ --backtrace Show stack backtrace on errors
89
+ --debug Turn on Ruby debugging
90
+
91
+
92
+ Arguments:
93
+ GEM built gem to push up
94
+
95
+ Summary:
96
+ Push a gem up to your GemInABox
97
+
98
+ Description:
99
+ Push a gem up to your GemInABox
100
+
101
+ ## Licence
102
+
103
+ Fork it, mod it, choose it, use it, make it better. All under the MIT License.
104
+
105
+ [WTFBPPL]: http://tomlea.co.uk/WTFBPPL.txt
106
+ [sinatra]: http://www.sinatrarb.com/
107
+ [passenger]: http://www.modrails.com/
108
+ [thin]: http://code.macournoyer.com/thin/
109
+ [unicorn]: http://unicorn.bogomips.org/
data/lib/geminabox.rb ADDED
@@ -0,0 +1,76 @@
1
+ require 'rubygems'
2
+ require 'digest/md5'
3
+ require 'builder'
4
+ require 'sinatra/base'
5
+ require 'rubygems/user_interaction'
6
+ require 'rubygems/indexer'
7
+ require 'rubygems/package'
8
+ require 'rss/atom'
9
+ require 'tempfile'
10
+ require 'json'
11
+
12
+ module Geminabox
13
+
14
+ require_relative 'geminabox/version'
15
+ require_relative 'geminabox/proxy'
16
+
17
+ def self.geminabox_path(file)
18
+ File.join File.dirname(__FILE__), 'geminabox', file
19
+ end
20
+
21
+ autoload :Hostess, geminabox_path('hostess')
22
+ autoload :GemStore, geminabox_path('gem_store')
23
+ autoload :GemStoreError, geminabox_path('gem_store_error')
24
+ autoload :RubygemsDependency, geminabox_path('rubygems_dependency')
25
+ autoload :GemListMerge, geminabox_path('gem_list_merge')
26
+ autoload :GemVersion, geminabox_path('gem_version')
27
+ autoload :GemVersionCollection, geminabox_path('gem_version_collection')
28
+ autoload :Server, geminabox_path('server')
29
+ autoload :DiskCache, geminabox_path('disk_cache')
30
+ autoload :IncomingGem, geminabox_path('incoming_gem')
31
+
32
+ class << self
33
+
34
+ attr_accessor(
35
+ :data,
36
+ :public_folder,
37
+ :build_legacy,
38
+ :incremental_updates,
39
+ :views,
40
+ :allow_replace,
41
+ :gem_permissions,
42
+ :allow_delete,
43
+ :rubygems_proxy
44
+ )
45
+
46
+ def set_defaults(defaults)
47
+ defaults.each do |method, default|
48
+ variable = "@#{method}"
49
+ instance_variable_set(variable, default) unless instance_variable_get(variable)
50
+ end
51
+ end
52
+
53
+ def settings
54
+ Server.settings
55
+ end
56
+
57
+ def call(env)
58
+ Server.call env
59
+ end
60
+ end
61
+
62
+ set_defaults(
63
+
64
+ data: File.join(File.dirname(__FILE__), *%w[.. data]),
65
+ public_folder: File.join(File.dirname(__FILE__), *%w[.. public]),
66
+ build_legacy: false,
67
+ incremental_updates: true,
68
+ views: File.join(File.dirname(__FILE__), *%w[.. views]),
69
+ allow_replace: false,
70
+ gem_permissions: 0644,
71
+ rubygems_proxy: (ENV['RUBYGEMS_PROXY'] == 'true'),
72
+ allow_delete: true
73
+
74
+ )
75
+
76
+ end
@@ -0,0 +1,73 @@
1
+ require "fileutils"
2
+ module Geminabox
3
+ class Geminabox::DiskCache
4
+ attr_reader :root_path
5
+
6
+ def initialize(root_path)
7
+ @root_path = root_path
8
+ ensure_dir_exists!
9
+ end
10
+
11
+ def flush_key(key)
12
+ path = path(key_hash(key))
13
+ FileUtils.rm_f(path)
14
+ end
15
+
16
+ def flush
17
+ FileUtils.rm_rf(root_path)
18
+ ensure_dir_exists!
19
+ end
20
+
21
+ def cache(key)
22
+ key_hash = key_hash(key)
23
+ read(key_hash) || write(key_hash, yield)
24
+ end
25
+
26
+ def marshal_cache(key)
27
+ key_hash = key_hash(key)
28
+ marshal_read(key_hash) || marshal_write(key_hash, yield)
29
+ end
30
+
31
+ protected
32
+
33
+ def ensure_dir_exists!
34
+ FileUtils.mkdir_p(root_path)
35
+ end
36
+
37
+ def key_hash(key)
38
+ Digest::MD5.hexdigest(key)
39
+ end
40
+
41
+ def path(key_hash)
42
+ File.join(root_path, key_hash)
43
+ end
44
+
45
+ def read(key_hash)
46
+ read_int(key_hash) { |path| File.read(path) }
47
+ end
48
+
49
+ def marshal_read(key_hash)
50
+ read_int(key_hash) { |path| Marshal.load(File.open(path)) }
51
+ end
52
+
53
+ def read_int(key_hash)
54
+ path = path(key_hash)
55
+ yield(path) if File.exists?(path)
56
+ end
57
+
58
+ def write(key_hash, value)
59
+ write_int(key_hash) { |f| f << value }
60
+ value
61
+ end
62
+
63
+ def marshal_write(key_hash, value)
64
+ write_int(key_hash) { |f| Marshal.dump(value, f) }
65
+ value
66
+ end
67
+
68
+ def write_int(key_hash)
69
+ File.open(path(key_hash), 'wb') { |f| yield(f) }
70
+ end
71
+
72
+ end
73
+ end
@@ -0,0 +1,51 @@
1
+ module Geminabox
2
+ class GemListMerge
3
+ attr_accessor :list
4
+
5
+ def self.from(*lists)
6
+ lists.map{|list| new(list)}.inject(:merge)
7
+ end
8
+
9
+ def initialize(list)
10
+ @list = list
11
+ end
12
+
13
+ def merge(other)
14
+ combine_hashes(other).values.flatten.sort do |x, y|
15
+ x.values[ignore_dependencies] <=> y.values[ignore_dependencies]
16
+ end
17
+ end
18
+
19
+ def hash
20
+ list.each do |item|
21
+ ensure_symbols_as_keys(item)
22
+ name = item[:name].to_sym
23
+ collection[name] ||= []
24
+ collection[name] << item unless collection[name].include?(item)
25
+ end
26
+ collection
27
+ end
28
+
29
+ def collection
30
+ @collection ||= {}
31
+ end
32
+
33
+ def combine_hashes(other)
34
+ hash.merge(other.hash) do |key, value, other_value|
35
+ (value + other_value).uniq{|v| v.values[ignore_dependencies]}
36
+ end
37
+ end
38
+
39
+ def ignore_dependencies
40
+ 0..-2
41
+ end
42
+
43
+ def ensure_symbols_as_keys(item)
44
+ item.keys.each do |key|
45
+ next if key.kind_of? Symbol
46
+ item[key.to_sym] = item.delete(key)
47
+ end
48
+ end
49
+
50
+ end
51
+ end
@@ -0,0 +1,99 @@
1
+ module Geminabox
2
+
3
+ class GemStore
4
+ attr_accessor :gem, :overwrite
5
+
6
+ def self.create(gem, overwrite = false)
7
+ gem_store = new(gem, overwrite)
8
+ gem_store.save
9
+ end
10
+
11
+ def initialize(gem, overwrite = false)
12
+ @gem = gem
13
+ @overwrite = overwrite && overwrite == 'true'
14
+ end
15
+
16
+ def save
17
+ ensure_gem_valid
18
+ prepare_data_folders
19
+ check_replacement_status
20
+ write_and_index
21
+ end
22
+
23
+ def prepare_data_folders
24
+ ensure_existing_data_folder_compatible
25
+ begin
26
+ FileUtils.mkdir_p(File.join(Geminabox.data, "gems"))
27
+ rescue
28
+ raise GemStoreError.new(
29
+ 500,
30
+ "Could not create #{File.expand_path(Geminabox.data)}."
31
+ )
32
+ end
33
+ end
34
+
35
+ def check_replacement_status
36
+ if !overwrite and Geminabox::Server.disallow_replace? and File.exist?(gem.dest_filename)
37
+ if existing_file_digest != gem.hexdigest
38
+ raise GemStoreError.new(409, "Updating an existing gem is not permitted.\nYou should either delete the existing version, or change your version number.")
39
+ else
40
+ raise GemStoreError.new(200, "Ignoring upload, you uploaded the same thing previously.\nPlease use -o to ovewrite.")
41
+ end
42
+ end
43
+ end
44
+
45
+ def ensure_gem_valid
46
+ raise GemStoreError.new(400, "Cannot process gem") unless gem.valid?
47
+ end
48
+
49
+ private
50
+ def ensure_existing_data_folder_compatible
51
+ if File.exists? Geminabox.data
52
+ ensure_data_folder_is_directory
53
+ ensure_data_folder_is_writable
54
+ end
55
+ end
56
+
57
+ def ensure_data_folder_is_directory
58
+ raise GemStoreError.new(
59
+ 500,
60
+ "Please ensure #{File.expand_path(Geminabox.data)} is a directory."
61
+ ) unless File.directory? Geminabox.data
62
+ end
63
+
64
+ def ensure_data_folder_is_writable
65
+ raise GemStoreError.new(
66
+ 500,
67
+ "Please ensure #{File.expand_path(Geminabox.data)} is writable by the geminabox web server."
68
+ ) unless File.writable? Geminabox.data
69
+ end
70
+
71
+ def existing_file_digest
72
+ Digest::SHA1.file(gem.dest_filename).hexdigest
73
+ end
74
+
75
+ def write_and_index
76
+ tmpfile = gem.gem_data
77
+ atomic_write(gem.dest_filename) do |f|
78
+ while blk = tmpfile.read(65536)
79
+ f << blk
80
+ end
81
+ end
82
+ Geminabox::Server.reindex
83
+ end
84
+
85
+ # based on http://as.rubyonrails.org/classes/File.html
86
+ def atomic_write(file_name)
87
+ temp_dir = File.join(Geminabox.data, "_temp")
88
+ FileUtils.mkdir_p(temp_dir)
89
+ temp_file = Tempfile.new("." + File.basename(file_name), temp_dir)
90
+ temp_file.binmode
91
+ yield temp_file
92
+ temp_file.close
93
+ File.rename(temp_file.path, file_name)
94
+ File.chmod(Geminabox::Server.gem_permissions, file_name)
95
+ end
96
+
97
+ end
98
+
99
+ end
@@ -0,0 +1,13 @@
1
+ require 'nesty'
2
+ module Geminabox
3
+ class GemStoreError < StandardError
4
+ attr_reader :code, :reason
5
+
6
+ include Nesty::NestedError
7
+
8
+ def initialize(code, reason)
9
+ @code = code.to_s
10
+ @reason = reason
11
+ end
12
+ end
13
+ end