shaf 1.1.0 → 1.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f71cd9b7d938bb9cf8c6cabb87dc85bd912052e371884ac253ec20afe8657c90
4
- data.tar.gz: e09e82d1f026f3d00e9a849b7ff65c04479940838f0f45bbdfa644ecdc47ef81
3
+ metadata.gz: 63fafb2ab34a4535e8d5ff38476ffcd43051bdcbeb397b9e9b06bc2c5fa855af
4
+ data.tar.gz: 8ce6362451525448857762bbfb016c80d698615dbf436549b3a600cf2521e72a
5
5
  SHA512:
6
- metadata.gz: 4140819946300e345ad2898212241275017c57f586c5dc47d51872047e2a9d4dd48e2d5e06662e83b98ba8963b6c7e87d69d7cae0fe4e79b11ecf0639f739d42
7
- data.tar.gz: 3a75893536dd2a17edcdacb8aaba291baa0ecbebc33d2b16b79015d80f922de0f3af79264f87b8acdf0c5b98f6285c6289d2e1e9db419e62cc7af5341620d7e0
6
+ metadata.gz: 1f9fdf99ec948ac02e171efdb6be8d0f71c6e8231e8f9e27546f97f62c38b1d3365716d6e14a51f01676a0432e4b09be06db70a3ba8df571118dc2d8bba2266f
7
+ data.tar.gz: 737e3f828105a47ff124a02d0ccff2f8c9f2b60ec1202fab9ac695a860d3444a31147a90d6b3faa8120e1effe15f849941d883bc7f4d0e23d46e1ef8fa0302c2
Binary file
data.tar.gz.sig CHANGED
Binary file
@@ -1,7 +1,4 @@
1
- require 'rubygems'
2
- require 'bundler'
3
1
  require 'set'
4
- Bundler.require :development, :test
5
2
  require 'shaf/command/test/filter'
6
3
  require 'shaf/command/test/runner'
7
4
  require 'shaf/command/test/runnable_method'
@@ -5,20 +5,42 @@ module Shaf
5
5
  class Upgrade < Base
6
6
 
7
7
  class UnknownShafVersionError < CommandError; end
8
- class UpgradeFailedError < CommandError; end
8
+ class UpgradeFailedError < CommandError
9
+ attr_reader :version
10
+
11
+ def initialize(version)
12
+ @version = version
13
+ end
14
+ end
9
15
 
10
16
  identifier %r(\Aupgrade\Z)
11
17
  usage 'upgrade'
12
18
 
19
+ def self.options(parser, options)
20
+ parser.on('--skip VERSION', String, 'Skip version') do |v|
21
+ options[:skip_version] = Shaf::Upgrade::Version.new(v)
22
+ end
23
+ end
24
+
13
25
  def call
14
26
  in_project_root do
15
27
  upgrade_packages.each { |package| apply(package) }
16
28
  puts "\nProject is up-to-date! Shaf version: #{current_version}"
17
29
  end
30
+ rescue UpgradeFailedError => e
31
+ puts <<~ERR
32
+
33
+ Failed to upgrade project to version #{e.version}
34
+ Please try resolve these issues manually and try again.
35
+ For more info see:
36
+ https://github.com/sammyhenningsson/shaf/blob/master/doc/UPGRADE.md
37
+ ERR
18
38
  end
19
39
 
20
40
  def apply(package)
21
- package.load.apply or raise UpgradeFailedError
41
+ unless skip? package
42
+ package.load.apply or raise UpgradeFailedError.new(package.version)
43
+ end
22
44
  write_shaf_version package.version.to_s
23
45
  rescue Errno::ENOENT
24
46
  raise UpgradeFailedError,
@@ -26,12 +48,27 @@ module Shaf
26
48
  " (E.g. `sudo apt install patch` for Ubuntu)"
27
49
  end
28
50
 
51
+ def skip?(package)
52
+ return false unless options[:skip_version]
53
+ package.version == options[:skip_version]
54
+ end
55
+
29
56
  def upgrade_packages
30
- Shaf::Upgrade::Package.all.select { |package| package > current_version }
57
+ current = current_version
58
+ target = target_version
59
+
60
+ Shaf::Upgrade::Package.all.select do |package|
61
+ current < package.version && package.version <= target
62
+ end
31
63
  end
