gemstash 2.0.0 → 2.1.0

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 (75) hide show
  1. checksums.yaml +4 -4
  2. data/exe/gemstash +3 -0
  3. data/lib/gemstash.rb +2 -0
  4. data/lib/gemstash/api_key_authorization.rb +3 -0
  5. data/lib/gemstash/authorization.rb +7 -3
  6. data/lib/gemstash/cache.rb +5 -2
  7. data/lib/gemstash/cli.rb +2 -0
  8. data/lib/gemstash/cli/authorize.rb +3 -3
  9. data/lib/gemstash/cli/base.rb +4 -1
  10. data/lib/gemstash/cli/setup.rb +8 -1
  11. data/lib/gemstash/cli/start.rb +4 -1
  12. data/lib/gemstash/cli/status.rb +2 -0
  13. data/lib/gemstash/cli/stop.rb +2 -0
  14. data/lib/gemstash/config.ru +3 -3
  15. data/lib/gemstash/configuration.rb +7 -1
  16. data/lib/gemstash/db.rb +3 -0
  17. data/lib/gemstash/db/authorization.rb +2 -0
  18. data/lib/gemstash/db/cached_rubygem.rb +3 -0
  19. data/lib/gemstash/db/dependency.rb +2 -0
  20. data/lib/gemstash/db/rubygem.rb +3 -0
  21. data/lib/gemstash/db/upstream.rb +3 -0
  22. data/lib/gemstash/db/version.rb +3 -0
  23. data/lib/gemstash/dependencies.rb +4 -0
  24. data/lib/gemstash/env.rb +22 -4
  25. data/lib/gemstash/gem_fetcher.rb +2 -0
  26. data/lib/gemstash/gem_pusher.rb +5 -3
  27. data/lib/gemstash/gem_source.rb +2 -0
  28. data/lib/gemstash/gem_source/dependency_caching.rb +4 -4
  29. data/lib/gemstash/gem_source/private_source.rb +3 -0
  30. data/lib/gemstash/gem_source/rack_middleware.rb +3 -0
  31. data/lib/gemstash/gem_source/upstream_source.rb +9 -3
  32. data/lib/gemstash/gem_yanker.rb +4 -0
  33. data/lib/gemstash/health.rb +2 -0
  34. data/lib/gemstash/http_client.rb +4 -1
  35. data/lib/gemstash/logging.rb +2 -0
  36. data/lib/gemstash/man/gemstash-authorize.1 +51 -0
  37. data/lib/gemstash/man/gemstash-authorize.1.txt +33 -53
  38. data/lib/gemstash/man/gemstash-configuration.5 +229 -0
  39. data/lib/gemstash/man/gemstash-configuration.5.txt +150 -6
  40. data/lib/gemstash/man/gemstash-customize.7 +301 -0
  41. data/lib/gemstash/man/gemstash-customize.7.txt +183 -62
  42. data/lib/gemstash/man/gemstash-debugging.7 +34 -0
  43. data/lib/gemstash/man/gemstash-debugging.7.txt +17 -54
  44. data/lib/gemstash/man/gemstash-deploy.7 +72 -0
  45. data/lib/gemstash/man/gemstash-deploy.7.txt +44 -51
  46. data/lib/gemstash/man/gemstash-mirror.7 +40 -0
  47. data/lib/gemstash/man/gemstash-mirror.7.txt +20 -53
  48. data/lib/gemstash/man/gemstash-multiple-sources.7 +89 -0
  49. data/lib/gemstash/man/gemstash-multiple-sources.7.txt +53 -48
  50. data/lib/gemstash/man/gemstash-private-gems.7 +227 -0
  51. data/lib/gemstash/man/gemstash-private-gems.7.txt +108 -18
  52. data/lib/gemstash/man/gemstash-readme.7 +233 -0
  53. data/lib/gemstash/man/gemstash-readme.7.txt +126 -10
  54. data/lib/gemstash/man/gemstash-setup.1 +43 -0
  55. data/lib/gemstash/man/gemstash-setup.1.txt +28 -54
  56. data/lib/gemstash/man/gemstash-start.1 +26 -0
  57. data/lib/gemstash/man/gemstash-start.1.txt +16 -56
  58. data/lib/gemstash/man/gemstash-status.1 +20 -0
  59. data/lib/gemstash/man/gemstash-status.1.txt +13 -57
  60. data/lib/gemstash/man/gemstash-stop.1 +20 -0
  61. data/lib/gemstash/man/gemstash-stop.1.txt +13 -57
  62. data/lib/gemstash/man/gemstash-version.1 +22 -0
  63. data/lib/gemstash/man/gemstash-version.1.txt +12 -57
  64. data/lib/gemstash/migrations/01_gem_dependencies.rb +2 -0
  65. data/lib/gemstash/migrations/02_authorizations.rb +2 -0
  66. data/lib/gemstash/migrations/03_cached_gems.rb +2 -0
  67. data/lib/gemstash/migrations/04_health_tests.rb +2 -0
  68. data/lib/gemstash/puma.rb +2 -0
  69. data/lib/gemstash/rack_env_rewriter.rb +11 -2
  70. data/lib/gemstash/specs_builder.rb +5 -1
  71. data/lib/gemstash/storage.rb +12 -3
  72. data/lib/gemstash/upstream.rb +2 -0
  73. data/lib/gemstash/version.rb +3 -1
  74. data/lib/gemstash/web.rb +2 -0
  75. metadata +69 -22
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9bab8ddab9daaae6c24fd9c878f367ca1206d275b1d42baacaa990cc5048d62d
4
- data.tar.gz: '079b116b2cfb74f712a8300f46aa93d75867fbd4e8b74180595bda2ec3ee6c5b'
3
+ metadata.gz: aaf9ebeef139205ff90579ee16b1cd307bc3669164704163bb9503b656532eb2
4
+ data.tar.gz: 7188adfcdde048e812747afc26e915efae2d502c305da21e6f692132d01a8028
5
5
  SHA512:
