docker-template 0.8.0 → 0.10.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.
@@ -1,8 +1,6 @@
1
- # ----------------------------------------------------------------------------
2
1
  # Frozen-string-literal: true
3
2
  # Copyright: 2015 - 2016 Jordon Bedwell - Apache v2.0 License
4
3
  # Encoding: utf-8
5
- # ----------------------------------------------------------------------------
6
4
 
7
5
  require "active_support/inflector"
8
6
  require "active_support/core_ext/hash/indifferent_access"
@@ -10,46 +8,84 @@ require "yaml"
10
8
 
11
9
  module Docker
12
10
  module Template
13
- class Metadata
14
- attr_reader :data
11
+ class Meta
15
12
  extend Forwardable::Extended
13
+ attr_reader :data
16
14
 
17
- # ----------------------------------------------------------------------
15
+ # --
18
16
  # rubocop:disable Style/MultilineBlockLayout
19
- # ----------------------------------------------------------------------
17
+ # --
20
18
 
21
- OPTS_FILE = "opts.yml"
22
- [Pathutil.allowed[:yaml][:classes], Array.allowed[:keys], \
23
- Hash.allowed[:vals]].each do |v| v.push(
24
- self, HashWithIndifferentAccess, Regexp
25
- )
19
+ [Pathutil.allowed[:yaml][:classes], Array.allowed[:keys],
20
+ Hash.allowed[:vals]].each do |v|
21
+
22
+ v.push(self,
23
+ HashWithIndifferentAccess, Regexp
24
+ )
26
25
  end
27
26
 
28
- # ----------------------------------------------------------------------
27
+ # --
29
28
  # rubocop:enable Style/MultilineBlockLayout
30
- # ----------------------------------------------------------------------
29
+ # --
31
30
 
32
31
  DEFAULTS = HashWithIndifferentAccess.new({
33
- "log_filters" => [],
32
+ "squash" => true,
33
+ "startup" => true,
34
+ "aliases" => {},
34
35
  "push" => false,
36
+ "build" => true,
35
37
  "cache" => false,
36
38
  "type" => "normal",
37
- "user" => "random_user",
38
39
  "local_prefix" => "local",
39
- "rootfs_base_img" => "envygeeks/ubuntu",
40
+ "project_data_dir" => "docker",
41
+ "rootfs_base_img" => "envygeeks/alpine",
40
42
  "maintainer" => "Random User <random.user@example.com>",
43
+ "user" => ENV["USER"] || ENV["USERNAME"] || "random",
41
44
  "name" => Template.root.basename.to_s,
45
+ "project_copy_dir" => "project",
42
46
  "rootfs_template" => "alpine",
43
47
  "cache_dir" => "cache",
44
48
  "repos_dir" => "repos",
45
49
  "copy_dir" => "copy",
46
50
  "tag" => "latest",
47
- "clean" => true,
51
+ "clean" => false,
48
52
  "tty" => false,
49
- "tags" => {}
53
+ "tags" => {},
54
+
55
+ #
56
+
57
+ "log_filters" => [
58
+ /^The push refers to a repository/,
59
+ /\sdigest: sha256:/
60
+ ],
61
+
62
+ #
63
+
64
+ "project_copy_ignore" => %w(
65
+ .git
66
+ .bundle
67
+ Dockerfile
68
+ vendor/bundle
69
+ .gitattributes
70
+ .node_modules
71
+ .gitignore
72
+ docker
73
+ tmp
74
+ log
75
+ ),
50
76
  }).freeze
51
77
 
52
- # ----------------------------------------------------------------------
78
+ # --
79
+
80
+ class << self
81
+ def opts_file(force: nil)
82
+ if force == :project || Template.project?
83
+ then "docker/template.yml" else "opts.yml"
84
+ end
85
+ end
86
+ end
87
+
88
+ # --
53
89
  # @param data [Hash, self.class] - the main data.
54
90
  # @param root [Hash, self.class] - the root data.
55
91
  # Create a new instance of `self.class`.
@@ -59,70 +95,100 @@ module Docker
59
95
  # :hello => :world
60
96
  # })
61
97
  # ```
62
- # ----------------------------------------------------------------------
98
+ # --
63
99
  # rubocop:disable Metrics/AbcSize
64
- # ----------------------------------------------------------------------
100
+ # --
65
101
 
66
102
  def initialize(overrides, root: nil)
67
- if root.is_a?(self.class)
68
- then root = root.to_h({
69
- :raw => true
70
- })
71
- end
72
-
73
- if overrides.is_a?(self.class)
74
- then overrides = overrides.to_h({
75
- :raw => true
76
- })
77
- end
103
+ overrides = overrides.to_h :raw => true if overrides.is_a?(self.class)
104
+ root = root.to_h :raw => true if root.is_a?(self.class)
78
105
 