32
64
 
33
65
  def current_version
34
- read_shaf_version or raise UnknownShafVersionError
66
+ version = read_shaf_version or raise UnknownShafVersionError
67
+ Shaf::Upgrade::Version.new(version)
68
+ end
69
+
70
+ def target_version
71
+ Shaf::Upgrade::Version.new(ENV.fetch('UPGRADE_TARGET', '99.9.9'))
35
72
  end
36
73
  end
37
74
  end
@@ -69,7 +69,7 @@ module Shaf
69
69
  end
70
70
 
71
71
  def links
72
- %w(doc:up self doc:edit-form doc:delete)
72
+ %w(collection self doc:edit-form doc:delete)
73
73
  end
74
74
 
75
75
  def curies_with_doc
@@ -103,7 +103,7 @@ module Shaf
103
103
 
104
104
  def collection_link
105
105
  link(
106
- rel: "doc:up",
106
+ rel: "collection",
107
107
  desc: "Link to the collection of all #{plural_name}. " \
108
108
  "Send a POST request to this uri to create a new #{name}",
109
109
  method: "GET or POST",
@@ -8,7 +8,7 @@ class <%= policy_class_name %> < BasePolicy
8
8
 
9
9
  <%= attributes.join("\n ") %>
10
10
 
11
- link :up
11
+ link :collection
12
12
 
13
13
  link :'create-form', :'edit-form', :delete do
14
14
  write?
@@ -5,11 +5,11 @@ describe <%= model_class_name %>, type: :integration do
5
5
  it "returns a <%= name %>" do
6
6
  <%= name %> = <%= model_class_name %>.create
7
7
  get <%= name %>_uri(<%= name %>)
8
- status.must_equal 200
9
- link_rels.must_include(:self)
10
- links[:self][:href].must_equal <%= name %>_uri(<%= name %>)
8
+ _(status).must_equal 200
9
+ _(link_rels).must_include(:self)
10
+ _(links[:self][:href]).must_equal <%= name %>_uri(<%= name %>)
11
11
  <% params.each do |param| -%>
12
- attributes.must_include(:'<%= param[0] %>')
12
+ _(attributes).must_include(:'<%= param[0] %>')
13
13
  <% end -%>
14
14
  end
15
15
 
@@ -18,15 +18,15 @@ describe <%= model_class_name %>, type: :integration do
18
18
  <%= model_class_name %>.create
19
19
 
20
20
  get <%= plural_name %>_uri
21
- status.must_equal 200
22
- link_rels.must_include(:self)
23
- links[:self][:href].must_include <%= plural_name %>_uri
24
- embedded(:'<%= plural_name %>').size.must_equal 2
21
+ _(status).must_equal 200
22
+ _(link_rels).must_include(:self)
23
+ _(links[:self][:href]).must_include <%= plural_name %>_uri
24
+ _(embedded(:'<%= plural_name %>').size).must_equal 2
25
25
 
26
26
  each_embedded :'<%= plural_name %>' do
27
- link_rels.must_include(:self)
27
+ _(link_rels).must_include(:self)
28
28
  <% params.each do |param| -%>
29
- attributes.must_include(:'<%= param[0] %>')
29
+ _(attributes).must_include(:'<%= param[0] %>')
30
30
  <% end -%>
31
31
  end
32
32
  end
@@ -34,34 +34,34 @@ describe <%= model_class_name %>, type: :integration do
34
34
  it "can create <%= plural_name %>" do
35
35
  get <%= plural_name %>_uri
36
36
 
37
- link_rels.must_include(:'doc:create-form')
37
+ _(link_rels).must_include(:'doc:create-form')
38
38
  follow_rel :'doc:create-form'
39
- links[:self][:href].must_equal new_<%= name %>_uri
40
- attributes[:href].must_equal <%= plural_name %>_uri
41
- attributes[:method].must_equal "POST"
42
- attributes[:name].must_equal "create-<%= name %>"
43
- attributes[:title].must_equal "Create <%= model_class_name %>"
44
- attributes[:type].must_equal "application/json"
45
- attributes[:fields].size.must_equal <%= params.size %>
39
+ _(links[:self][:href]).must_equal new_<%= name %>_uri
40
+ _(attributes[:href]).must_equal <%= plural_name %>_uri
41
+ _(attributes[:method]).must_equal "POST"
42
+ _(attributes[:name]).must_equal "create-<%= name %>"
43
+ _(attributes[:title]).must_equal "Create <%= model_class_name %>"
44
+ _(attributes[:type]).must_equal "application/json"
45
+ _(attributes[:fields].size).must_equal <%= params.size %>
46
46
 
47
47
  payload = fill_form attributes[:fields]
48
48
  post attributes[:href], payload
49
- status.must_equal 201
50
- link_rels.must_include(:self)
51
- headers["Location"].must_equal links[:self][:href]
49
+ _(status).must_equal 201
50
+ _(link_rels).must_include(:self)
51
+ _(headers["Location"]).must_equal links[:self][:href]
52
52
 
53
53
  get <%= plural_name %>_uri
54
- status.must_equal 200
55
- links[:self][:href].must_include <%= plural_name %>_uri
56
- embedded(:'<%= plural_name %>').size.must_equal 1
54
+ _(status).must_equal 200
55
+ _(links[:self][:href]).must_include <%= plural_name %>_uri
56
+ _(embedded(:'<%= plural_name %>').size).must_equal 1
57
57
 
58
58
  embedded :'<%= plural_name %>' do
59
59
  <%= name %> = last_payload.first
60
60
  <% params.each do |param| -%>
61
61
  <% if param[1] == 'string' -%>
62
- <%= name %>[:<%= param[0] %>].must_equal "value for <%= param[0] %>"
62
+ _(<%= name %>[:<%= param[0] %>]).must_equal "value for <%= param[0] %>"
63
63
  <% elsif param[1] == 'integer' -%>
64
- <%= name %>[:<%= param[0] %>].must_equal "<%= param[0] %>".size
64
+ _(<%= name %>[:<%= param[0] %>]).must_equal "<%= param[0] %>".size
65
65
  <% end -%>
66
66
  <% end -%>
67
67
  end
@@ -70,37 +70,37 @@ describe <%= model_class_name %>, type: :integration do
70
70
  it "<%= plural_name %> can be updated" do
71
71
  <%= name %> = <%= model_class_name %>.create
72
72
  get <%= name %>_uri(<%= name %>)
73
- status.must_equal 200
73
+ _(status).must_equal 200
74
74
 
75
- link_rels.must_include(:'doc:edit-form')
75
+ _(link_rels).must_include(:'doc:edit-form')
76
76
  follow_rel :'doc:edit-form'
77
77
 
78
- links[:self][:href].must_equal edit_<%= name %>_uri(<%= name %>)
79
- attributes[:href].must_equal <%= name %>_uri(<%= name %>)
80
- attributes[:method].must_equal "PUT"
81
- attributes[:name].must_equal "update-<%= name %>"
82
- attributes[:title].must_equal "Update <%= model_class_name %>"
83
- attributes[:type].must_equal "application/json"
84
- attributes[:fields].size.must_equal <%= params.size %>
78
+ _(links[:self][:href]).must_equal edit_<%= name %>_uri(<%= name %>)
79
+ _(attributes[:href]).must_equal <%= name %>_uri(<%= name %>)
80
+ _(attributes[:method]).must_equal "PUT"
81
+ _(attributes[:name]).must_equal "update-<%= name %>"
82
+ _(attributes[:title]).must_equal "Update <%= model_class_name %>"
83
+ _(attributes[:type]).must_equal "application/json"
84
+ _(attributes[:fields].size).must_equal <%= params.size %>
85
85
 
86
86
  payload = fill_form attributes[:fields]
87
87
  put attributes[:href], payload
88
- status.must_equal 200
89
- link_rels.must_include(:self)
88
+ _(status).must_equal 200
89
+ _(link_rels).must_include(:self)
90
90
  end
91
91
  <% end -%>
92
92
 
93
93
  it "<%= plural_name %> can be deleted" do
94
94
  <%= name %> = <%= model_class_name %>.create
95
95
  get <%= name %>_uri(<%= name %>)
96
- status.must_equal 200
97
- link_rels.must_include(:'doc:delete')
96
+ _(status).must_equal 200
97
+ _(link_rels).must_include(:'doc:delete')
98
98
 
99
99
  follow_rel(:'doc:delete', method: :delete)
100
- status.must_equal 204
100
+ _(status).must_equal 204
101
101
 
102
102
  get <%= name %>_uri(<%= name %>)
103
- status.must_equal 404
103
+ _(status).must_equal 404
104
104
  end
105
105
 
106
106
  end
@@ -16,13 +16,13 @@ describe <%= class_name %> do
16
16
 
17
17
  it "serializes attributes" do
18
18
  <% attributes.each do |attr| -%>
19
- attributes.keys.must_include(<%= attr %>)
19
+ _(attributes.keys).must_include(<%= attr %>)
20
20
  <% end -%>
21
21
  end
22
22
 
23
23
  it "serializes links" do
24
- <% ['self', 'doc:up'].each do |rel| -%>
25
- link_rels.must_include(:'<%= rel %>')
24
+ <% ['self', 'collection'].each do |rel| -%>
25
+ _(link_rels).must_include(:'<%= rel %>')
26
26
  <% end -%>
27
27
  end
28
28
  end
@@ -34,13 +34,13 @@ describe <%= class_name %> do
34
34
 
35
35
  it "serializes attributes" do
36
36
  <% attributes.each do |attr| -%>
37
- attributes.keys.must_include(<%= attr %>)
37
+ _(attributes.keys).must_include(<%= attr %>)
38
38
  <% end -%>
39
39
  end
40
40
 
41
41
  it "serializes links" do
42
42
  <% links.each do |rel| -%>
43
- link_rels.must_include(:'<%= rel %>')
43
+ _(link_rels).must_include(:'<%= rel %>')
44
44
  <% end -%>
45
45
  end
46
46
  end
@@ -1,7 +1,7 @@
1
1
  Shaf::DbTask.new(:version, description: "Prints current schema version") do
2
2
  if migrations.any?
3
3
  version, filename = extract_version_and_filename(last_migration)
4
- puts "Schema version: #{version} (#{filename})"
4
+ puts "Schema version: #{version} (#{filename}) [#{ENV['RACK_ENV']}]"
5
5
  else
6
6
  puts "No migrations found"
7
7
  end
@@ -19,20 +19,10 @@ module Shaf
19
19
  class << self
20
20
  def load
21
21
  @settings = DEFAULTS.dup
22
- config = read_config(SETTINGS_FILE)
22
+ config = Utils.read_config(SETTINGS_FILE, erb: true)
23
23
  @settings.merge! config.fetch(env, {})
24
24
  end
25
25
 
26
- def read_config(file)
27
- return {} unless File.exist? file
28
-
29
- yaml = File.read(file)
30
- if RUBY_VERSION < '2.6.0'
31
- Utils.deep_symbolize_keys(YAML.safe_load(yaml, [], [], true))
32
- else
33
- YAML.safe_load(yaml, aliases: true, symbolize_names: true)
34
- end
35
- end
36
26
 
37
27
  def env
38
28
  (ENV['APP_ENV'] || ENV['RACK_ENV'] || 'development').to_sym
@@ -1,3 +1,5 @@
1
+ require 'rack/test'
2
+
1
3
  module Shaf
2
4
  module Spec
3
5
  module HttpUtils
@@ -106,19 +106,19 @@ module Shaf
106
106
  end
107
107
 
108
108
  def attribute(line)
109
- line[/\A\s*attribute[^s]\s*\(?\s*:(\w+)/, 1]
109
+ line[/\A\s*attribute[^s]\s*\(?:(\w+)/, 1]
110
110
  end
111
111
 
112
112
  def link(line)
113
- line[/\A\s*link\s*\(?\s*:'?([-:\w]+)'?/, 1]
113
+ line[/\A\s*link\s*\(?:?['"]?([-:\w]+)['"]?/, 1]
114
114
  end
115
115
 
116
116
  def curie(line)
117
- line[/\A\s*curie\s*\(?\s*:'?([-\w]+)'?/, 1]
117
+ line[/\A\s*curie\s*\(?:'?([-\w]+)'?/, 1]
118
118
  end
119
119
 
120
120
  def embed(line)
121
- line[/\A\s*embed\s*\(?\s*:'?([-:\w]+)'?/, 1]
121
+ line[/\A\s*embed\s*\(?:'?([-:\w]+)'?/, 1]
122
122
  end
123
123
  end
124
124
  end
@@ -21,6 +21,7 @@ module Shaf
21
21
 
22
22
  UPGRADE_FILES_PATH = File.join(Utils.gem_root, 'upgrades').freeze
23
23
  MANIFEST_FILENAME = 'manifest'.freeze
24
+ IGNORE_FILE_PATTERNS = [/.rej\z/, /.orig\z/]
24
25
 
25
26
  attr_reader :version
26
27
 
@@ -76,10 +77,13 @@ module Shaf
76
77
  end
77
78
 
78
79
  def apply(dir = nil)
79
- apply_patches(dir)
80
- apply_drops(dir)
81
- apply_additions
82
- apply_substitutes(dir)
80
+ puts "Applying changes for version #{version}" if ENV["VERBOSE"] == "1"
81
+ [
82
+ apply_patches(dir),
83
+ apply_drops(dir),
84
+ apply_additions,
85
+ apply_substitutes(dir),
86
+ ].all?
83
87
  end
84
88
 
85
89
  def to_s
@@ -139,12 +143,20 @@ module Shaf
139
143
 
140
144
  def files_in(dir)
141
145
  dir += '/' if !dir.nil? && dir[-1] != '/'
142
- Dir["#{dir}**/*"]
146
+ Dir["#{dir}**/*"].reject do |file|
147
+ ignore? file
148
+ end
149
+ end
150
+
151
+ def ignore?(file)
152
+ IGNORE_FILE_PATTERNS.any? do |pattern|
153
+ file.match? pattern
154
+ end
143
155
  end
144
156
 
145
157
  def apply_patches(dir = nil)
146
- files_in(dir).each do |file|
147
- @manifest.patches_for(file).each do |name|
158
+ files_in(dir).all? do |file|
159
+ @manifest.patches_for(file).all? do |name|
148
160
  patch = @files[name]
149
161
  apply_patch(file, patch)
150
162
  end
@@ -158,27 +170,37 @@ module Shaf
158
170
  puts o.read
159
171
  err = e.read
160
172
  puts err unless err.empty?
161
- next if t.value.success?
162
- STDERR.puts "Failed to apply patch for: #{file}\n"
173
+ t.value.success?.tap do |patch_succeeded|
174
+ next if patch_succeeded
175
+ STDERR.puts "Failed to apply patch for: #{file}\n"
176
+ end
163
177
  end
164
178
  end
165
179
 
166
180
  def apply_additions
167
181
  puts '' unless @manifest.additions.empty?
168
- @manifest.additions.each do |chksum, filename|
182
+ @manifest.additions.all? do |chksum, filename|
169
183
  content = @files[chksum]
170
184
  FileUtils.mkdir_p File.dirname(filename)
171
185
  puts "adding file: #{filename}"
172
186
  File.open(filename, 'w') { |file| file.write(content) }
187
+ true
188
+ rescue StandardError => e
189
+ STDERR.puts "Failed to add '#{filename}': #{e.message}\n"
190
+ false
173
191
  end
174
192
  end
175
193
 
176
194
  def apply_drops(dir = nil)
177
195
  puts '' unless @manifest.removals.empty?
178
- files_in(dir).map do |file|
179
- next unless @manifest.drop?(file)
196
+ files_in(dir).all? do |file|
197
+ next true unless @manifest.drop?(file)
180
198
  puts "removing file: #{file}"
181
199
  File.unlink(file)
200
+ true
201
+ rescue StandardError => e
202
+ STDERR.puts "Failed to unlink '#{file}': #{e.message}\n"
203
+ false
182
204
  end
183
205
  end
184
206
 
@@ -14,11 +14,13 @@ module Shaf
14
14
  end
15
15
 
16
16
  def initialize(version)
17
- if self.class === version
17
+ case version
18
+ when Version
18
19
  @major, @minor, @patch = [:major, :minor, :patch].map { |m| version.send m }
19
- else
20
- raise UpgradeVersionError.new(version) unless version =~ /\d+\.\d+\.\d+/
20
+ when /\d+\.\d+(\.\d+)?/
21
21
  @major, @minor, @patch = split_version(version)
22
+ else
23
+ raise UpgradeVersionError.new(version)
22
24
  end
23
25
  end
24
26
 
@@ -37,7 +39,9 @@ module Shaf
37
39
  private
38
40
 
39
41
  def split_version(str)
40
- str.split('.').map(&:to_i)
42
+ str.split('.').map(&:to_i).tap do |list|
43
+ list << 0 while list.size < 3
44
+ end
41
45
  end
42
46
 
43
47
  def compare_version(other_major, other_minor, other_patch)
@@ -1,7 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'erb'
3
4
  require 'forwardable'
5
+ require 'yaml'
4
6
  require 'shaf/version'
7
+ require 'sinatra/base'
5
8
 
6
9
  module Shaf
7
10
  module Utils
@@ -41,6 +44,10 @@ module Shaf
41
44
  symbolize(str).inspect
42
45
  end
43
46
 
47
+ def environment
48
+ Sinatra::Application.settings.environment
49
+ end
50
+
44
51
  def rackify_header(str)
45
52
  return if str.nil?
46
53
  str.upcase.tr('-', '_').tap do |key|
@@ -60,6 +67,24 @@ module Shaf
60
67
  value
61
68
  end
62
69
  end
70
+
71
+ def read_config(file, erb: false, erb_binding: nil)
72
+ return {} unless File.exist? file
73
+
74
+ yaml = File.read(file)
75
+ yaml = erb(yaml, binding: erb_binding) if erb || erb_binding
76
+ if RUBY_VERSION < '2.6.0'
77
+ Utils.deep_symbolize_keys(YAML.safe_load(yaml, [], [], true))
78
+ else
79
+ YAML.safe_load(yaml, aliases: true, symbolize_names: true)
80
+ end
81
+ end
82
+
83
+ def erb(content, binding: nil)
84
+ bindings = binding ? [binding] : []
85
+ return ERB.new(content, 0, '%-<>').result(*bindings) if RUBY_VERSION < '2.6.0'
86
+ ERB.new(content, trim_mode: '-<>').result(*bindings)
87
+ end
63
88
  end
64
89
 
65
90
  def_delegators Utils, :pluralize, :singularize, :symbolize, :symbol_string, :gem_root, :rackify_header
@@ -95,7 +120,7 @@ module Shaf
95
120
 
96
121
  def bootstrap(env: 'development')
97
122
  in_project_root do
98
- ENV['RACK_ENV'] ||= env
123
+ ENV['RACK_ENV'] = env
99
124
  require 'config/bootstrap'
100
125
  yield if block_given?
101
126
  end
@@ -1,3 +1,3 @@
1
1
  module Shaf
2
- VERSION = "1.1.0"
2
+ VERSION = "1.2.0"
3
3
  end
@@ -1,7 +1,7 @@
1
- require 'rubygems'
2
- require 'bundler'
3
- Bundler.setup(:default, :development)
4
- $:.unshift __dir__
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift __dir__ unless $LOAD_PATH.include? __dir__
4
+
5
5
  require 'shaf/rake'
6
6
  require 'shaf/settings'
7
7
 
@@ -39,6 +39,14 @@ class BaseController < Sinatra::Base
39
39
  before do
40
40
  log.info "Processing: #{request.request_method} #{request.path_info}"
41
41
  log.debug "Payload: #{payload || 'empty'}"
42
+ set_vary_header
43
+ end
44
+
45
+ def set_vary_header
46
+ return unless settings.auth_token_header
47
+ return unless [:get, :head].include? request.request_method.downcase.to_sym
48
+
49
+ headers('Vary' => Shaf::Settings.auth_token_header)
42
50
  end
43
51
 
44
52
  not_found do
@@ -1,11 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'rubygems'
4
- require 'bundler'
5
- Bundler.require(:default, ENV['RACK_ENV'])
6
-
7
3
  $logger = nil
8
- require 'shaf/settings'
4
+
5
+ require 'shaf'
6
+ if ENV['RACK_ENV'] == 'test'
7
+ require 'minitest'
8
+ require 'minitest/autorun'
9
+ require 'minitest/hooks'
10
+ require 'shaf/spec'
11
+ end
12
+
9
13
  require 'config/paths'
10
14
  require 'config/database'
11
15
  require 'config/initializers'
@@ -1,39 +1,45 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'sinatra/base'
4
3
  require 'sequel'
5
4
  require 'fileutils'
6
-
7
- config = {
8
-
9
- production: {
10
- adapter: 'postgres',
11
- host: ENV['SHAF_DB_HOST'],
12
- database: ENV['SHAF_DB_NAME'],
13
- user: ENV['SHAF_DB_USER'],
14
- password: ENV['SHAF_DB_PASS']
15
- }.freeze,
16
-
17
- development: {
18
- adapter: 'sqlite',
19
- database: 'db/development.sqlite3'
20
- }.freeze,
21
-
22
- test: {
23
- adapter: 'sqlite',
24
- database: 'db/test.sqlite3'
25
- }.freeze
26
-
27
- }.freeze
28
-
29
- env = Sinatra::Application.settings.environment
30
-
31
- unless config[env]
32
- STDERR.puts "No Database config for environment '#{env}'"
33
- exit 1
5
+ require 'yaml'
6
+ require 'shaf/utils'
7
+
8
+ class Database
9
+ CONFIG_FILE = File.expand_path("../database.yml", __FILE__)
10
+ MIGRATIONS_DIR = 'db/migrations'
11
+
12
+ class << self
13
+ def get_connection
14
+ ensure_config
15
+ ensure_migrations_dir
16
+
17
+ connect
18
+ end
19
+
20
+ def config
21
+ @config ||= Shaf::Utils.read_config(CONFIG_FILE, erb: true)
22
+ end
23
+
24
+ def env
25
+ Shaf::Utils.environment
26
+ end
27
+
28
+ def connect
29
+ Sequel.connect config[env]
30
+ end
31
+
32
+ def ensure_config
33
+ return if config[env]
34
+ STDERR.puts "No Database config for environment '#{env}'"
35
+ exit 1
36
+ end
37
+
38
+ def ensure_migrations_dir
39
+ return if Dir.exist?(MIGRATIONS_DIR)
40
+ FileUtils.mkdir_p(MIGRATIONS_DIR)
41
+ end
42
+ end
34
43
  end
35
44
 
36
- migrations_dir = 'db/migrations'
37
- FileUtils.mkdir_p(migrations_dir) unless Dir.exist?(migrations_dir)
38
-
39
- DB = Sequel.connect(config[env])
45
+ DB = Database.get_connection
@@ -0,0 +1,14 @@
1
+ production:
2
+ adapter: postgres
3
+ host: <%= ENV['SHAF_DB_HOST'] %>
4
+ database: <%= ENV['SHAF_DB_NAME'] %>
5
+ user: <%= ENV['SHAF_DB_USER'] %>
6
+ password: <%= ENV['SHAF_DB_PASS'] %>
7
+
8
+ development:
9
+ adapter: sqlite
10
+ database: db/development.sqlite3
11
+
12
+ test:
13
+ adapter: sqlite
14
+ database: db/test.sqlite3
@@ -3,30 +3,43 @@ require 'config/database'
3
3
 
4
4
  Sequel.extension :migration
5
5
 
6
- def current?
7
- return true unless Dir[migrations_dir_glob].any?
8
- Sequel::Migrator.is_current?(DB, migrations_dir)
9
- end
6
+ class DbMigrations
7
+ def self.verify
8
+ new.verify
9
+ end
10
10
 
11
- def migrations_dir
12
- File.join(Shaf::Settings.app_root, Shaf::Settings.migrations_dir)
13
- end
11
+ def verify
12
+ return if fully_migrated?
13
+ run_migrations? ? migrate : show_warning
14
+ end
14
15
 
15
- def migrations_dir_glob
16
- File.join(migrations_dir, '*')
17
- end
16
+ def fully_migrated?
17
+ return true unless Dir[migrations_dir_glob].any?
18
+ Sequel::Migrator.is_current?(DB, migrations_dir)
19
+ end
18
20
 
19
- def environment
20
- ENV['RACK_ENV']
21
- end
21
+ def migrations_dir
22
+ File.join(Shaf::Settings.app_root, Shaf::Settings.migrations_dir)
23
+ end
22
24
 
23
- def init
24
- return if current?
25
+ def migrations_dir_glob
26
+ File.join(migrations_dir, '*')
27
+ end
28
+
29
+ def environment
30
+ ENV['RACK_ENV']
31
+ end
25
32
 
26
- if environment == 'test'
27
- $logger.info "Running migrations in 'test' environment.."
33
+ def run_migrations?
34
+ environment == 'test'
35
+ end
36
+
37
+ def migrate
38
+ $logger&.info "Running migrations in #{environment} environment.."
28
39
  Sequel::Migrator.run(DB, migrations_dir)
29
- else
40
+ end
41
+
42
+ def show_warning
30
43
  msg = "Database for environment '#{environment}' is not " \
31
44
  'updated to the latest migration'
32
45
  STDERR.puts msg
@@ -34,4 +47,4 @@ def init
34
47
  end
35
48
  end
36
49
 
37
- init
50
+ DbMigrations.verify
@@ -1 +1,3 @@
1
+ require 'hal_presenter'
2
+
1
3
  HALPresenter.paginate = true
@@ -4,11 +4,11 @@ describe "Root", type: :integration do
4
4
 
5
5
  before do
6
6
  get root_uri
7
- status.must_equal 200
7
+ _(status).must_equal 200
8
8
  end
9
9
 
10
10
  it "returns links" do
11
- links.must_include :self
11
+ _(links).must_include :self
12
12
  end
13
13
 
14
14
  end
@@ -7,6 +7,6 @@ describe RootSerializer do
7
7
  end
8
8
 
9
9
  it "serializes links" do
10
- links.keys.must_include(:self)
10
+ _(links.keys).must_include(:self)
11
11
  end
12
12
  end
Binary file
Binary file
Binary file
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shaf
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sammy Henningsson
@@ -30,7 +30,7 @@ cert_chain:
30
30
  ZMhjYR7sRczGJx+GxGU2EaR0bjRsPVlC4ywtFxoOfRG3WaJcpWGEoAoMJX6Z0bRv
31
31
  M40=
32
32
  -----END CERTIFICATE-----
33
- date: 2019-08-31 00:00:00.000000000 Z
33
+ date: 2019-09-23 00:00:00.000000000 Z
34
34
  dependencies:
35
35
  - !ruby/object:Gem::Dependency
36
36
  name: minitest
@@ -41,7 +41,7 @@ dependencies:
41
41
  version: '5'
42
42
  - - ">="
43
43
  - !ruby/object:Gem::Version
44
- version: '5.10'
44
+ version: '5.11'
45
45
  type: :development
46
46
  prerelease: false
47
47
  version_requirements: !ruby/object:Gem::Requirement
@@ -51,7 +51,7 @@ dependencies:
51
51
  version: '5'
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '5.10'
54
+ version: '5.11'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rack-test
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -122,6 +122,20 @@ dependencies:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
124
  version: '1.3'
125
+ - !ruby/object:Gem::Dependency
126
+ name: redcarpet
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '3.5'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '3.5'
125
139
  description: A framework for building hypermedia driven APIs with sinatra and sequel.
126
140
  email: sammy.henningsson@gmail.com
127
141
  executables:
@@ -238,6 +252,7 @@ files:
238
252
  - templates/config/bootstrap.rb
239
253
  - templates/config/customize.rb
240
254
  - templates/config/database.rb
255
+ - templates/config/database.yml
241
256
  - templates/config/directories.rb
242
257
  - templates/config/helpers.rb
243
258
  - templates/config/initializers.rb
@@ -260,6 +275,7 @@ files:
260
275
  - upgrades/1.0.0.tar.gz
261
276
  - upgrades/1.0.4.tar.gz
262
277
  - upgrades/1.1.0.tar.gz
278
+ - upgrades/1.2.0.tar.gz
263
279
  homepage:
264
280
  licenses:
265
281
  - MIT
@@ -281,7 +297,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
281
297
  - !ruby/object:Gem::Version
282
298
  version: '0'
283
299
  requirements: []
284
- rubygems_version: 3.0.1
300
+ rubygems_version: 3.0.6
285
301
  signing_key:
286
302
  specification_version: 4
287
303
  summary: Sinatra Hypermedia Api Framework
metadata.gz.sig CHANGED
Binary file