gemstash 2.0.0 → 2.1.0

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