79
106
  if root.nil?
80
- overrides = overrides.stringify
81
- gdata = Template.root.join(OPTS_FILE).read_yaml
82
- @data = DEFAULTS.deep_merge(gdata.stringify).deep_merge(overrides)
83
- tdata = Template.root.join(@data[:repos_dir], @data[:name], OPTS_FILE).read_yaml
84
- @data = @data.deep_merge(tdata.stringify).deep_merge(overrides)
85
- @data = @data.stringify.with_indifferent_access
107
+ if Template.project?
108
+ load_project_config(
109
+ overrides
110
+ )
111
+
112
+ else
113
+ load_normal_config(
114
+ overrides
115
+ )
116
+ end
86
117
 
118
+ @root = true
87
119
  else
88
120
  @data = overrides.stringify.with_indifferent_access
89
- @root_data = root.stringify \
90
- .with_indifferent_access
121
+ @root_data = root.stringify.with_indifferent_access
91
122
  end
123
+
124
+ debug!
125
+ normalize!
126
+ return
92
127
  end
93
128
 
94
- # ----------------------------------------------------------------------
95
- # rubocop:enable Metrics/AbcSize
96
- # ----------------------------------------------------------------------
129
+ # --
97
130
 
98
- def _shas
99
- return @_shas ||= begin
100
- self.class.new(Template.gem_root.join("shas.yml").read_yaml, {
101
- :root => root_data
131
+ def normalize!
132
+ if root?
133
+ opts = {
134
+ :allowed_keys => [],
135
+ :allowed_vals => []
136
+ }
137
+
138
+ merge!({
139
+ "tags" => @data[ "tags"].stringify(**opts),
140
+ "aliases" => @data["aliases"].stringify(**opts)
102
141
  })
103
142
  end
104
143
  end
105
144
 
106
- # ----------------------------------------------------------------------
145
+ # --
146
+
147
+ def debug!
148
+ if root? && root_data["debug"]
149
+ if !key?(:env) || self[:env].queryable?
150
+ self[:env] ||= {}
151
+
152
+ merge!({
153
+ :env => {
154
+ :all => {
155
+ :DEBUG => true
156
+ }
157
+ }
158
+ })
159
+ end
160
+ end
161
+ end
162
+
163
+ # --
107
164
 
108
165
  def root_data
109
166
  return @root_data || @data
110
167
  end
111
168
 
112
- # ----------------------------------------------------------------------
169
+ # --
113
170
 
114
171
  def root
115
- Template.root.join(
116
- root_data[:repos_dir], root_data[:name]
117
- )
172
+ if Template.project?
173
+ then return Template.root.join(root_data[
174
+ :project_data_dir
175
+ ])
176
+
177
+ else
178
+ Template.root.join(
179
+ root_data[:repos_dir], root_data[
180
+ :name
181
+ ]
182
+ )
183
+ end
118
184
  end
119
185
 
120
- # ----------------------------------------------------------------------
186
+ # --
121
187
  # Check if a part of the hash or a value is inside.
122
188
  # @param val [Anytning(), Hash] - The key or key => val you wish check.
123
- # @example metadata.include?(:key => :val) => true|false
124
- # @example metadata.include?(:key) => true|false
125
- # ----------------------------------------------------------------------
189
+ # @example meta.include?(:key => :val) => true|false
190
+ # @example meta.include?(:key) => true|false
191
+ # --
126
192
 
127
193
  def include?(val)
128
194
  if val.is_a?(Hash)
@@ -141,11 +207,11 @@ module Docker
141
207
  true
142
208
  end
143
209
 
144
- # ----------------------------------------------------------------------
210
+ # --
145
211
  # @param key [Anything()] the key you wish to pull.
146
212
  # @note we make the getter slightly more indifferent because of tags.
147
213
  # Pull an indifferent key from the hash.
148
- # ----------------------------------------------------------------------
214
+ # --
149
215
 
150
216
  def [](key)
151
217
  val = begin
@@ -173,7 +239,7 @@ module Docker
173
239
  val
174
240
  end
175
241
 
176
- # ----------------------------------------------------------------------
242
+ # --
177
243
 
178
244
  def []=(key, val)
179
245
  hash = { key => val }.stringify
@@ -182,7 +248,7 @@ module Docker
182
248
  )
183
249
  end
184
250
 
185
- # ----------------------------------------------------------------------
251
+ # --
186
252
 
187
253
  def update(hash)
188
254
  @data.update(
@@ -190,7 +256,7 @@ module Docker
190
256
  )
191
257
  end
192
258
 
193
- # ----------------------------------------------------------------------
259
+ # --
194
260
 
195
261
  def to_enum
196
262
  @data.each_with_object({}) do |(k, v), h|
@@ -204,10 +270,10 @@ module Docker
204
270
  end.to_enum
205
271
  end
206
272
 
207
- # ----------------------------------------------------------------------
208
- # Merge a hash into the metadata. If you merge non-queryable data
273
+ # --
274
+ # Merge a hash into the meta. If you merge non-queryable data
209
275
  # it will then get merged into the queryable data.
210
- # ----------------------------------------------------------------------
276
+ # --
211
277
 
212
278
  def merge(new_)
213
279
  if !queryable?(:query_data => new_) && queryable?
@@ -222,9 +288,9 @@ module Docker
222
288
  })