6
- metadata.gz: b9d4634083a17c6cca10725523aec385964b42755ade1c43334c7436acf275c3b66c265ed256b2006076b10ae643cd17862bd35be5f622239d9eacd0474180cd
7
- data.tar.gz: 88fd7c8d2822fab3a50794453c1d7e1ea1e0014b6b80dbe3f15c05af9b4c078a54c16232c988cb3dbc0e3eb877e05177525daa75e8a9ee736e0e2e47ffc4986f
6
+ metadata.gz: 4a4326563fe277ae496e087a5e941d9f829cde351c1c1d92021061e4796cb612f081a73acece2e250a0220a660b631017a4372b401afbb30b4cfe4b95ac6618e
7
+ data.tar.gz: ff3b604ca9d7280b2ca0b72fa98c605e1b998eb3fcf9aa5801b6854c970c3d9c8f5d5c33732eb619bd8106dc86c27ee2ac6823cc2b14f2a2f8a7d44eb1383cae
@@ -1,3 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
+
3
+ # frozen_string_literal: true
4
+
2
5
  require "gemstash/cli"
3
6
  Gemstash::CLI.start
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  #:nodoc:
2
4
  module Gemstash
3
5
  autoload :ApiKeyAuthorization, "gemstash/api_key_authorization"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "gemstash"
2
4
 
3
5
  module Gemstash
@@ -19,6 +21,7 @@ module Gemstash
19
21
  def self.parse_authorization(request_env)
20
22
  http_auth = Rack::Auth::Basic::Request.new(request_env)
21
23
  return http_auth.credentials.first if http_auth.provided? && http_auth.basic?
24
+
22
25
  request_env["HTTP_AUTHORIZATION"]
23
26
  end
24
27
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "set"
2
4
 
3
5
  module Gemstash
