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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/lib/shaf/command/test.rb +0 -3
- data/lib/shaf/command/upgrade.rb +41 -4
- data/lib/shaf/generator/serializer.rb +2 -2
- data/lib/shaf/generator/templates/api/policy.rb.erb +1 -1
- data/lib/shaf/generator/templates/spec/integration_spec.rb.erb +41 -41
- data/lib/shaf/generator/templates/spec/serializer_spec.rb.erb +5 -5
- data/lib/shaf/rake/db.rb +1 -1
- data/lib/shaf/settings.rb +1 -11
- data/lib/shaf/spec/http_method_utils.rb +2 -0
- data/lib/shaf/tasks/api_doc_task.rb +4 -4
- data/lib/shaf/upgrade/package.rb +34 -12
- data/lib/shaf/upgrade/version.rb +8 -4
- data/lib/shaf/utils.rb +26 -1
- data/lib/shaf/version.rb +1 -1
- data/templates/Rakefile +4 -4
- data/templates/api/controllers/base_controller.rb +8 -0
- data/templates/config/bootstrap.rb +9 -5
- data/templates/config/database.rb +39 -33
- data/templates/config/database.yml +14 -0
- data/templates/config/initializers/db_migrations.rb +32 -19
- data/templates/config/initializers/hal_presenter.rb +2 -0
- data/templates/spec/integration/root_spec.rb +2 -2
- data/templates/spec/serializers/root_serializer_spec.rb +1 -1
- data/upgrades/0.5.0.tar.gz +0 -0
- data/upgrades/1.0.0.tar.gz +0 -0
- data/upgrades/1.0.4.tar.gz +0 -0
- data/upgrades/1.2.0.tar.gz +0 -0
- metadata +21 -5
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 63fafb2ab34a4535e8d5ff38476ffcd43051bdcbeb397b9e9b06bc2c5fa855af
|
4
|
+
data.tar.gz: 8ce6362451525448857762bbfb016c80d698615dbf436549b3a600cf2521e72a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1f9fdf99ec948ac02e171efdb6be8d0f71c6e8231e8f9e27546f97f62c38b1d3365716d6e14a51f01676a0432e4b09be06db70a3ba8df571118dc2d8bba2266f
|
7
|
+
data.tar.gz: 737e3f828105a47ff124a02d0ccff2f8c9f2b60ec1202fab9ac695a860d3444a31147a90d6b3faa8120e1effe15f849941d883bc7f4d0e23d46e1ef8fa0302c2
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/lib/shaf/command/test.rb
CHANGED
data/lib/shaf/command/upgrade.rb
CHANGED
@@ -5,20 +5,42 @@ module Shaf
|
|
5
5
|
class Upgrade < Base
|
6
6
|
|
7
7
|
class UnknownShafVersionError < CommandError; end
|
8
|
-
class UpgradeFailedError < CommandError
|
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
|
-
|
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
|
-
|
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(
|
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: "
|
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",
|
@@ -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', '
|
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
|
data/lib/shaf/rake/db.rb
CHANGED
@@ -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
|
data/lib/shaf/settings.rb
CHANGED
@@ -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
|
@@ -106,19 +106,19 @@ module Shaf
|
|
106
106
|
end
|
107
107
|
|
108
108
|
def attribute(line)
|
109
|
-
line[/\A\s*attribute[^s]\s*\(
|
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*\(
|
113
|
+
line[/\A\s*link\s*\(?:?['"]?([-:\w]+)['"]?/, 1]
|
114
114
|
end
|
115
115
|
|
116
116
|
def curie(line)
|
117
|
-
line[/\A\s*curie\s*\(
|
117
|
+
line[/\A\s*curie\s*\(?:'?([-\w]+)'?/, 1]
|
118
118
|
end
|
119
119
|
|
120
120
|
def embed(line)
|
121
|
-
line[/\A\s*embed\s*\(
|
121
|
+
line[/\A\s*embed\s*\(?:'?([-:\w]+)'?/, 1]
|
122
122
|
end
|
123
123
|
end
|
124
124
|
end
|
data/lib/shaf/upgrade/package.rb
CHANGED
@@ -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
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
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).
|
147
|
-
@manifest.patches_for(file).
|
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
|
-
|
162
|
-
|
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.
|
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).
|
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
|
|
data/lib/shaf/upgrade/version.rb
CHANGED
@@ -14,11 +14,13 @@ module Shaf
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def initialize(version)
|
17
|
-
|
17
|
+
case version
|
18
|
+
when Version
|
18
19
|
@major, @minor, @patch = [:major, :minor, :patch].map { |m| version.send m }
|
19
|
-
|
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)
|
data/lib/shaf/utils.rb
CHANGED
@@ -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']
|
123
|
+
ENV['RACK_ENV'] = env
|
99
124
|
require 'config/bootstrap'
|
100
125
|
yield if block_given?
|
101
126
|
end
|
data/lib/shaf/version.rb
CHANGED
data/templates/Rakefile
CHANGED
@@ -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
|
-
|
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
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
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
|
-
|
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
|
-
|
7
|
-
|
8
|
-
|
9
|
-
end
|
6
|
+
class DbMigrations
|
7
|
+
def self.verify
|
8
|
+
new.verify
|
9
|
+
end
|
10
10
|
|
11
|
-
def
|
12
|
-
|
13
|
-
|
11
|
+
def verify
|
12
|
+
return if fully_migrated?
|
13
|
+
run_migrations? ? migrate : show_warning
|
14
|
+
end
|
14
15
|
|
15
|
-
def
|
16
|
-
|
17
|
-
|
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
|
20
|
-
|
21
|
-
end
|
21
|
+
def migrations_dir
|
22
|
+
File.join(Shaf::Settings.app_root, Shaf::Settings.migrations_dir)
|
23
|
+
end
|
22
24
|
|
23
|
-
def
|
24
|
-
|
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
|
-
|
27
|
-
|
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
|
-
|
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
|
-
|
50
|
+
DbMigrations.verify
|
data/upgrades/0.5.0.tar.gz
CHANGED
Binary file
|
data/upgrades/1.0.0.tar.gz
CHANGED
Binary file
|
data/upgrades/1.0.4.tar.gz
CHANGED
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.
|
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-
|
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.
|
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.
|
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.
|
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
|