223
289
  end
224
290
 
225
- # ----------------------------------------------------------------------
291
+ # --
226
292
  # Destructive merging (@see self#merge)
227
- # ----------------------------------------------------------------------
293
+ # --
228
294
 
229
295
  def merge!(new_)
230
296
  if !queryable?(:query_data => new_) && queryable?
@@ -240,13 +306,13 @@ module Docker
240
306
  self
241
307
  end
242
308
 
243
- # --------------------------------------------------------------------
309
+ # --
244
310
  # Check if a hash is queryable. AKA has "all", "group", "tag".
245
- # --------------------------------------------------------------------
311
+ # --
246
312
 
247
313
  def queryable?(query_data: @data)
248
314
  if query_data.is_a?(self.class)
249
- then query_data \
315
+ then query_data
250
316
  .queryable?
251
317
 
252
318
  elsif !query_data || !query_data.is_a?(Hash) || query_data.empty?
@@ -259,12 +325,12 @@ module Docker
259
325
  end
260
326
  end
261
327
 
262
- # --------------------------------------------------------------------
328
+ # --
263
329
  # Fallback, determining which route is the best. Tag > Group > All.
264
- # --------------------------------------------------------------------
330
+ # --
265
331
  # rubocop:disable Metrics/CyclomaticComplexity
266
332
  # rubocop:disable Metrics/PerceivedComplexity
267
- # ----------------------------------------------------------------------
333
+ # --
268
334
 
269
335
  def fallback(group: current_group, tag: current_tag, query_data: @data)
270
336
  if query_data.is_a?(self.class)
@@ -276,18 +342,19 @@ module Docker
276
342
  return nil
277
343
 
278
344
  else
279
- by_tag(:tag => tag, :query_data => query_data) || \
280
- by_parent_tag(:tag => tag, :query_data => query_data) || \
281
- by_group(:group => group, :query_data => query_data) || \
282
- by_parent_group(:tag => tag, :query_data => query_data) || \
283
- for_all(:query_data => query_data)
345
+ if !(v = by_tag(:tag => tag, :query_data => query_data)).nil? then return v
346
+ elsif !(v = by_parent_tag(:tag => tag, :query_data => query_data)).nil? then return v
347
+ elsif !(v = by_group(:group => group, :query_data => query_data)).nil? then return v
348
+ elsif !(v = by_parent_group(:tag => tag, :query_data => query_data)).nil? then return v
349
+ else return for_all(:query_data => query_data)
350
+ end
284
351
  end
285
352
  end
286
353
 
287
- # --------------------------------------------------------------------
354
+ # --
288
355
  # rubocop:enable Metrics/CyclomaticComplexity
289
356
  # rubocop:enable Metrics/PerceivedComplexity
290
- # ----------------------------------------------------------------------
357
+ # --
291
358
 
292
359
  def for_all(query_data: @data)
293
360
  if query_data.is_a?(self.class)
@@ -304,7 +371,7 @@ module Docker
304
371
  end
305
372
  end
306
373
 
307
- # --------------------------------------------------------------------
374
+ # --
308
375
 
309
376
  def by_tag(tag: current_tag, query_data: @data)
310
377
  if query_data.is_a?(self.class)
@@ -322,7 +389,7 @@ module Docker
322
389
  end
323
390
  end
324
391
 
325
- # ----------------------------------------------------------------------
392
+ # --
326
393
 
327
394
  def by_parent_tag(tag: current_tag, query_data: @data)
328
395
  if aliased_tag == current_tag || !complex_alias?
@@ -338,7 +405,7 @@ module Docker
338
405
  end
339
406
  end
340
407
 