@@ -17,9 +19,7 @@ module Gemstash
17
19
 
18
20
  unless permissions == "all"
19
21
  permissions.each do |permission|
20
- unless VALID_PERMISSIONS.include?(permission)
21
- raise "Invalid permission '#{permission}'"
22
- end
22
+ raise "Invalid permission '#{permission}'" unless VALID_PERMISSIONS.include?(permission)
23
23
  end
24
24
 
25
25
  permissions = permissions.join(",")
@@ -33,6 +33,7 @@ module Gemstash
33
33
  def self.remove(auth_key)
34
34
  record = Gemstash::DB::Authorization[auth_key: auth_key]
35
35
  return unless record
36
+
36
37
  record.destroy
37
38
  gemstash_env.cache.invalidate_authorization(auth_key)
38
39
  log.info "Authorization '#{auth_key}' with access to '#{record.permissions}' removed"
@@ -40,6 +41,7 @@ module Gemstash
40
41
 
41
42
  def self.check(auth_key, permission)
42
43
  raise NotAuthorizedError, "Authorization key required" if auth_key.to_s.strip.empty?
44
+
43
45
  auth = self[auth_key]
44
46
  raise NotAuthorizedError, "Authorization key is invalid" unless auth
45
47
  raise NotAuthorizedError, "Authorization key doesn't have #{permission} access" unless auth.can?(permission)
@@ -48,6 +50,7 @@ module Gemstash
48
50
  def self.[](auth_key)
49
51
  cached_auth = gemstash_env.cache.authorization(auth_key)
50
52
  return cached_auth if cached_auth
53
+
51
54
  record = Gemstash::DB::Authorization[auth_key: auth_key]
52
55
 
53
56
  if record
@@ -65,6 +68,7 @@ module Gemstash
65
68
 
66
69
  def can?(permission)
67
70
  raise "Invalid permission '#{permission}'" unless VALID_PERMISSIONS.include?(permission)
71
+
68
72
  all? || @permissions.include?(permission)
69
73
  end
70
74
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "lru_redux"
2
4
  require "forwardable"
3
5
 
@@ -6,7 +8,7 @@ module Gemstash
6
8
  # for them. Under the hood is either a Memcached client via the dalli gem, or
7
9
  # an in memory client via the lru_redux gem.
8
10
  class Cache
9
- EXPIRY = 30 * 60
11
+ EXPIRY = Env.current.config[:cache_expiration]
10
12
  extend Forwardable
11
13
  def_delegators :@client, :flush
12
14
 
@@ -47,7 +49,7 @@ module Gemstash
47
49
 
48
50
  # Wrapper around the lru_redux gem to behave like a dalli Memcached client.
49
51
  class LruReduxClient
50
- MAX_SIZE = 500
52
+ MAX_SIZE = Env.current.config[:cache_max_size]
51
53
  EXPIRY = Gemstash::Cache::EXPIRY
52
54
  extend Forwardable
53
55
  def_delegators :@cache, :delete
@@ -68,6 +70,7 @@ module Gemstash
68
70
  # Atomic fetch... don't rely on nil meaning missing
69
71
  value = @cache.fetch(key) { found = false }
70
72
  next unless found
73
+
71
74
  yield(key, value)
72
75
  end
73
76
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "gemstash"
2
4
  require "thor"
3
5
  require "thor/error"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "gemstash"
2
4
  require "securerandom"
3
5
 
@@ -32,9 +34,7 @@ Instead just authorize with the new set of permissions")
32
34
  end
33
35
 
34
36
  def save_authorization
35
- if @args.include?("all")
36
- raise Gemstash::CLI::Error.new(@cli, "Don't specify permissions to authorize for all")
37
- end
37
+ raise Gemstash::CLI::Error.new(@cli, "Don't specify permissions to authorize for all") if @args.include?("all")
38
38
 
39
39
  @args.each do |arg|
40
40
  unless Gemstash::Authorization::VALID_PERMISSIONS.include?(arg)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "gemstash"
