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