paneron-register 0.2.0 → 0.3.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
- data/.irbrc +1 -0
- data/.pryrc +1 -0
- data/README.adoc +163 -19
- data/docs/examples.adoc +91 -0
- data/lib/paneron/register/hierarchical.rb +24 -0
- data/lib/paneron/register/raw/data_set.rb +349 -34
- data/lib/paneron/register/raw/item.rb +147 -23
- data/lib/paneron/register/raw/item_class.rb +140 -23
- data/lib/paneron/register/raw/register.rb +452 -63
- data/lib/paneron/register/register.rb +0 -2
- data/lib/paneron/register/root_finder.rb +24 -0
- data/lib/paneron/register/validatable.rb +40 -0
- data/lib/paneron/register/version.rb +1 -1
- data/lib/paneron/register/writeable.rb +96 -0
- data/lib/paneron/register.rb +5 -0
- data/paneron-register.gemspec +1 -0
- metadata +21 -2
@@ -1,21 +1,286 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "yaml"
|
4
|
+
require "set"
|
4
5
|
|
5
6
|
module Paneron
|
6
7
|
module Register
|
7
8
|
module Raw
|
8
9
|
class Register
|
9
|
-
|
10
|
+
include Writeable
|
11
|
+
include Validatable
|
10
12
|
|
11
|
-
|
12
|
-
|
13
|
+
attr_reader :git_client, :git_url, :git_branch, :git_remote_name
|
14
|
+
attr_accessor :register_path
|
15
|
+
|
16
|
+
def initialize(
|
17
|
+
register_path,
|
18
|
+
git_url: nil,
|
19
|
+
update_git: nil,
|
20
|
+
git_remote_name: nil,
|
21
|
+
git_branch: nil
|
22
|
+
)
|
23
|
+
@old_git_url = @git_url = git_url
|
13
24
|
@register_path = register_path
|
14
|
-
|
15
|
-
|
16
|
-
|
25
|
+
setup_git(
|
26
|
+
git_url: git_url,
|
27
|
+
path: register_path,
|
28
|
+
git_remote_name: git_remote_name,
|
29
|
+
git_branch: git_branch,
|
30
|
+
update: update_git,
|
31
|
+
)
|
32
|
+
|
33
|
+
@old_path = @register_path
|
17
34
|
@data_sets = {}
|
35
|
+
@item_classes = {}
|
36
|
+
@items = {}
|
18
37
|
@metadata = nil
|
38
|
+
@git_save_fn = proc {}
|
39
|
+
end
|
40
|
+
|
41
|
+
# Defer all mkdir until #save_sequence
|
42
|
+
def setup_git(
|
43
|
+
git_url: nil,
|
44
|
+
path: nil,
|
45
|
+
git_remote_name: nil,
|
46
|
+
git_branch: nil,
|
47
|
+
update: nil
|
48
|
+
)
|
49
|
+
require "git"
|
50
|
+
self.class.setup_cache_path
|
51
|
+
|
52
|
+
@git_remote_name = if git_remote_name.nil? || git_remote_name.empty?
|
53
|
+
"origin"
|
54
|
+
else
|
55
|
+
git_remote_name
|
56
|
+
end
|
57
|
+
|
58
|
+
@git_branch = if git_branch.nil? || git_branch.empty?
|
59
|
+
"main"
|
60
|
+
else
|
61
|
+
git_branch
|
62
|
+
end
|
63
|
+
|
64
|
+
if git_url.nil? && path.nil?
|
65
|
+
raise Paneron::Register::Error,
|
66
|
+
"Must supply either git_url or path."
|
67
|
+
end
|
68
|
+
|
69
|
+
repo_path = if path.nil?
|
70
|
+
self.class.calculate_repo_cache_path(git_url)
|
71
|
+
else
|
72
|
+
path
|
73
|
+
end
|
74
|
+
|
75
|
+
#------------------------------------
|
76
|
+
# | dir | Git.open(dir)
|
77
|
+
# no |exists |
|
78
|
+
# git |-------|----------------------
|
79
|
+
# url | dir | mkdirp &&
|
80
|
+
# |!exists| Git.open(dir) ? Git.init(dir)
|
81
|
+
#------------------------------------
|
82
|
+
# | dir | Git.open(dir) &&
|
83
|
+
# has |exists | remote? ? check remote : add remote
|
84
|
+
# git |-------|----------------------
|
85
|
+
# url | dir | Git.clone(url, dir) ||
|
86
|
+
# |!exists| mkdirp && Git.open(dir) ? Git.init(dir) &&
|
87
|
+
# | | add remote
|
88
|
+
#------------------------------------
|
89
|
+
|
90
|
+
if git_url.nil?
|
91
|
+
if File.exist?(repo_path)
|
92
|
+
# No remote, but local repo path exists.
|
93
|
+
# Simply open it as a Git repo.
|
94
|
+
@git_save_fn = nil
|
95
|
+
|
96
|
+
begin
|
97
|
+
@git_client = self.class.open_git_repo(repo_path)
|
98
|
+
log_change_git_remote(nil)
|
99
|
+
change_git_remote(nil)
|
100
|
+
rescue ArgumentError => e
|
101
|
+
if /not in a git working tree/.match?(e.message)
|
102
|
+
@git_save_fn = proc {
|
103
|
+
@git_client = self.class.init_git_repo(repo_path,
|
104
|
+
initial_branch: @git_branch)
|
105
|
+
log_change_git_remote(nil)
|
106
|
+
change_git_remote(nil)
|
107
|
+
}
|
108
|
+
else
|
109
|
+
raise e
|
110
|
+
end
|
111
|
+
end
|
112
|
+
else
|
113
|
+
# No remote, and local repo path does not exist.
|
114
|
+
git_init_fn = proc {
|
115
|
+
FileUtils.mkdir_p(repo_path)
|
116
|
+
@git_client = self.class.init_git_repo(repo_path, initial_branch: @git_branch)
|
117
|
+
log_change_git_remote(nil)
|
118
|
+
change_git_remote(nil)
|
119
|
+
}
|
120
|
+
|
121
|
+
# Defer creation of directory until #save_sequence
|
122
|
+
@git_client = nil
|
123
|
+
@git_save_fn = git_init_fn
|
124
|
+
|
125
|
+
end
|
126
|
+
elsif File.exist?(repo_path)
|
127
|
+
# Has remote, as well as local repo path.
|
128
|
+
@git_save_fn = nil
|
129
|
+
|
130
|
+
git_fn = proc {
|
131
|
+
# Check if remote matches the provided git_url
|
132
|
+
if !@git_client.remote(@git_remote_name).url.nil? && @git_client.remote(@git_remote_name).url != git_url
|
133
|
+
|
134
|
+
raise Paneron::Register::Error,
|
135
|
+
"Git remote @ #{clone_path} already exists " \
|
136
|
+
"(#{@git_client.remote(@git_remote_name).url}) " \
|
137
|
+
"but does not match provided URL (#{git_url}).\n" \
|
138
|
+
"Instead, use `r = #{self}.new(\"#{path}\")` and "\
|
139
|
+
"`r.git_url = \"#{git_url}\"` to change its Git URL."
|
140
|
+
end
|
141
|
+
log_change_git_remote(git_url)
|
142
|
+
change_git_remote(git_url)
|
143
|
+
|
144
|
+
# Pull-rebase to update it
|
145
|
+
if update
|
146
|
+
@git_client.pull(
|
147
|
+
nil, nil, rebase: true
|
148
|
+
)
|
149
|
+
end
|
150
|
+
}
|
151
|
+
|
152
|
+
begin
|
153
|
+
@git_client = self.class.open_git_repo(repo_path)
|
154
|
+
git_fn.call
|
155
|
+
rescue ArgumentError => e
|
156
|
+
if /not in a git working tree/.match?(e.message)
|
157
|
+
@git_save_fn = proc {
|
158
|
+
@git_client = self.class.init_git_repo(repo_path,
|
159
|
+
initial_branch: @git_branch)
|
160
|
+
git_fn.call
|
161
|
+
}
|
162
|
+
else
|
163
|
+
raise e
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
else
|
168
|
+
git_clone_fn = proc {
|
169
|
+
begin
|
170
|
+
@git_client = self.class.clone_git_repo(git_url, repo_path)
|
171
|
+
change_git_remote(git_url)
|
172
|
+
rescue Git::TimeoutError => e
|
173
|
+
e.result.tap do |_r|
|
174
|
+
warn "Timed out trying to clone #{repo_url}."
|
175
|
+
raise e
|
176
|
+
end
|
177
|
+
end
|
178
|
+
}
|
179
|
+
|
180
|
+
# rubocop:disable Style/IdenticalConditionalBranches
|
181
|
+
# URL changed. Use save fn.
|
182
|
+
if git_url_changed?(git_url)
|
183
|
+
log_change_git_remote(git_url)
|
184
|
+
@git_client = nil
|
185
|
+
@git_save_fn = git_clone_fn
|
186
|
+
else
|
187
|
+
# Path is nil. Clone repo.
|
188
|
+
log_change_git_remote(git_url)
|
189
|
+
@git_save_fn = nil
|
190
|
+
git_clone_fn.call
|
191
|
+
end
|
192
|
+
# rubocop:enable Style/IdenticalConditionalBranches
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
def register_yaml_path
|
197
|
+
File.join(register_path,
|
198
|
+
REGISTER_METADATA_FILENAME)
|
199
|
+
end
|
200
|
+
|
201
|
+
def parent; nil; end
|
202
|
+
|
203
|
+
def self.name
|
204
|
+
"Register"
|
205
|
+
end
|
206
|
+
|
207
|
+
def save_sequence
|
208
|
+
# Save self
|
209
|
+
require "fileutils"
|
210
|
+
|
211
|
+
# Move old register to new path
|
212
|
+
if File.directory?(@old_path) && @old_path != self_path
|
213
|
+
FileUtils.mv(@old_path, self_path)
|
214
|
+
@old_path = self_path
|
215
|
+
else
|
216
|
+
FileUtils.mkdir_p(self_path)
|
217
|
+
end
|
218
|
+
|
219
|
+
if @git_client.nil?
|
220
|
+
@git_save_fn.call
|
221
|
+
end
|
222
|
+
|
223
|
+
if @metadata.nil? || @metadata.empty?
|
224
|
+
File.write(register_yaml_path, self.class.metadata_template.to_yaml)
|
225
|
+
else
|
226
|
+
File.write(register_yaml_path, metadata.to_yaml)
|
227
|
+
end
|
228
|
+
|
229
|
+
# Save data sets
|
230
|
+
data_set_names.each do |data_set_name|
|
231
|
+
new_thing = data_sets(data_set_name)
|
232
|
+
new_thing.register = self
|
233
|
+
new_thing.save
|
234
|
+
end
|
235
|
+
# else
|
236
|
+
# raise Paneron::Register::Error, "Register is not valid"
|
237
|
+
# end
|
238
|
+
end
|
239
|
+
|
240
|
+
def title=(new_title)
|
241
|
+
metadata["title"] = new_title.to_s
|
242
|
+
end
|
243
|
+
|
244
|
+
def title
|
245
|
+
metadata["title"]
|
246
|
+
end
|
247
|
+
|
248
|
+
def self_path
|
249
|
+
register_path
|
250
|
+
end
|
251
|
+
|
252
|
+
# TODO: Expand validation to include data set metadata?
|
253
|
+
# TODO: What is considered valid?
|
254
|
+
def is_valid?
|
255
|
+
true
|
256
|
+
end
|
257
|
+
|
258
|
+
def add_data_sets(*new_data_sets)
|
259
|
+
new_data_sets = [new_data_sets] unless new_data_sets.is_a?(Enumerable)
|
260
|
+
new_data_sets.each do |data_set|
|
261
|
+
data_set.set_register(self)
|
262
|
+
@data_sets[data_set.data_set_name] = data_set
|
263
|
+
metadata["datasets"].merge!(
|
264
|
+
{ data_set.data_set_name => true },
|
265
|
+
)
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
def spawn_data_set(
|
270
|
+
data_set_name,
|
271
|
+
metadata: {},
|
272
|
+
paneron_metadata: {}
|
273
|
+
)
|
274
|
+
new_data_set = Paneron::Register::Raw::DataSet.new(
|
275
|
+
File.join(register_path, data_set_name),
|
276
|
+
register: self,
|
277
|
+
)
|
278
|
+
|
279
|
+
new_data_set.merge_metadata(metadata)
|
280
|
+
new_data_set.merge_paneron_metadata(paneron_metadata)
|
281
|
+
add_data_sets(new_data_set)
|
282
|
+
|
283
|
+
new_data_set
|
19
284
|
end
|
20
285
|
|
21
286
|
def self.local_cache_path
|
@@ -27,7 +292,7 @@ module Paneron
|
|
27
292
|
)
|
28
293
|
else
|
29
294
|
File.join(
|
30
|
-
Dir.exist?(ENV["XDG_CACHE_HOME"]) ? ENV["XDG_CACHE_HOME"] : "~/.cache",
|
295
|
+
Dir.exist?(ENV["XDG_CACHE_HOME"].to_s) ? ENV["XDG_CACHE_HOME"] : "~/.cache",
|
31
296
|
"ruby-paneron-register",
|
32
297
|
)
|
33
298
|
end
|
@@ -47,59 +312,64 @@ module Paneron
|
|
47
312
|
Base64.encode64(digest).tr("+/= ", "_-")[0..16]
|
48
313
|
end
|
49
314
|
|
50
|
-
|
51
|
-
|
52
|
-
|
315
|
+
# Basically .new but calls #save at the end
|
316
|
+
def self.generate(
|
317
|
+
register_path,
|
318
|
+
git_url: nil,
|
319
|
+
git_branch: nil,
|
320
|
+
git_remote_name: nil
|
321
|
+
)
|
322
|
+
new(
|
323
|
+
register_path,
|
324
|
+
git_url: git_url,
|
325
|
+
git_branch: git_branch,
|
326
|
+
git_remote_name: git_remote_name,
|
327
|
+
).save
|
328
|
+
end
|
329
|
+
|
330
|
+
def self.calculate_repo_cache_name(repo_url)
|
331
|
+
"#{File.basename(repo_url)}-#{calculate_repo_cache_hash(repo_url)}"
|
332
|
+
end
|
333
|
+
|
334
|
+
def self.calculate_repo_cache_path(repo_url)
|
53
335
|
repo_cache_name =
|
54
|
-
|
336
|
+
calculate_repo_cache_name(repo_url)
|
55
337
|
|
56
338
|
# Check if repo is already cloned
|
57
|
-
|
58
|
-
|
59
|
-
if File.exist?(full_local_cache_path)
|
60
|
-
_g = Git.open(full_local_cache_path)
|
339
|
+
File.join(local_cache_path, repo_cache_name)
|
340
|
+
end
|
61
341
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
nil, nil, rebase: true
|
66
|
-
)
|
67
|
-
end
|
68
|
-
_g
|
69
|
-
else
|
70
|
-
Git.clone(
|
71
|
-
repo_url,
|
72
|
-
repo_cache_name,
|
73
|
-
path: local_cache_path,
|
74
|
-
# timeout: 30,
|
75
|
-
)
|
76
|
-
end
|
77
|
-
rescue Git::TimeoutError => e
|
78
|
-
e.result.tap do |_r|
|
79
|
-
warn "Timed out trying to clone #{repo_url}."
|
80
|
-
raise e
|
81
|
-
end
|
82
|
-
end
|
342
|
+
def git_url=(new_url)
|
343
|
+
setup_git(git_url: new_url, path: self_path)
|
344
|
+
end
|
83
345
|
|
84
|
-
|
346
|
+
def self.from_git(repo_url, path: nil, update: true)
|
347
|
+
new(path, git_url: repo_url, update_git: true)
|
85
348
|
end
|
86
349
|
|
87
350
|
REGISTER_METADATA_FILENAME = "/paneron.yaml"
|
88
351
|
|
89
|
-
def self.
|
90
|
-
|
352
|
+
def self.validate_path_before_saving
|
353
|
+
false
|
354
|
+
end
|
355
|
+
|
356
|
+
def self.validate_path(path)
|
357
|
+
unless File.exist?(path)
|
91
358
|
raise Paneron::Register::Error,
|
92
|
-
"
|
359
|
+
"#{name} path (#{path}) does not exist"
|
93
360
|
end
|
94
|
-
|
361
|
+
|
362
|
+
unless File.directory?(path)
|
95
363
|
raise Paneron::Register::Error,
|
96
|
-
"
|
364
|
+
"#{name} path (#{path}) is not a directory"
|
97
365
|
end
|
98
|
-
|
99
|
-
|
100
|
-
|
366
|
+
|
367
|
+
register_file = File.join(
|
368
|
+
path, REGISTER_METADATA_FILENAME
|
369
|
+
)
|
370
|
+
unless File.exist?(register_file)
|
101
371
|
raise Paneron::Register::Error,
|
102
|
-
"Register metadata file does not exist"
|
372
|
+
"Register metadata file (#{register_file}) does not exist"
|
103
373
|
end
|
104
374
|
end
|
105
375
|
|
@@ -110,16 +380,21 @@ module Paneron
|
|
110
380
|
)
|
111
381
|
end
|
112
382
|
|
113
|
-
def data_set_names
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
383
|
+
def data_set_names(refresh: false)
|
384
|
+
if refresh || @data_sets.empty?
|
385
|
+
Dir.glob(
|
386
|
+
File.join(
|
387
|
+
register_path,
|
388
|
+
"*#{Paneron::Register::Raw::DataSet::DATA_SET_METADATA_FILENAME}",
|
389
|
+
),
|
390
|
+
)
|
391
|
+
.map do |file|
|
121
392
|
File.basename(File.dirname(file))
|
122
|
-
end
|
393
|
+
end.to_set
|
394
|
+
else
|
395
|
+
@data_sets.keys
|
396
|
+
end
|
397
|
+
# @data_set_names ||= Dir.glob(
|
123
398
|
end
|
124
399
|
|
125
400
|
def data_set_path(data_set_name)
|
@@ -127,27 +402,141 @@ module Paneron
|
|
127
402
|
end
|
128
403
|
|
129
404
|
def metadata
|
130
|
-
@metadata ||=
|
405
|
+
@metadata ||= begin
|
406
|
+
YAML.safe_load_file(
|
407
|
+
register_yaml_path,
|
408
|
+
permitted_classes: [Time, Date, DateTime],
|
409
|
+
)
|
410
|
+
rescue Errno::ENOENT
|
411
|
+
self.class.metadata_template
|
412
|
+
end
|
413
|
+
end
|
414
|
+
|
415
|
+
def metadata=(metadata)
|
416
|
+
@metadata = metadata
|
131
417
|
end
|
132
418
|
|
133
|
-
def data_sets(data_set_name = nil)
|
419
|
+
def data_sets(data_set_name = nil, refresh: false)
|
134
420
|
if data_set_name.nil?
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
421
|
+
@data_sets = if !refresh && !@data_sets.empty?
|
422
|
+
@data_sets
|
423
|
+
else
|
424
|
+
data_set_names(refresh: refresh).reduce({}) do |acc, data_set_name|
|
425
|
+
acc[data_set_name] = data_sets(data_set_name)
|
426
|
+
acc
|
427
|
+
end
|
428
|
+
end
|
429
|
+
elsif refresh
|
430
|
+
data_sets(refresh: true)[data_set_name]
|
139
431
|
else
|
140
432
|
@data_sets[data_set_name] ||=
|
141
|
-
Paneron::Register::Raw::DataSet.new(
|
142
|
-
|
433
|
+
Paneron::Register::Raw::DataSet.new(
|
434
|
+
File.join(register_path, data_set_name),
|
435
|
+
register: self,
|
436
|
+
)
|
143
437
|
end
|
144
438
|
end
|
145
439
|
|
440
|
+
# @return Hash of { data_set_name => { item_class_name => ItemClass }}
|
441
|
+
# - ["data_set_name"]["item_class_name"]
|
442
|
+
def item_classes(data_set_name = nil, item_class_name = nil, refresh: false)
|
443
|
+
if data_set_name.nil? && item_class_name.nil?
|
444
|
+
@item_classes = if !refresh && !@item_classes.empty?
|
445
|
+
@item_classes
|
446
|
+
else
|
447
|
+
data_sets.reduce({}) do |acc, (ddata_set_name, data_set)|
|
448
|
+
acc[ddata_set_name] ||= {}
|
449
|
+
data_set.item_class_names.each do |item_klass_name|
|
450
|
+
acc[ddata_set_name][item_klass_name] =
|
451
|
+
item_classes(ddata_set_name, item_klass_name)
|
452
|
+
end
|
453
|
+
acc
|
454
|
+
end
|
455
|
+
end
|
456
|
+
elsif item_class_name.nil?
|
457
|
+
item_classes(refresh: refresh)[data_set_name]
|
458
|
+
elsif refresh
|
459
|
+
item_classes(refresh: true)[data_set_name][item_class_name]
|
460
|
+
else
|
461
|
+
@item_classes[data_set_name] ||= {}
|
462
|
+
@item_classes[data_set_name][item_class_name] ||=
|
463
|
+
Paneron::Register::Raw::ItemClass.new(
|
464
|
+
File.join(data_set_path(data_set_name), item_class_name),
|
465
|
+
data_set: data_sets[data_set_name],
|
466
|
+
)
|
467
|
+
end
|
468
|
+
end
|
469
|
+
|
470
|
+
# @return Hash of { item_uuid => Item }
|
471
|
+
# - ["uuid"]
|
472
|
+
def items(item_uuid = nil, refresh: false)
|
473
|
+
@items = if !refresh && !@items.empty?
|
474
|
+
@items
|
475
|
+
else
|
476
|
+
data_sets(refresh: refresh).reduce({}) do |acc, (_ddata_set_name, data_set)|
|
477
|
+
data_set.items.each do |iitem_uuid, item|
|
478
|
+
acc[iitem_uuid] = item
|
479
|
+
end
|
480
|
+
acc
|
481
|
+
end
|
482
|
+
end
|
483
|
+
|
484
|
+
if item_uuid.nil?
|
485
|
+
@items
|
486
|
+
else
|
487
|
+
@items[item_uuid]
|
488
|
+
end
|
489
|
+
end
|
490
|
+
|
491
|
+
def self.metadata_template
|
492
|
+
{
|
493
|
+
"title" => "",
|
494
|
+
"datasets" => {
|
495
|
+
# "data-set-1" => true,
|
496
|
+
},
|
497
|
+
}
|
498
|
+
end
|
499
|
+
|
500
|
+
private
|
501
|
+
|
502
|
+
def log_change_git_remote(new_url)
|
503
|
+
@old_git_url = @git_url
|
504
|
+
@git_url = new_url
|
505
|
+
end
|
506
|
+
|
507
|
+
def change_git_remote(new_url, git_client: @git_client)
|
508
|
+
if !git_client.remote(@git_remote_name).url.nil?
|
509
|
+
git_client.remove_remote(@git_remote_name)
|
510
|
+
if !new_url.nil?
|
511
|
+
git_client.add_remote(@git_remote_name)
|
512
|
+
end
|
513
|
+
end
|
514
|
+
end
|
515
|
+
|
516
|
+
def git_url_changed?(url = @git_url)
|
517
|
+
@old_git_url != url
|
518
|
+
end
|
519
|
+
|
146
520
|
def data_set_lutamls
|
147
521
|
data_sets.map do |_data_set_name, data_set|
|
148
522
|
data_set.to_lutaml
|
149
523
|
end
|
150
524
|
end
|
525
|
+
|
526
|
+
# For abstraction
|
527
|
+
class << self
|
528
|
+
def clone_git_repo(git_url, repo_path)
|
529
|
+
Git.clone(git_url, repo_path)
|
530
|
+
end
|
531
|
+
|
532
|
+
def open_git_repo(repo_path)
|
533
|
+
Git.open(repo_path)
|
534
|
+
end
|
535
|
+
|
536
|
+
def init_git_repo(repo_path, initial_branch: nil)
|
537
|
+
Git.init(repo_path, initial_branch: initial_branch)
|
538
|
+
end
|
539
|
+
end
|
151
540
|
end
|
152
541
|
end
|
153
542
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Paneron
|
4
|
+
module Register
|
5
|
+
module RootFinder
|
6
|
+
# def self.included(base)
|
7
|
+
# base.class_eval do
|
8
|
+
# end
|
9
|
+
# end
|
10
|
+
|
11
|
+
def register
|
12
|
+
parent.register
|
13
|
+
end
|
14
|
+
|
15
|
+
def git_client
|
16
|
+
parent.git_client
|
17
|
+
end
|
18
|
+
|
19
|
+
def git_url
|
20
|
+
parent.git_url
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Paneron
|
4
|
+
module Register
|
5
|
+
module Validatable
|
6
|
+
# def self.included(base)
|
7
|
+
# base.class_eval do
|
8
|
+
# end
|
9
|
+
# end
|
10
|
+
|
11
|
+
def path_valid?
|
12
|
+
self.class.validate_path(self_path)
|
13
|
+
true
|
14
|
+
rescue Paneron::Register::Error => e
|
15
|
+
errors << e.message
|
16
|
+
warn "#{self.class.name} is not path-valid:\n#{errors.map do |e|
|
17
|
+
" - #{e}"
|
18
|
+
end.join("\n")}"
|
19
|
+
false
|
20
|
+
end
|
21
|
+
|
22
|
+
def valid?
|
23
|
+
@errors = []
|
24
|
+
# Taking advantage of side-effects in #is_valid?
|
25
|
+
# before validate_path happens:
|
26
|
+
is_valid?
|
27
|
+
rescue Paneron::Register::Error => e
|
28
|
+
errors << e.message
|
29
|
+
warn "#{self.class.name} is not valid:\n#{errors.map do |e|
|
30
|
+
" - #{e}"
|
31
|
+
end.join("\n")}"
|
32
|
+
false
|
33
|
+
end
|
34
|
+
|
35
|
+
def errors
|
36
|
+
@errors ||= []
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|