2
4
 
3
5
  module Gemstash
@@ -38,13 +40,14 @@ module Gemstash
38
40
  def check_gemstash_version
39
41
  version = Gem::Version.new(Gemstash::Storage.metadata[:gemstash_version])
40
42
  return if Gem::Requirement.new("<= #{Gemstash::VERSION}").satisfied_by?(Gem::Version.new(version))
43
+
41
44
  raise Gemstash::CLI::Error.new(@cli, "Gemstash version #{Gemstash::VERSION} does not support version " \
42
45
  "#{version}.\nIt appears you may have downgraded Gemstash, please " \
43
46
  "install version #{version} or later.")
44
47
  end
45
48
 
46
49
  def pidfile_args
47
- ["--pidfile", gemstash_env.base_file("puma.pid")]
50
+ ["--pidfile", gemstash_env.pidfile]
48
51
  end
49
52
  end
50
53
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "gemstash"
2
4
  require "fileutils"
3
5
  require "yaml"
@@ -44,11 +46,13 @@ module Gemstash
44
46
 
45
47
  def say_current_config(option, label)
46
48
  return if gemstash_env.config.default?(option)
49
+
47
50
  @cli.say "#{label}: #{gemstash_env.config[option]}"
48
51
  end
49
52
 
50
53
  def ask_with_default(prompt, options, default)
51
54
  raise "The options must all be lower case" if options.any? {|x| x.downcase != x }
55
+
52
56
  result = nil
53
57
  displayed_options = options.map {|x| x == default ? x.upcase : x }
54
58
  prompt = "#{prompt} [#{displayed_options.join(", ")}]"
@@ -135,8 +139,10 @@ module Gemstash
135
139
  # we don't want to store metadata just yet
136
140
  metadata_file = gemstash_env.base_file("metadata.yml")
137
141
  break unless File.exist?(metadata_file)
142
+
138
143
  version = Gem::Version.new(YAML.load_file(metadata_file)[:gemstash_version])
139
144
  break if Gem::Requirement.new("<= #{Gemstash::VERSION}").satisfied_by?(Gem::Version.new(version))
145
+
140
146
  raise Gemstash::CLI::Error.new(@cli, "The base path already exists with a newer version of Gemstash")
141
147
  else
142
148
  @cli.say "Creating the file storage path '#{dir}'"
@@ -160,6 +166,7 @@ module Gemstash
160
166
 
161
167
  def say_error(title, error)
162
168
  return unless @cli.options[:debug]
169
+
163
170
  @cli.say @cli.set_color("#{title}: #{error}", :red)
164
171
 
165
172
  error.backtrace.each do |line|
@@ -177,7 +184,7 @@ module Gemstash
177
184
  def try(thing)
178
185
  @cli.say "Checking that the #{thing} is available"
179
186
  with_new_config { yield }
180
- rescue => e
187
+ rescue StandardError => e
181
188
  say_error "Error checking #{thing}", e
182
189
  raise Gemstash::CLI::Error.new(@cli, "The #{thing} is not available")
183
190
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "gemstash"
2
4
  require "puma/cli"
3
5
 
@@ -18,6 +20,7 @@ module Gemstash
18
20
 
19
21
  def setup_logging
20
22
  return unless daemonize?
23
+
21
24
  Gemstash::Logging.setup_logger(gemstash_env.log_file)
22
25
  end
23
26
 
@@ -30,7 +33,7 @@ module Gemstash
30
33
  end
31
34
 
32
35
  def puma_config
33
- File.expand_path("../../puma.rb", __FILE__)
36
+ File.expand_path("../puma.rb", __dir__)
34
37
  end
35
38
 
36
39
  def args
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "gemstash"
2
4
  require "puma/control_cli"
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "gemstash"
2
4
  require "puma/control_cli"
3
5
 
@@ -1,12 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "gemstash"
2
4
  require "puma/commonlogger"
3
5
 