341
- # --------------------------------------------------------------------
408
+ # --
342
409
 
343
410
  def by_group(group: current_group, query_data: @data)
344
411
  if query_data.is_a?(self.class)
@@ -356,7 +423,7 @@ module Docker
356
423
  end
357
424
  end
358
425
 
359
- # ----------------------------------------------------------------------
426
+ # --
360
427
 
361
428
  def by_parent_group(tag: current_tag, query_data: @data)
362
429
  if aliased_tag == current_tag || !complex_alias?
@@ -372,21 +439,21 @@ module Docker
372
439
  end
373
440
  end
374
441
 
375
- # ----------------------------------------------------------------------
376
- # Checks to see if the current metadata is an alias of another. This
442
+ # --
443
+ # Checks to see if the current meta is an alias of another. This
377
444
  # happens when the user has the tag in aliases but it's not complex.
378
- # ----------------------------------------------------------------------
445
+ # --
379
446
 
380
447
  def alias?
381
448
  !!(aliased_tag && aliased_tag != tag)
382
449
  end
383
450
 
384
- # ----------------------------------------------------------------------
451
+ # --
385
452
  # A complex alias happens when the user has an alias but also tries to
386
453
  # add extra data, this allows them to use data from all parties. This
387
454
  # allows them to reap the benefits of having shared data but sometimes
388
455
  # independent data that diverges into it's own.
389
- # ----------------------------------------------------------------------
456
+ # --
390
457
 
391
458
  def complex_alias?
392
459
  if !alias?
@@ -400,7 +467,7 @@ module Docker
400
467
  end
401
468
  end
402
469
 
403
- # ----------------------------------------------------------------------
470
+ # --
404
471
 
405
472
  def aliased_tag(tag: current_tag)
406
473
  aliases = root_data[:aliases]
@@ -414,7 +481,7 @@ module Docker
414
481
  end
415
482
  end
416
483
 
417
- # ----------------------------------------------------------------------
484
+ # --
418
485
 
419
486
  def aliased_group(tag: current_tag)
420
487
  root_data[:tags][aliased_tag({
@@ -422,9 +489,9 @@ module Docker
422
489
  })]
423
490
  end
424
491
 
425
- # ----------------------------------------------------------------------
492
+ # --
426
493
  # Converts the current meta into a string.
427
- # ----------------------------------------------------------------------
494
+ # --
428
495
 
429
496
  def to_s(raw: false, shell: false)
430
497
  if !raw && (mergeable_hash? || mergeable_array?)
@@ -441,10 +508,10 @@ module Docker
441
508
  end
442
509
  end
443
510
 
444
- # ----------------------------------------------------------------------
511
+ # --
445
512
  # rubocop:disable Metrics/CyclomaticComplexity
446
513
  # rubocop:disable Metrics/PerceivedComplexity
447
- # ----------------------------------------------------------------------
514
+ # --
448
515
 
449
516
  def to_a(raw: false, shell: false)
450
517
  if raw
@@ -464,16 +531,16 @@ module Docker
464
531
  end
465
532
  end
466
533
 
467
- # ----------------------------------------------------------------------
534
+ # --
468
535
  # rubocop:eanble Metrics/CyclomaticComplexity
469
536
  # rubocop:eanble Metrics/PerceivedComplexity
470
- # ----------------------------------------------------------------------
471
- # Convert a `Metadata' into a normal hash. If `self' is queryable then
537
+ # --
538
+ # Convert a `Meta' into a normal hash. If `self' is queryable then
472
539
  # we go and start merging values smartly. This means that we will merge
473
540
  # all the arrays into one another and we will merge hashes into hashes.
474
- # ----------------------------------------------------------------------
541
+ # --
475
542
  # rubocop:disable Metrics/AbcSize
476
- # ----------------------------------------------------------------------
543
+ # --
477
544
 
478
545
  def to_h(raw: false)
479
546
  return @data.to_h if raw || !queryable? || !mergeable_hash?
@@ -499,16 +566,18 @@ module Docker
499
566
 
500
567
  else
501
568
  vals.find do |v|
502
- v[k]
569
+ v.key?(
570
+ k
571
+ )
503
572
  end \
504
573
  [k]
505
574
  end
506
575
  end
507
576
  end
508
577
 
509
- # ----------------------------------------------------------------------
578
+ # --
510
579
  # rubocop:enable Metrics/AbcSize
511
- # ----------------------------------------------------------------------
580
+ # --
512
581
 
513
582
  def mergeable_hash?(key = nil)
514
583
  return false unless queryable?
@@ -528,7 +597,7 @@ module Docker
528
597
  end
