pangea 0.0.36 → 0.0.38
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
- data/Gemfile +1 -0
- data/Gemfile.lock +1 -0
- data/lib/pangea/cli/subcommands/infra.rb +214 -162
- data/lib/pangea/modules.rb +76 -7
- data/lib/pangea/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3f3e6f63447395733123799d775f0e399fffc41e1775e565a3f45ddfa2e54757
|
4
|
+
data.tar.gz: 8677e8ab34de7c145ba207cce558fa06d2d697a539c19fc90290ed7d5baf6e3b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7d028cb0f6d1d5471c74769fb5e63583d5078c82b86e35f4f28364ba3defc549311ad03a684498b443362b0eca6affb598e45b1d3ac127fe65fc4063922f1944
|
7
|
+
data.tar.gz: 9b11287e63adecb61e5a58d15d25de58105e03116f710618c1bb24a872844163b842cd36917aa3470beeebd3299f45bbca3ff508c81daf3404d3fe08ba7d4b7d
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -8,8 +8,8 @@ require %(pangea/errors/no_infra_target_error)
|
|
8
8
|
require %(pangea/errors/incorrect_subcommand_error)
|
9
9
|
require %(pangea/say/init)
|
10
10
|
require %(pangea/modules)
|
11
|
-
require %(terraform-synthesizer)
|
12
|
-
require %(json)
|
11
|
+
# require %(terraform-synthesizer)
|
12
|
+
# require %(json)
|
13
13
|
|
14
14
|
class InfraCommand < PangeaCommand
|
15
15
|
include Constants
|
@@ -29,36 +29,47 @@ class InfraCommand < PangeaCommand
|
|
29
29
|
desc %(target like ${namespace}.${site})
|
30
30
|
end
|
31
31
|
|
32
|
-
def
|
33
|
-
Say.terminal %(planning!)
|
34
|
-
parse(argv)
|
35
|
-
|
36
|
-
# grab a config synth
|
37
|
-
cfg_synth = Config.resolve_configurations
|
38
|
-
|
39
|
-
# reject empty configurations
|
32
|
+
def reject_empty_configurations
|
40
33
|
if cfg_synth.empty?
|
41
34
|
Say.terminal %(configuration empty, exiting...)
|
42
35
|
exit
|
43
36
|
end
|
37
|
+
end
|
44
38
|
|
45
|
-
|
39
|
+
def help
|
40
|
+
<<~HELP
|
41
|
+
Usage: pangea infra command [OPTIONS] SUBCOMMAND
|
46
42
|
|
47
|
-
|
48
|
-
|
49
|
-
# check_target(params[:target], cfg_synth)
|
43
|
+
Arguments:
|
44
|
+
SUBCOMMAND subcommand for pangea infra
|
50
45
|
|
51
|
-
|
52
|
-
|
46
|
+
Subcommands:
|
47
|
+
plan plan infrastructure
|
48
|
+
apply apply infrastructure
|
49
|
+
config show run configuration
|
50
|
+
HELP
|
51
|
+
end
|
53
52
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
# modules can have a virtual environment to execute in
|
58
|
-
###########################################################################
|
53
|
+
def cfg_synth
|
54
|
+
@cfg_synth ||= Config.resolve_configurations
|
55
|
+
end
|
59
56
|
|
60
|
-
|
57
|
+
def plan(argv)
|
58
|
+
Say.terminal %(planning!)
|
59
|
+
parse(argv)
|
60
|
+
process_modules
|
61
|
+
end
|
62
|
+
|
63
|
+
def config
|
64
|
+
Say.terminal JSON.pretty_generate(cfg_synth)
|
65
|
+
end
|
66
|
+
|
67
|
+
def common_run_checks
|
68
|
+
reject_empty_configurations
|
69
|
+
end
|
61
70
|
|
71
|
+
def process_modules
|
72
|
+
namespaces = cfg_synth[:namespace].keys.map(&:to_sym)
|
62
73
|
namespaces.each do |namespace_name|
|
63
74
|
namespace = cfg_synth[:namespace][namespace_name]
|
64
75
|
context_names = namespace.keys.map(&:to_sym)
|
@@ -67,166 +78,207 @@ class InfraCommand < PangeaCommand
|
|
67
78
|
context = namespace[cn]
|
68
79
|
modules = context[:modules]
|
69
80
|
|
70
|
-
modules.
|
81
|
+
modules.each_key do |mod_key|
|
82
|
+
mod = modules[mod_key]
|
71
83
|
PangeaModule.process(mod)
|
72
84
|
end
|
73
85
|
end
|
74
86
|
end
|
75
|
-
|
76
|
-
###########################################################################
|
77
|
-
|
78
|
-
# provide some kind of default exit of the command execution
|
79
|
-
exit
|
80
|
-
end
|
81
|
-
|
82
|
-
private
|
83
|
-
|
84
|
-
# process stage for target
|
85
|
-
def process_target(targets, cfg_synth)
|
86
|
-
namespaces = cfg_synth[:namespace].keys.map(&:to_sym)
|
87
|
-
environments = []
|
88
|
-
|
89
|
-
namespaces.each do |ns_name|
|
90
|
-
environments.concat(cfg_synth[:namespace][ns_name].keys.map(&:to_sym))
|
91
|
-
end
|
92
|
-
|
93
|
-
case targets.length.to_i
|
94
|
-
# only provided namespace
|
95
|
-
when 1
|
96
|
-
nil
|
97
|
-
# only provided namespace.site
|
98
|
-
when 2
|
99
|
-
nil
|
100
|
-
# only provided namespace.site.project
|
101
|
-
when 3
|
102
|
-
announce_preflight_info(targets, cfg_synth)
|
103
|
-
environments.each do |e_name|
|
104
|
-
projects = cfg_synth[:namespace][targets[0]][e_name][:projects]
|
105
|
-
projects.each do |project|
|
106
|
-
announce_project(project)
|
107
|
-
|
108
|
-
synth = TerraformSynthesizer.new
|
109
|
-
case project[:src][:type].to_sym
|
110
|
-
when :local
|
111
|
-
system %(mkdir -p #{CACHE_DIR}) unless Dir.exist?(CACHE_DIR)
|
112
|
-
PROJECT_SRC_DIRS.each do |src_dir|
|
113
|
-
next unless File.exist?(File.join(
|
114
|
-
project[:src][:location].to_s,
|
115
|
-
%(src),
|
116
|
-
src_dir.to_s
|
117
|
-
))
|
118
|
-
|
119
|
-
synth_files = Dir.glob("#{File.join(
|
120
|
-
project[:src][:location].to_s,
|
121
|
-
%(src),
|
122
|
-
src_dir.to_s
|
123
|
-
)}/**/*.rb")
|
124
|
-
synth_files.each do |synth_file|
|
125
|
-
synth.synthesize(File.read(synth_file))
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
Say.terminal JSON.pretty_generate(synth.synthesis)
|
130
|
-
|
131
|
-
project_cache_dir = File.join(CACHE_DIR, project[:name].to_s)
|
132
|
-
|
133
|
-
system %(mkdir -p #{project_cache_dir}) unless Dir.exist?(project_cache_dir)
|
134
|
-
File.write(File.join(project_cache_dir, ARTIFACT_FILE), synth.synthesis.to_json)
|
135
|
-
system %(cd #{project_cache_dir} && terraform init)
|
136
|
-
system %(cd #{project_cache_dir} && terraform plan)
|
137
|
-
|
138
|
-
when :git
|
139
|
-
nil
|
140
|
-
end
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
# fetch project data
|
145
|
-
# projet_data = cfg_synth[:namespace][targets[0]]
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
def announce_project(project)
|
150
|
-
msg = []
|
151
|
-
msg << %(project: #{project[:name]})
|
152
|
-
msg << %(src: #{project[:src]})
|
153
|
-
Say.terminal msg.map(&:strip).join(%(\n))
|
154
87
|
end
|
155
88
|
|
156
|
-
def
|
157
|
-
|
158
|
-
environments = []
|
89
|
+
def run(argv)
|
90
|
+
common_run_checks
|
159
91
|
|
160
|
-
|
161
|
-
|
92
|
+
if argv.length < 2
|
93
|
+
puts help
|
94
|
+
exit
|
162
95
|
end
|
163
96
|
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
preflight_info << %(namespace: #{targets[0]})
|
168
|
-
preflight_info << %(site: #{targets[1]})
|
169
|
-
preflight_info << %(project: #{targets[2]})
|
170
|
-
|
171
|
-
Say.terminal preflight_info.map(&:strip).join(%(\n))
|
172
|
-
end
|
97
|
+
config if argv[1].to_s.eql?(%(config))
|
98
|
+
plan(argv) if argv[1].to_s.eql?(%(plan))
|
99
|
+
apply(argv) if argv[1].to_s.eql?(%(apply))
|
173
100
|
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
def check_target(target, config)
|
178
|
-
# raise NamespaceNotFoundError if target.nil?
|
101
|
+
# preflight checks for the command execution
|
102
|
+
# check_run
|
103
|
+
# check_target(params[:target], cfg_synth)
|
179
104
|
|
180
|
-
# targets
|
181
|
-
#
|
182
|
-
# runtype = nil
|
183
|
-
# environments = []
|
105
|
+
# targets = params[:target].split('.').map(&:to_sym)
|
106
|
+
# process_target(targets, cfg_synth)
|
184
107
|
|
185
|
-
|
186
|
-
#
|
187
|
-
#
|
108
|
+
###########################################################################
|
109
|
+
# modules
|
110
|
+
# modules can be fetched from git or local path
|
111
|
+
# modules can have a virtual environment to execute in
|
112
|
+
###########################################################################
|
188
113
|
|
189
|
-
#
|
114
|
+
# namespaces = cfg_synth[:namespace].keys.map(&:to_sym)
|
190
115
|
|
191
|
-
# namespaces.each do |
|
192
|
-
#
|
193
|
-
#
|
194
|
-
#
|
195
|
-
# next if sites.empty?
|
116
|
+
# namespaces.each do |namespace_name|
|
117
|
+
# namespace = cfg_synth[:namespace][namespace_name]
|
118
|
+
# context_names = namespace.keys.map(&:to_sym)
|
196
119
|
#
|
197
|
-
#
|
198
|
-
#
|
199
|
-
#
|
200
|
-
# end
|
201
|
-
#
|
202
|
-
# raise SiteNotFoundError unless site_names.include?(targets[1].to_sym)
|
203
|
-
#
|
204
|
-
# projects = config[:namespace][ns_name][e_name][:projects] || []
|
120
|
+
# context_names.each do |cn|
|
121
|
+
# context = namespace[cn]
|
122
|
+
# modules = context[:modules]
|
205
123
|
#
|
206
|
-
#
|
207
|
-
#
|
208
|
-
# project_names = []
|
209
|
-
# projects.each do |project|
|
210
|
-
# project_names << project[:name]
|
124
|
+
# modules.each do |mod|
|
125
|
+
# PangeaModule.process(mod)
|
211
126
|
# end
|
212
|
-
#
|
213
|
-
# raise ProjectNotFoundError \
|
214
|
-
# unless project_names
|
215
|
-
# .include?(
|
216
|
-
# targets[2].to_sym
|
217
|
-
# )
|
218
127
|
# end
|
219
128
|
# end
|
220
|
-
end
|
221
129
|
|
222
|
-
|
223
|
-
raise IncorrectSubcommandError unless correct_subcommand?(
|
224
|
-
params[:subcommand]
|
225
|
-
)
|
226
|
-
raise NoInfraTargetError unless params[:target]
|
227
|
-
end
|
130
|
+
###########################################################################
|
228
131
|
|
229
|
-
|
230
|
-
|
132
|
+
# provide some kind of default exit of the command execution
|
133
|
+
# exit
|
231
134
|
end
|
135
|
+
|
136
|
+
# process stage for target
|
137
|
+
# def process_target(targets, cfg_synth)
|
138
|
+
# namespaces = cfg_synth[:namespace].keys.map(&:to_sym)
|
139
|
+
# environments = []
|
140
|
+
#
|
141
|
+
# namespaces.each do |ns_name|
|
142
|
+
# environments.concat(cfg_synth[:namespace][ns_name].keys.map(&:to_sym))
|
143
|
+
# end
|
144
|
+
#
|
145
|
+
# case targets.length.to_i
|
146
|
+
# # only provided namespace
|
147
|
+
# when 1
|
148
|
+
# nil
|
149
|
+
# # only provided namespace.site
|
150
|
+
# when 2
|
151
|
+
# nil
|
152
|
+
# # only provided namespace.site.project
|
153
|
+
# when 3
|
154
|
+
# announce_preflight_info(targets, cfg_synth)
|
155
|
+
# environments.each do |e_name|
|
156
|
+
# projects = cfg_synth[:namespace][targets[0]][e_name][:projects]
|
157
|
+
# projects.each do |project|
|
158
|
+
# announce_project(project)
|
159
|
+
#
|
160
|
+
# synth = TerraformSynthesizer.new
|
161
|
+
# case project[:src][:type].to_sym
|
162
|
+
# when :local
|
163
|
+
# system %(mkdir -p #{CACHE_DIR}) unless Dir.exist?(CACHE_DIR)
|
164
|
+
# PROJECT_SRC_DIRS.each do |src_dir|
|
165
|
+
# next unless File.exist?(File.join(
|
166
|
+
# project[:src][:location].to_s,
|
167
|
+
# %(src),
|
168
|
+
# src_dir.to_s
|
169
|
+
# ))
|
170
|
+
#
|
171
|
+
# synth_files = Dir.glob("#{File.join(
|
172
|
+
# project[:src][:location].to_s,
|
173
|
+
# %(src),
|
174
|
+
# src_dir.to_s
|
175
|
+
# )}/**/*.rb")
|
176
|
+
# synth_files.each do |synth_file|
|
177
|
+
# synth.synthesize(File.read(synth_file))
|
178
|
+
# end
|
179
|
+
# end
|
180
|
+
#
|
181
|
+
# Say.terminal JSON.pretty_generate(synth.synthesis)
|
182
|
+
#
|
183
|
+
# project_cache_dir = File.join(CACHE_DIR, project[:name].to_s)
|
184
|
+
#
|
185
|
+
# system %(mkdir -p #{project_cache_dir}) unless Dir.exist?(project_cache_dir)
|
186
|
+
# File.write(File.join(project_cache_dir, ARTIFACT_FILE), synth.synthesis.to_json)
|
187
|
+
# system %(cd #{project_cache_dir} && terraform init)
|
188
|
+
# system %(cd #{project_cache_dir} && terraform plan)
|
189
|
+
#
|
190
|
+
# when :git
|
191
|
+
# nil
|
192
|
+
# end
|
193
|
+
# end
|
194
|
+
# end
|
195
|
+
#
|
196
|
+
# # fetch project data
|
197
|
+
# # projet_data = cfg_synth[:namespace][targets[0]]
|
198
|
+
# end
|
199
|
+
# end
|
200
|
+
|
201
|
+
# def announce_project(project)
|
202
|
+
# msg = []
|
203
|
+
# msg << %(project: #{project[:name]})
|
204
|
+
# msg << %(src: #{project[:src]})
|
205
|
+
# Say.terminal msg.map(&:strip).join(%(\n))
|
206
|
+
# end
|
207
|
+
|
208
|
+
# def announce_preflight_info(targets, cfg_synth)
|
209
|
+
# namespaces = cfg_synth[:namespace].keys.map(&:to_sym)
|
210
|
+
# environments = []
|
211
|
+
#
|
212
|
+
# namespaces.each do |ns_name|
|
213
|
+
# environments.concat(cfg_synth[:namespace][ns_name].keys.map(&:to_sym))
|
214
|
+
# end
|
215
|
+
#
|
216
|
+
# preflight_info = []
|
217
|
+
# preflight_info << %(environments: #{environments})
|
218
|
+
# preflight_info << %(\n)
|
219
|
+
# preflight_info << %(namespace: #{targets[0]})
|
220
|
+
# preflight_info << %(site: #{targets[1]})
|
221
|
+
# preflight_info << %(project: #{targets[2]})
|
222
|
+
#
|
223
|
+
# Say.terminal preflight_info.map(&:strip).join(%(\n))
|
224
|
+
# end
|
225
|
+
|
226
|
+
# targets can be...
|
227
|
+
# ${namespace}
|
228
|
+
# ${namespace}.${site}
|
229
|
+
# def check_target(target, config)
|
230
|
+
# # raise NamespaceNotFoundError if target.nil?
|
231
|
+
#
|
232
|
+
# # targets = target.split('.').map(&:to_sym)
|
233
|
+
# # namespaces = config[:namespace].keys.map(&:to_sym)
|
234
|
+
# # runtype = nil
|
235
|
+
# # environments = []
|
236
|
+
#
|
237
|
+
# # namespaces.each do |ns_name|
|
238
|
+
# # environments.concat(config[:namespace][ns_name].keys.map(&:to_sym))
|
239
|
+
# # end
|
240
|
+
#
|
241
|
+
# # raise NamespaceNotFoundError unless namespaces.include?(targets[0])
|
242
|
+
#
|
243
|
+
# # namespaces.each do |ns_name|
|
244
|
+
# # environments.each do |e_name|
|
245
|
+
# # sites = config[:namespace][ns_name][e_name][:sites] || []
|
246
|
+
# #
|
247
|
+
# # next if sites.empty?
|
248
|
+
# #
|
249
|
+
# # site_names = []
|
250
|
+
# # sites.each do |site|
|
251
|
+
# # site_names << site[:name]
|
252
|
+
# # end
|
253
|
+
# #
|
254
|
+
# # raise SiteNotFoundError unless site_names.include?(targets[1].to_sym)
|
255
|
+
# #
|
256
|
+
# # projects = config[:namespace][ns_name][e_name][:projects] || []
|
257
|
+
# #
|
258
|
+
# # next if projects.empty?
|
259
|
+
# #
|
260
|
+
# # project_names = []
|
261
|
+
# # projects.each do |project|
|
262
|
+
# # project_names << project[:name]
|
263
|
+
# # end
|
264
|
+
# #
|
265
|
+
# # raise ProjectNotFoundError \
|
266
|
+
# # unless project_names
|
267
|
+
# # .include?(
|
268
|
+
# # targets[2].to_sym
|
269
|
+
# # )
|
270
|
+
# # end
|
271
|
+
# # end
|
272
|
+
# end
|
273
|
+
|
274
|
+
# def check_run
|
275
|
+
# raise IncorrectSubcommandError unless correct_subcommand?(
|
276
|
+
# params[:subcommand]
|
277
|
+
# )
|
278
|
+
# raise NoInfraTargetError unless params[:target]
|
279
|
+
# end
|
280
|
+
|
281
|
+
# def correct_subcommand?(sbcmd)
|
282
|
+
# NAME.to_s.eql?(sbcmd.to_s)
|
283
|
+
# end
|
232
284
|
end
|
data/lib/pangea/modules.rb
CHANGED
@@ -5,6 +5,9 @@
|
|
5
5
|
# for terraform code.
|
6
6
|
###############################################################################
|
7
7
|
|
8
|
+
require %(terraform-synthesizer)
|
9
|
+
require %(bundler)
|
10
|
+
|
8
11
|
module PangeaBase
|
9
12
|
BASE_DIR = File.join(
|
10
13
|
Dir.home,
|
@@ -28,12 +31,60 @@ module PangeaRbenv
|
|
28
31
|
)
|
29
32
|
|
30
33
|
class << self
|
34
|
+
def versions_dir
|
35
|
+
VERSIONS_DIR
|
36
|
+
end
|
37
|
+
|
31
38
|
def rbenv_installed?
|
32
39
|
`which rbenv`.strip != ''
|
33
40
|
end
|
34
41
|
|
35
|
-
def rbenv_install(
|
42
|
+
def rbenv_install(version, path)
|
36
43
|
system %(mkdir -p #{VERSIONS_DIR}) unless Dir.exist?(VERSIONS_DIR)
|
44
|
+
if rbenv_installed? && !Dir.exist?(File.join(path.to_s))
|
45
|
+
system [BIN, %(install), version.to_s, path.to_s].join(%( ))
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
module PangeaRubyBuild
|
52
|
+
include PangeaBase
|
53
|
+
BIN = %(ruby-build).freeze
|
54
|
+
RUBY_BUILD_DIR = File.join(
|
55
|
+
BASE_DIR,
|
56
|
+
%(rbenv)
|
57
|
+
)
|
58
|
+
class << self
|
59
|
+
def ruby_build_installed?
|
60
|
+
`which rbenv`.strip != ''
|
61
|
+
end
|
62
|
+
|
63
|
+
def ruby_build(version, path)
|
64
|
+
system %(mkdir -p #{PangeaRbenv.versions_dir}) unless Dir.exist?(PangeaRbenv.versions_dir)
|
65
|
+
system [BIN, version.to_s, path.to_s].join(%( )) if ruby_build_installed? && !Dir.exist?(File.join(path.to_s))
|
66
|
+
end
|
67
|
+
|
68
|
+
def gem_install(gem, ruby_version, gem_version, gemset_path)
|
69
|
+
gem_path = File.join(gemset_path, %(lib), %(ruby), %(gems), ruby_version.to_s, %(gems), %(#{gem}-#{gem_version}))
|
70
|
+
unless Dir.exist?(gem_path)
|
71
|
+
gembin = File.join(gemset_path, %(bin), %(gem))
|
72
|
+
system [gembin, %(install), gem.to_s.strip, %(-v), gem_version.to_s].join(%( ))
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def bundle_install(mpath, gemset_path)
|
77
|
+
@bundlebin = File.join(gemset_path, %(bin), %(bundle))
|
78
|
+
bundlehint = File.join(gemset_path, %(bundle_hint))
|
79
|
+
unless File.exist?(bundlehint)
|
80
|
+
cmd = [
|
81
|
+
# %(cd #{mpath} &&),
|
82
|
+
%(BUNDLE_GEMFILE=#{File.join(mpath, %(Gemfile))}), @bundlebin,
|
83
|
+
%(install)
|
84
|
+
].join(%( ))
|
85
|
+
system cmd
|
86
|
+
system [%(touch), bundlehint].join(%( ))
|
87
|
+
end
|
37
88
|
end
|
38
89
|
end
|
39
90
|
end
|
@@ -51,15 +102,33 @@ module PangeaModule
|
|
51
102
|
%(rubies)
|
52
103
|
)
|
53
104
|
|
54
|
-
# SECTIONS = %i[
|
55
|
-
# lib
|
56
|
-
# src
|
57
|
-
# ].freeze
|
58
|
-
|
59
105
|
class << self
|
106
|
+
def symbolize(hash)
|
107
|
+
JSON[JSON[hash], symbolize_names: true]
|
108
|
+
end
|
109
|
+
|
110
|
+
def terraform_synth
|
111
|
+
@terraform_synth ||= TerraformSynthesizer.new
|
112
|
+
end
|
113
|
+
|
60
114
|
# entrypoint for module processing
|
61
115
|
def process(mod)
|
62
|
-
|
116
|
+
mod = symbolize(mod)
|
117
|
+
if mod.fetch(:sandboxed)
|
118
|
+
|
119
|
+
name = mod.fetch(:name)
|
120
|
+
|
121
|
+
raise ArgumentError, %(name cannot be nil) if name.nil?
|
122
|
+
|
123
|
+
# understanding that module entrypoint loading
|
124
|
+
# will work with #{context}-#{name}
|
125
|
+
context = mod.fetch(:context, %(pangea-component))
|
126
|
+
require_name = %(#{context}-#{name})
|
127
|
+
|
128
|
+
require require_name
|
129
|
+
puts render
|
130
|
+
puts %(end)
|
131
|
+
end
|
63
132
|
end
|
64
133
|
end
|
65
134
|
end
|
data/lib/pangea/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pangea
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.38
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- drzthslnt@gmail.com
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-11-
|
11
|
+
date: 2023-11-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubocop-rspec
|