4
6
  use Rack::Deflater
5
7
  use Gemstash::Logging::RackMiddleware
6
8
 
7
- if Gemstash::Env.daemonized?
8
- use Puma::CommonLogger, Gemstash::Logging::StreamLogger.for_stdout
9
- end
9
+ use Puma::CommonLogger, Gemstash::Logging::StreamLogger.for_stdout if Gemstash::Env.daemonized?
10
10
 
11
11
  use Gemstash::Env::RackMiddleware, Gemstash::Env.current
12
12
  use Gemstash::GemSource::RackMiddleware
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "yaml"
2
4
  require "erb"
3
5
 
@@ -10,12 +12,15 @@ module Gemstash
10
12
  db_adapter: "sqlite3",
11
13
  bind: "tcp://0.0.0.0:9292",
12
14
  rubygems_url: "https://rubygems.org",
15
+ ignore_gemfile_source: false,
13
16
  protected_fetch: false,
14
17
  fetch_timeout: 20,
15
18
  # Actual default for db_connection_options is dynamic based on the adapter
16
19
  db_connection_options: {},
17
20
  puma_threads: 16,
18
- puma_workers: 1
21
+ puma_workers: 1,
22
+ cache_expiration: 30 * 60,
23
+ cache_max_size: 500
19
24
  }.freeze
20
25
 
21
26
  DEFAULT_FILE = File.expand_path("~/.gemstash/config.yml").freeze
@@ -35,6 +40,7 @@ module Gemstash
35
40
  end
36
41
 
37
42
  raise MissingFileError, file if file && !File.exist?(file)
43
+
38
44
  file ||= default_file
39
45
 
40
46
  if File.exist?(file)
@@ -1,9 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "gemstash"
2
4
 
3
5
  module Gemstash
4
6
  # Module containing the DB models.
5
7
  module DB
6
8
  raise "Gemstash::DB cannot be loaded until the Gemstash::Env is available" unless Gemstash::Env.available?
9
+
7
10
  Sequel::Model.db = Gemstash::Env.current.db
8
11
  Sequel::Model.raise_on_save_failure = true
9
12
  Sequel::Model.plugin :timestamps, update_on_create: true
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "gemstash"
2
4
 
3
5
  module Gemstash
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "gemstash"
2
4
 
3
5
  module Gemstash
@@ -9,6 +11,7 @@ module Gemstash
9
11
  upstream_id = Gemstash::DB::Upstream.find_or_insert(upstream)
10
12
  record = self[upstream_id: upstream_id, name: gem_name.name, resource_type: resource_type.to_s]
11
13
  return record.id if record
14
+
12
15
  new(upstream_id: upstream_id, name: gem_name.name, resource_type: resource_type.to_s).tap(&:save).id
13
16
  end
14
17
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "gemstash"
2
4
 
3
5
  module Gemstash
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "gemstash"
2
4
 
3
5
  module Gemstash
@@ -7,6 +9,7 @@ module Gemstash
7
9
  def self.find_or_insert(spec)
8
10
  record = self[name: spec.name]
9
11
  return record.id if record
12
+
10
13
  new(name: spec.name).tap(&:save).id
11
14
  end
12
15
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Gemstash
2
4
  module DB
3
5
  # Sequel model for upstreams table.
@@ -5,6 +7,7 @@ module Gemstash
5
7
  def self.find_or_insert(upstream)
6
8
  record = self[uri: upstream.to_s]
7
9
  return record.id if record
10
+
8
11
  new(uri: upstream.to_s, host_id: upstream.host_id).tap(&:save).id
9
12
  end
10
13
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "gemstash"
2
4
 
3
5
  module Gemstash
@@ -52,6 +54,7 @@ module Gemstash
52
54
  def self.find_by_full_name(full_name)
53
55
  result = self[full_name: full_name]
54
56
  return result if result
57
+
55
58
  # Try again with the default platform, in case it is implied