529
598
  end
530
599
 
531
- # ----------------------------------------------------------------------
600
+ # --
532
601
 
533
602
  def mergeable_array?(key = nil)
534
603
  return false unless queryable?
@@ -548,30 +617,30 @@ module Docker
548
617
  end
549
618
  end
550
619
 
551
- # ----------------------------------------------------------------------
620
+ # --
552
621
 
553
622
  def current_group
554
623
  root_data[:tags][current_tag] ||
555
624
  "normal"
556
625
  end
557
626
 
558
- # ----------------------------------------------------------------------
627
+ # --
559
628
  # HELPER: Get a list of all the tags.
560
- # ----------------------------------------------------------------------
629
+ # --
561
630
 
562
631
  def tags
563
632
  (root_data[:tags] || {}).keys | (root_data[:aliases] || {}).keys
564
633
  end
565
634
 
566
- # ----------------------------------------------------------------------
635
+ # --
567
636
  # HELPER: Get a list of all the groups.
568
- # ----------------------------------------------------------------------
637
+ # --
569
638
 
570
639
  def groups
571
640
  root_data["tags"].values.uniq
572
641
  end
573
642
 
574
- # ----------------------------------------------------------------------
643
+ # --
575
644
 
576
645
  private
577
646
  def merge_or_override(val, new_val)
@@ -581,18 +650,21 @@ module Docker
581
650
  return new_val | val if val.respond_to?(:|)
582
651
  end
583
652
 
584
- # ----------------------------------------------------------------------
653
+ # --
585
654
 
586
655
  private
587
656
  def string_wrapper(obj, shell: false)
588
657
  return obj if obj == true || obj == false || obj.nil?
658
+ return obj.fallback if obj.is_a?(self.class) && obj.queryable? \
659
+ && !(o = obj.fallback).nil? && (o == true || o == false)
660
+
589
661
  return obj.to_s(:shell => shell) if obj.is_a?(self.class)
590
662
  !obj.is_a?(Array) ? obj.to_s : obj.join(
591
663
  "\s"
592
664
  )
593
665
  end
594
666
 
595
- # ----------------------------------------------------------------------
667
+ # --
596
668
 
597
669
  private
598
670
  def method_missing(method, *args, shell: false, &block)
@@ -609,6 +681,7 @@ module Docker
609
681
  })
610
682
 
611
683
  else
684
+ val = val.fallback if val.is_a?(self.class) && val.queryable?
612
685
  [true, false].include?(val) ? val : \
613
686
  if val.respond_to?(:empty?)
614
687
  then !val.empty? else !!val
@@ -616,7 +689,29 @@ module Docker
616
689
  end
617
690
  end
618
691
 
619
- # ----------------------------------------------------------------------
692
+ # --
693
+
694
+ private
695
+ def load_normal_config(overrides)
696
+ overrides = overrides.stringify
697
+ gdata = Template.root.join(self.class.opts_file).read_yaml
698
+ @data = DEFAULTS.deep_merge(gdata.stringify).deep_merge(overrides)
699
+ tdata = Template.root.join(@data[:repos_dir], @data[:name], self.class.opts_file).read_yaml
700
+ @data = @data.deep_merge(tdata.stringify).deep_merge(overrides)
701
+ @data = @data.stringify.with_indifferent_access
702
+ end
703
+
704
+ # --
705
+
706
+ private
707
+ def load_project_config(overrides)
708
+ overrides = overrides.stringify
709
+ gdata = Template.root.join(self.class.opts_file).read_yaml
710
+ @data = DEFAULTS.deep_merge(gdata.stringify).deep_merge(overrides)
711
+ @data = @data.stringify.with_indifferent_access
712
+ end
713
+
714
+ # --
620
715
 
621
716
  alias deep_merge merge
622
717
  alias group current_group
@@ -625,7 +720,7 @@ module Docker
625
720
  rb_delegate :tag, :to => :root_data, :type => :hash, :key => :tag
626
721
  rb_delegate :root, :to => :@root, :type => :ivar, :bool => true
627
722
 
628
- # ----------------------------------------------------------------------
723
+ # --
629
724
 
630
725
  rb_delegate :fetch, :to => :@data
631
726
  rb_delegate :delete, :to => :@data
@@ -637,7 +732,7 @@ module Docker
637
732
  rb_delegate :key?, :to => :@data
638
733
  rb_delegate :==, :to => :@data
639
734
 
640
- # ----------------------------------------------------------------------
735
+ # --
641
736
 
642
737
  rb_delegate :inject, :to => :to_enum
643
738
  rb_delegate :select, :to => :to_enum