gemstash 1.0.0.pre.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.
- checksums.yaml +7 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +139 -0
- data/Rakefile +35 -0
- data/bin/console +14 -0
- data/bin/gemstash +3 -0
- data/bin/setup +5 -0
- data/docs/config.md +136 -0
- data/docs/debug.md +24 -0
- data/docs/deploy.md +30 -0
- data/docs/mirror.md +30 -0
- data/docs/multiple_sources.md +68 -0
- data/docs/private_gems.md +140 -0
- data/docs/reference.md +308 -0
- data/exe/gemstash +3 -0
- data/gemstash.gemspec +47 -0
- data/gemstash.png +0 -0
- data/lib/gemstash.rb +26 -0
- data/lib/gemstash/authorization.rb +87 -0
- data/lib/gemstash/cache.rb +79 -0
- data/lib/gemstash/cli.rb +71 -0
- data/lib/gemstash/cli/authorize.rb +69 -0
- data/lib/gemstash/cli/base.rb +46 -0
- data/lib/gemstash/cli/setup.rb +173 -0
- data/lib/gemstash/cli/start.rb +52 -0
- data/lib/gemstash/cli/status.rb +21 -0
- data/lib/gemstash/cli/stop.rb +21 -0
- data/lib/gemstash/config.ru +13 -0
- data/lib/gemstash/configuration.rb +41 -0
- data/lib/gemstash/db.rb +15 -0
- data/lib/gemstash/db/authorization.rb +20 -0
- data/lib/gemstash/db/dependency.rb +50 -0
- data/lib/gemstash/db/rubygem.rb +14 -0
- data/lib/gemstash/db/version.rb +51 -0
- data/lib/gemstash/dependencies.rb +93 -0
- data/lib/gemstash/env.rb +150 -0
- data/lib/gemstash/gem_fetcher.rb +50 -0
- data/lib/gemstash/gem_pusher.rb +125 -0
- data/lib/gemstash/gem_source.rb +37 -0
- data/lib/gemstash/gem_source/dependency_caching.rb +40 -0
- data/lib/gemstash/gem_source/private_source.rb +139 -0
- data/lib/gemstash/gem_source/rack_middleware.rb +22 -0
- data/lib/gemstash/gem_source/upstream_source.rb +183 -0
- data/lib/gemstash/gem_unyanker.rb +61 -0
- data/lib/gemstash/gem_yanker.rb +61 -0
- data/lib/gemstash/http_client.rb +77 -0
- data/lib/gemstash/logging.rb +93 -0
- data/lib/gemstash/migrations/01_gem_dependencies.rb +41 -0
- data/lib/gemstash/migrations/02_authorizations.rb +12 -0
- data/lib/gemstash/puma.rb +6 -0
- data/lib/gemstash/rack_env_rewriter.rb +66 -0
- data/lib/gemstash/specs_builder.rb +93 -0
- data/lib/gemstash/storage.rb +207 -0
- data/lib/gemstash/upstream.rb +65 -0
- data/lib/gemstash/version.rb +4 -0
- data/lib/gemstash/web.rb +97 -0
- metadata +306 -0
@@ -0,0 +1,52 @@
|
|
1
|
+
require "gemstash"
|
2
|
+
require "puma/cli"
|
3
|
+
|
4
|
+
module Gemstash
|
5
|
+
class CLI
|
6
|
+
# This implements the command line start task to start the Gemstash server:
|
7
|
+
# $ gemstash start
|
8
|
+
class Start < Gemstash::CLI::Base
|
9
|
+
def run
|
10
|
+
prepare
|
11
|
+
setup_logging
|
12
|
+
store_daemonized
|
13
|
+
Puma::CLI.new(args, Gemstash::Logging::StreamLogger.puma_events).run
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def setup_logging
|
19
|
+
return unless daemonize?
|
20
|
+
Gemstash::Logging.setup_logger(gemstash_env.base_file("server.log"))
|
21
|
+
end
|
22
|
+
|
23
|
+
def store_daemonized
|
24
|
+
Gemstash::Env.daemonized = daemonize?
|
25
|
+
end
|
26
|
+
|
27
|
+
def daemonize?
|
28
|
+
@cli.options[:daemonize]
|
29
|
+
end
|
30
|
+
|
31
|
+
def puma_config
|
32
|
+
File.expand_path("../../puma.rb", __FILE__)
|
33
|
+
end
|
34
|
+
|
35
|
+
def args
|
36
|
+
config_args + pidfile_args + daemonize_args
|
37
|
+
end
|
38
|
+
|
39
|
+
def config_args
|
40
|
+
["--config", puma_config]
|
41
|
+
end
|
42
|
+
|
43
|
+
def daemonize_args
|
44
|
+
if daemonize?
|
45
|
+
["--daemon"]
|
46
|
+
else
|
47
|
+
[]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "gemstash"
|
2
|
+
require "puma/control_cli"
|
3
|
+
|
4
|
+
module Gemstash
|
5
|
+
class CLI
|
6
|
+
# This implements the command line status task to check the server status:
|
7
|
+
# $ gemstash status
|
8
|
+
class Status < Gemstash::CLI::Base
|
9
|
+
def run
|
10
|
+
prepare
|
11
|
+
Puma::ControlCLI.new(args).run
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def args
|
17
|
+
pidfile_args + %w(status)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "gemstash"
|
2
|
+
require "puma/control_cli"
|
3
|
+
|
4
|
+
module Gemstash
|
5
|
+
class CLI
|
6
|
+
# This implements the command line stop task to stop the Gemstash server:
|
7
|
+
# $ gemstash stop
|
8
|
+
class Stop < Gemstash::CLI::Base
|
9
|
+
def run
|
10
|
+
prepare
|
11
|
+
Puma::ControlCLI.new(args).run
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def args
|
17
|
+
pidfile_args + %w(stop)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require "gemstash"
|
2
|
+
require "puma/commonlogger"
|
3
|
+
|
4
|
+
use Rack::Deflater
|
5
|
+
use Gemstash::Logging::RackMiddleware
|
6
|
+
|
7
|
+
if Gemstash::Env.daemonized?
|
8
|
+
use Puma::CommonLogger, Gemstash::Logging::StreamLogger.for_stdout
|
9
|
+
end
|
10
|
+
|
11
|
+
use Gemstash::Env::RackMiddleware, Gemstash::Env.current
|
12
|
+
use Gemstash::GemSource::RackMiddleware
|
13
|
+
run Gemstash::Web.new(gemstash_env: Gemstash::Env.current)
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require "yaml"
|
2
|
+
|
3
|
+
module Gemstash
|
4
|
+
#:nodoc:
|
5
|
+
class Configuration
|
6
|
+
DEFAULTS = {
|
7
|
+
:cache_type => "memory",
|
8
|
+
:base_path => File.expand_path("~/.gemstash"),
|
9
|
+
:db_adapter => "sqlite3",
|
10
|
+
:bind => "tcp://0.0.0.0:9292",
|
11
|
+
:rubygems_url => "https://www.rubygems.org"
|
12
|
+
}.freeze
|
13
|
+
|
14
|
+
DEFAULT_FILE = File.expand_path("~/.gemstash/config.yml").freeze
|
15
|
+
|
16
|
+
def initialize(file: nil, config: nil)
|
17
|
+
if config
|
18
|
+
@config = DEFAULTS.merge(config).freeze
|
19
|
+
return
|
20
|
+
end
|
21
|
+
|
22
|
+
file ||= DEFAULT_FILE
|
23
|
+
|
24
|
+
if File.exist?(file)
|
25
|
+
@config = YAML.load_file(file)
|
26
|
+
@config = DEFAULTS.merge(@config)
|
27
|
+
@config.freeze
|
28
|
+
else
|
29
|
+
@config = DEFAULTS
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def default?(key)
|
34
|
+
@config[key] == DEFAULTS[key]
|
35
|
+
end
|
36
|
+
|
37
|
+
def [](key)
|
38
|
+
@config[key]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/gemstash/db.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require "gemstash"
|
2
|
+
|
3
|
+
module Gemstash
|
4
|
+
# Module containing the DB models.
|
5
|
+
module DB
|
6
|
+
raise "Gemstash::DB cannot be loaded until the Gemstash::Env is available" unless Gemstash::Env.available?
|
7
|
+
Sequel::Model.db = Gemstash::Env.current.db
|
8
|
+
Sequel::Model.raise_on_save_failure = true
|
9
|
+
Sequel::Model.plugin :timestamps, update_on_create: true
|
10
|
+
autoload :Authorization, "gemstash/db/authorization"
|
11
|
+
autoload :Dependency, "gemstash/db/dependency"
|
12
|
+
autoload :Rubygem, "gemstash/db/rubygem"
|
13
|
+
autoload :Version, "gemstash/db/version"
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "gemstash"
|
2
|
+
|
3
|
+
module Gemstash
|
4
|
+
module DB
|
5
|
+
# Sequel model for authorizations table.
|
6
|
+
class Authorization < Sequel::Model
|
7
|
+
def self.insert_or_update(auth_key, permissions)
|
8
|
+
db.transaction do
|
9
|
+
record = self[auth_key: auth_key]
|
10
|
+
|
11
|
+
if record
|
12
|
+
record.update(permissions: permissions)
|
13
|
+
else
|
14
|
+
create(auth_key: auth_key, permissions: permissions)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require "gemstash"
|
2
|
+
|
3
|
+
module Gemstash
|
4
|
+
module DB
|
5
|
+
# Sequel model for dependencies table.
|
6
|
+
class Dependency < Sequel::Model
|
7
|
+
def self.insert_by_spec(version_id, spec)
|
8
|
+
spec.runtime_dependencies.each do |dep|
|
9
|
+
requirements = dep.requirement.requirements
|
10
|
+
requirements = requirements.map {|r| "#{r.first} #{r.last}" }
|
11
|
+
requirements = requirements.join(", ")
|
12
|
+
create(version_id: version_id,
|
13
|
+
rubygem_name: dep.name,
|
14
|
+
requirements: requirements)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.fetch(gems)
|
19
|
+
results = db["
|
20
|
+
SELECT rubygem.name,
|
21
|
+
version.number, version.platform,
|
22
|
+
dependency.rubygem_name, dependency.requirements
|
23
|
+
FROM rubygems rubygem
|
24
|
+
JOIN versions version
|
25
|
+
ON version.rubygem_id = rubygem.id
|
26
|
+
LEFT JOIN dependencies dependency
|
27
|
+
ON dependency.version_id = version.id
|
28
|
+
WHERE rubygem.name IN ?
|
29
|
+
AND version.indexed = ?", gems.to_a, true].to_a
|
30
|
+
results.group_by {|r| r[:name] }.each do |gem, rows|
|
31
|
+
requirements = rows.group_by {|r| [r[:number], r[:platform]] }
|
32
|
+
|
33
|
+
value = requirements.map do |version, r|
|
34
|
+
deps = r.map {|x| [x[:rubygem_name], x[:requirements]] }
|
35
|
+
deps = [] if deps.size == 1 && deps.first.first.nil?
|
36
|
+
|
37
|
+
{
|
38
|
+
:name => gem,
|
39
|
+
:number => version.first,
|
40
|
+
:platform => version.last,
|
41
|
+
:dependencies => deps
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
yield(gem, value)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require "gemstash"
|
2
|
+
|
3
|
+
module Gemstash
|
4
|
+
module DB
|
5
|
+
# Sequel model for rubygems table.
|
6
|
+
class Rubygem < Sequel::Model
|
7
|
+
def self.find_or_insert(spec)
|
8
|
+
record = self[name: spec.name]
|
9
|
+
return record.id if record
|
10
|
+
new(name: spec.name).tap(&:save).id
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require "gemstash"
|
2
|
+
|
3
|
+
module Gemstash
|
4
|
+
module DB
|
5
|
+
# Sequel model for versions table.
|
6
|
+
class Version < Sequel::Model
|
7
|
+
many_to_one :rubygem
|
8
|
+
|
9
|
+
def deindex
|
10
|
+
update(indexed: false)
|
11
|
+
end
|
12
|
+
|
13
|
+
def reindex
|
14
|
+
update(indexed: true)
|
15
|
+
end
|
16
|
+
|
17
|
+
# This converts to the format used by /private/specs.4.8.gz
|
18
|
+
def to_spec
|
19
|
+
[rubygem.name, Gem::Version.new(number), platform]
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.for_spec_collection(prerelease: false)
|
23
|
+
where(indexed: true, prerelease: prerelease).association_join(:rubygem)
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.find_by_spec(gem_id, spec)
|
27
|
+
self[rubygem_id: gem_id,
|
28
|
+
number: spec.version.to_s,
|
29
|
+
platform: spec.platform.to_s]
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.find_by_full_name(full_name)
|
33
|
+
result = self[full_name: full_name]
|
34
|
+
return result if result
|
35
|
+
# Try again with the default platform, in case it is implied
|
36
|
+
self[full_name: "#{full_name}-ruby"]
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.insert_by_spec(gem_id, spec)
|
40
|
+
gem_name = Gemstash::DB::Rubygem[gem_id].name
|
41
|
+
new(rubygem_id: gem_id,
|
42
|
+
number: spec.version.to_s,
|
43
|
+
platform: spec.platform.to_s,
|
44
|
+
full_name: "#{gem_name}-#{spec.version}-#{spec.platform}",
|
45
|
+
storage_id: spec.full_name,
|
46
|
+
indexed: true,
|
47
|
+
prerelease: spec.version.prerelease?).tap(&:save).id
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require "cgi"
|
2
|
+
require "set"
|
3
|
+
|
4
|
+
module Gemstash
|
5
|
+
#:nodoc:
|
6
|
+
class Dependencies
|
7
|
+
def self.for_private
|
8
|
+
new(scope: "private", db_model: Gemstash::DB::Dependency)
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.for_upstream(upstream, http_client)
|
12
|
+
new(scope: "upstream/#{upstream}", http_client: http_client)
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(scope: nil, http_client: nil, db_model: nil)
|
16
|
+
@scope = scope
|
17
|
+
@http_client = http_client
|
18
|
+
@db_model = db_model
|
19
|
+
end
|
20
|
+
|
21
|
+
def fetch(gems)
|
22
|
+
Fetcher.new(gems, @scope, @http_client, @db_model).fetch
|
23
|
+
end
|
24
|
+
|
25
|
+
#:nodoc:
|
26
|
+
class Fetcher
|
27
|
+
include Gemstash::Env::Helper
|
28
|
+
include Gemstash::Logging
|
29
|
+
|
30
|
+
def initialize(gems, scope, http_client, db_model)
|
31
|
+
@gems = Set.new(gems)
|
32
|
+
@scope = scope
|
33
|
+
@http_client = http_client
|
34
|
+
@db_model = db_model
|
35
|
+
@dependencies = []
|
36
|
+
end
|
37
|
+
|
38
|
+
def fetch
|
39
|
+
fetch_from_cache
|
40
|
+
fetch_from_database
|
41
|
+
fetch_from_web
|
42
|
+
cache_missing
|
43
|
+
@dependencies
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def done?
|
49
|
+
@gems.empty?
|
50
|
+
end
|
51
|
+
|
52
|
+
def fetch_from_cache
|
53
|
+
gemstash_env.cache.dependencies(@scope, @gems) do |gem, value|
|
54
|
+
@gems.delete(gem)
|
55
|
+
@dependencies += value
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def fetch_from_database
|
60
|
+
return if done?
|
61
|
+
return unless @db_model
|
62
|
+
log.info "Querying dependencies: #{@gems.to_a.join(", ")}"
|
63
|
+
|
64
|
+
@db_model.fetch(@gems) do |gem, value|
|
65
|
+
@gems.delete(gem)
|
66
|
+
gemstash_env.cache.set_dependency(@scope, gem, value)
|
67
|
+
@dependencies += value
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def fetch_from_web
|
72
|
+
return if done?
|
73
|
+
return unless @http_client
|
74
|
+
log.info "Fetching dependencies: #{@gems.to_a.join(", ")}"
|
75
|
+
gems_param = @gems.map {|gem| CGI.escape(gem) }.join(",")
|
76
|
+
fetched = @http_client.get("api/v1/dependencies?gems=#{gems_param}")
|
77
|
+
fetched = Marshal.load(fetched).group_by {|r| r[:name] }
|
78
|
+
|
79
|
+
fetched.each do |gem, result|
|
80
|
+
@gems.delete(gem)
|
81
|
+
gemstash_env.cache.set_dependency(@scope, gem, result)
|
82
|
+
@dependencies += result
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def cache_missing
|
87
|
+
@gems.each do |gem|
|
88
|
+
gemstash_env.cache.set_dependency(@scope, gem, [])
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
data/lib/gemstash/env.rb
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
require "gemstash"
|
2
|
+
require "dalli"
|
3
|
+
require "fileutils"
|
4
|
+
require "sequel"
|
5
|
+
require "uri"
|
6
|
+
|
7
|
+
module Gemstash
|
8
|
+
# Storage for application-wide variables and configuration.
|
9
|
+
class Env
|
10
|
+
# The Gemstash::Env must be set before being retreived via
|
11
|
+
# Gemstash::Env.current. This error is thrown when that is not honored.
|
12
|
+
class EnvNotSetError < StandardError
|
13
|
+
end
|
14
|
+
|
15
|
+
# Little module to provide easy access to the current Gemstash::Env.
|
16
|
+
module Helper
|
17
|
+
private
|
18
|
+
|
19
|
+
def gemstash_env
|
20
|
+
Gemstash::Env.current
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Rack middleware to set the Gemstash::Env for the app.
|
25
|
+
class RackMiddleware
|
26
|
+
def initialize(app, gemstash_env)
|
27
|
+
@app = app
|
28
|
+
@gemstash_env = gemstash_env
|
29
|
+
end
|
30
|
+
|
31
|
+
def call(env)
|
32
|
+
env["gemstash.env"] = @gemstash_env
|
33
|
+
@app.call(env)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def initialize(config = nil, cache: nil, db: nil)
|
38
|
+
@config = config
|
39
|
+
@cache = cache
|
40
|
+
@db = db
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.available?
|
44
|
+
!Thread.current[:gemstash_env].nil?
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.current
|
48
|
+
raise EnvNotSetError unless Thread.current[:gemstash_env]
|
49
|
+
Thread.current[:gemstash_env]
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.current=(value)
|
53
|
+
Thread.current[:gemstash_env] = value
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.daemonized?
|
57
|
+
if @daemonized.nil?
|
58
|
+
raise "Daemonized hasn't been set yet!"
|
59
|
+
else
|
60
|
+
@daemonized
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.daemonized=(value)
|
65
|
+
value = false if value.nil?
|
66
|
+
@daemonized = value
|
67
|
+
end
|
68
|
+
|
69
|
+
def config
|
70
|
+
@config ||= Gemstash::Configuration.new
|
71
|
+
end
|
72
|
+
|
73
|
+
def config=(value)
|
74
|
+
reset
|
75
|
+
@config = value
|
76
|
+
end
|
77
|
+
|
78
|
+
def reset
|
79
|
+
@config = nil
|
80
|
+
@cache = nil
|
81
|
+
@cache_client = nil
|
82
|
+
@db = nil
|
83
|
+
end
|
84
|
+
|
85
|
+
def base_path
|
86
|
+
dir = config[:base_path]
|
87
|
+
|
88
|
+
if config.default?(:base_path)
|
89
|
+
FileUtils.mkpath(dir) unless Dir.exist?(dir)
|
90
|
+
else
|
91
|
+
raise "Base path '#{dir}' is not writable" unless File.writable?(dir)
|
92
|
+
end
|
93
|
+
|
94
|
+
dir
|
95
|
+
end
|
96
|
+
|
97
|
+
def base_file(path)
|
98
|
+
File.join(base_path, path)
|
99
|
+
end
|
100
|
+
|
101
|
+
def rackup
|
102
|
+
File.expand_path("../config.ru", __FILE__)
|
103
|
+
end
|
104
|
+
|
105
|
+
def db
|
106
|
+
@db ||= begin
|
107
|
+
case config[:db_adapter]
|
108
|
+
when "sqlite3"
|
109
|
+
db_path = base_file("gemstash.db")
|
110
|
+
|
111
|
+
if RUBY_PLATFORM == "java"
|
112
|
+
db = Sequel.connect("jdbc:sqlite:#{db_path}", max_connections: 1)
|
113
|
+
else
|
114
|
+
db = Sequel.connect("sqlite://#{URI.escape(db_path)}", max_connections: 1)
|
115
|
+
end
|
116
|
+
when "postgres"
|
117
|
+
db = Sequel.connect(config[:db_url])
|
118
|
+
else
|
119
|
+
raise "Unsupported DB adapter: '#{config[:db_adapter]}'"
|
120
|
+
end
|
121
|
+
|
122
|
+
Gemstash::Env.migrate(db)
|
123
|
+
db
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def self.migrate(db)
|
128
|
+
Sequel.extension :migration
|
129
|
+
migrations_dir = File.expand_path("../migrations", __FILE__)
|
130
|
+
Sequel::Migrator.run(db, migrations_dir, :use_transactions => true)
|
131
|
+
end
|
132
|
+
|
133
|
+
def cache
|
134
|
+
@cache ||= Gemstash::Cache.new(cache_client)
|
135
|
+
end
|
136
|
+
|
137
|
+
def cache_client
|
138
|
+
@cache_client ||= begin
|
139
|
+
case config[:cache_type]
|
140
|
+
when "memory"
|
141
|
+
Gemstash::LruReduxClient.new
|
142
|
+
when "memcached"
|
143
|
+
Dalli::Client.new(config[:memcached_servers])
|
144
|
+
else
|
145
|
+
raise "Invalid cache client: '#{config[:cache_type]}'"
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|