56
59
  self[full_name: "#{full_name}-ruby"]
57
60
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "cgi"
2
4
  require "set"
3
5
 
@@ -59,6 +61,7 @@ module Gemstash
59
61
  def fetch_from_database
60
62
  return if done?
61
63
  return unless @db_model
64
+
62
65
  log.info "Querying dependencies: #{@gems.to_a.join(", ")}"
63
66
 
64
67
  @db_model.fetch(@gems) do |gem, value|
@@ -71,6 +74,7 @@ module Gemstash
71
74
  def fetch_from_web
72
75
  return if done?
73
76
  return unless @http_client
77
+
74
78
  log.info "Fetching dependencies: #{@gems.to_a.join(", ")}"
75
79
  gems_param = @gems.map {|gem| CGI.escape(gem) }.join(",")
76
80
  fetched = @http_client.get("api/v1/dependencies?gems=#{gems_param}")
@@ -1,9 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "gemstash"
2
4
  require "active_support/core_ext/file/atomic"
3
5
  require "dalli"
4
6
  require "fileutils"
5
7
  require "sequel"
6
8
  require "uri"
9
+ require "pathname"
7
10
 
8
11
  module Gemstash
9
12
  # Storage for application-wide variables and configuration.
@@ -15,7 +18,7 @@ module Gemstash
15
18
 
16
19
  # Little module to provide easy access to the current Gemstash::Env.
17
20
  module Helper
18
- private
21
+ private # rubocop:disable Layout/AccessModifierIndentation
19
22
 
20
23
  def gemstash_env
21
24
  Gemstash::Env.current
@@ -48,6 +51,7 @@ module Gemstash
48
51
 
49
52
  def self.current
50
53
  raise EnvNotSetError unless Thread.current[:gemstash_env]
54
+
51
55
  Thread.current[:gemstash_env]
52
56
  end
53
57
 
@@ -57,6 +61,7 @@ module Gemstash
57
61
 
58
62
  def self.daemonized?
59
63
  raise "Daemonized hasn't been set yet!" if @daemonized.nil?
64
+
60
65
  @daemonized
61
66
  end
62
67
 
@@ -105,12 +110,25 @@ module Gemstash
105
110
  end
106
111
  end
107
112
 
113
+ def pidfile
114
+ if config[:pidfile]
115
+ pathname = Pathname.new(config[:pidfile])
116
+ if pathname.relative?
117
+ base_file(pathname.to_s)
118
+ else
119
+ pathname.to_s
120
+ end
121
+ else
122
+ base_file("puma.pid")
123
+ end
124
+ end
125
+
108
126
  def atomic_write(file, &block)
109
127
  File.atomic_write(file, File.dirname(file), &block)
110
128
  end
111
129
 
112
130
  def rackup
113
- File.expand_path("../config.ru", __FILE__)
131
+ File.expand_path("config.ru", __dir__)
114
132
  end
115
133
 
116
134
  def db
@@ -122,7 +140,7 @@ module Gemstash
122
140
  db = if RUBY_PLATFORM == "java"
123
141
  Sequel.connect("jdbc:sqlite:#{db_path}", config.database_connection_config)
124
142
  else
125
- Sequel.connect("sqlite://#{URI.escape(db_path)}", config.database_connection_config)
143
+ Sequel.connect("sqlite://#{CGI.escape(db_path)}", config.database_connection_config)
126
144
  end
127
145
  when "postgres", "mysql", "mysql2"
128
146
  db = Sequel.connect(config[:db_url], config.database_connection_config)
@@ -137,7 +155,7 @@ module Gemstash
137
155
 
138
156
  def self.migrate(db)
139
157
  Sequel.extension :migration
140
- migrations_dir = File.expand_path("../migrations", __FILE__)
158
+ migrations_dir = File.expand_path("migrations", __dir__)
141
159
  Sequel::Migrator.run(db, migrations_dir, :use_transactions => true)
142
160
  end
143
161