k_builder 0.0.39 → 0.0.56

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5c8b5b5e5cc829fc8d5239d970cda55ef650e6d0b6bc5e6474a4d4172bde0661
4
- data.tar.gz: c326954d805393dc3137c1b37642dfc507337d93319f8fd247bacfcb62d495e4
3
+ metadata.gz: 758519925163c21cae5ef6bd99798577d7481f6bff55d6ce51599ee15bdd1baa
4
+ data.tar.gz: 89fbffd295334411d71ea48279838e13029ed01e3fa9c5b76be2aea7f1d44c8b
5
5
  SHA512:
6
- metadata.gz: a8def8a344f419a00722f2e0d2c481603fa940e02dab468a8a28251c273f1c8b0d06310cfd496abcad82d331f99efeb4f5c57f0c25462ddb2ca50da2b83008d0
7
- data.tar.gz: bf23b9b0c8bc4cba10a2f944889210baa0378008779dd4ac935a85d42826c83e12aad1f84c29904fcf96aa0e3c2545baa32cfb7cb2a7a84bbf3c48d67cdb10a7
6
+ metadata.gz: a620cc2730bdac7d129de3b7975967d2bea5819213091c7c551a4ed59a480f994617f08fb2649c9aeb46968181f0dea956875c3c6e87d456eacbe29310ab5295
7
+ data.tar.gz: 3bd54f3c7e9869fbb232239096ac201a62299b292fffa00cfd3612a7fb7f2b43b9242e86d6821142f1ed4743d7e68cff3d2e10789342dd346a8abb2241b3e9c7
data/.rubocop.yml CHANGED
@@ -73,6 +73,9 @@ Layout/EmptyLineBetweenDefs:
73
73
  Exclude:
74
74
  - "**/spec/**/*"
75
75
 
76
+ Style/Documentation:
77
+ Enabled: false
78
+
76
79
  Lint/AmbiguousBlockAssociation:
77
80
  Exclude:
78
81
  - "**/spec/**/*"
data/Rakefile CHANGED
@@ -1,7 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ GEM_NAME = 'k_builder'
4
+
3
5
  require 'bundler/gem_tasks'
4
6
  require 'rspec/core/rake_task'
7
+ require 'k_builder/version'
5
8
 
6
9
  RSpec::Core::RakeTask.new(:spec)
7
10
 
@@ -14,4 +17,15 @@ Rake::ExtensionTask.new('k_builder') do |ext|
14
17
  ext.lib_dir = 'lib/k_builder'
15
18
  end
16
19
 
20
+ desc 'Publish the gem to RubyGems.org'
21
+ task :publish do
22
+ system 'gem build'
23
+ system "gem push #{GEM_NAME}-#{KBuilder::VERSION}.gem"
24
+ end
25
+
26
+ desc 'Remove old *.gem files'
27
+ task :clean do
28
+ system 'rm *.gem'
29
+ end
30
+
17
31
  task default: %i[clobber compile spec]
data/STORIES.md CHANGED
@@ -10,14 +10,34 @@ As a Polyglot Developer, I want to be up and running in any development language
10
10
 
11
11
  As a Polyglot Developer, I want to be up and running in any development language with consistency, so I am productive and using best practices [EPIC]
12
12
 
13
- ### Tasks next on list
13
+ As a Developer, I need builders to be easier to use, so I am more efficient
14
14
 
15
- BaseBuilder
15
+ - Logging needs to be more informative
16
+ - Template errors need to log the template and the filename
17
+ - add_file with template_file: needs to support optional filename that is the same as the template_file (or use a token, eg. $TF_PATH$, $TF_NAME$, $TF_FILE$
18
+ - add_file, the files being generated are not being logged
16
19
 
17
20
  ## Stories and tasks
18
21
 
22
+ ### Stories - completed
23
+
24
+ As a Developer, I want have multiple template, so I can group my templates by area of specialty
25
+
26
+ - Refactor global and app templates to a layered folder array using (First In, Last Out) priority
27
+ - Support subfolders of any template folder (maybe)
28
+
29
+ As a Developer, I want have multiple output folders, so I can write to multiple locations
30
+
31
+ - Refactor output folder so that there are multiple named output folders, with :default working the same way as the existing system
32
+ - Support subfolders of any output folder
33
+ - Support output folder change of focus
34
+
19
35
  ### Tasks - completed
20
36
 
37
+ WatchBuilder - Build Watcher (as a builder) - [k_builder-watch](https://github.com/klueless-io/k_builder-watch)
38
+
39
+ Refactor BaseBuilder
40
+
21
41
  Setup RubyGems and RubyDoc
22
42
 
23
43
  - Build and deploy gem to [rubygems.org](https://rubygems.org/gems/k_builder)
data/USAGE.md CHANGED
@@ -55,26 +55,26 @@ TEXT
55
55
 
56
56
  builder = KBuilder::Builder.init
57
57
 
58
- builder
59
- .add_file('main.rb', template_file: 'class.rb', name: 'main')
60
- .add_file('person.rb',
61
- template_file: 'model.rb',
62
- name: 'person',
63
- fields: %i[first_name last_name])
64
- .add_file('address.rb',
65
- template_file: 'model.rb',
66
- name: 'address',
67
- fields: %i[street1 street2 post_code state])
68
- .add_file('configuration.log.txt',
69
- template: template,
70
- a: builder.template_folder,
71
- b: builder.global_template_folder,
72
- c: builder.target_folder)
73
- .add_file('css/index.css',
74
- template: '{{#each colors}} .{{.}} { color: {{.}} } {{/each}}',
75
- colors: ['red', 'blue', 'green'],
76
- pretty: true)
77
-
58
+ builder.add_file('main.rb', template_file: 'class.rb', name: 'main').add_file(
59
+ 'person.rb',
60
+ template_file: 'model.rb', name: 'person', fields: %i[first_name last_name]
61
+ ).add_file(
62
+ 'address.rb',
63
+ template_file: 'model.rb',
64
+ name: 'address',
65
+ fields: %i[street1 street2 post_code state]
66
+ ).add_file(
67
+ 'configuration.log.txt',
68
+ template: template,
69
+ a: builder.template_folder,
70
+ b: builder.global_template_folder,
71
+ c: builder.target_folder
72
+ ).add_file(
73
+ 'css/index.css',
74
+ template: '{{#each colors}} .{{.}} { color: {{.}} } {{/each}}',
75
+ colors: %w[red blue green],
76
+ pretty: true
77
+ )
78
78
  ```
79
79
 
80
80
  #### Folder Structure (after)
@@ -85,7 +85,7 @@ Folder structure after running the builder
85
85
 
86
86
  #### main.rb
87
87
 
88
- ![main.rb](usage/_out1.png)
88
+ ![](usage/_out1.png)
89
89
 
90
90
  #### person.rb
91
91
 
@@ -93,12 +93,12 @@ Folder structure after running the builder
93
93
 
94
94
  #### address.rb
95
95
 
96
- ![person.rb](usage/_out3.png)
96
+ ![](usage/_out3.png)
97
97
 
98
98
  #### configuration.log.txt
99
99
 
100
- ![configuration.log.txt](usage/_out4.png)
100
+ ![](usage/_out4.png)
101
101
 
102
102
  #### css/index.css
103
103
 
104
- ![css/index.css](usage/_out5.png)
104
+ ![](usage/_out5.png)
data/k_builder.gemspec CHANGED
@@ -39,6 +39,9 @@ Gem::Specification.new do |spec|
39
39
  # spec.extensions = ['ext/k_builder/extconf.rb']
40
40
 
41
41
  spec.add_dependency 'handlebars-helpers', '~> 0'
42
+ spec.add_dependency 'k_log', '~> 0'
43
+ spec.add_dependency 'k_type', '~> 0'
44
+ spec.add_dependency 'k_util', '~> 0'
42
45
  # spec.add_dependency "anyway_config" , ">= 2.0.0"
43
46
  # spec.add_dependency "config" , ">= 3.0.0"
44
47
  end
data/lib/k_builder.rb CHANGED
@@ -1,18 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'k_log'
4
+ require 'k_util'
5
+ require 'k_type'
3
6
  require 'k_builder/version'
4
7
  require 'k_builder/base_builder'
5
8
  require 'k_builder/base_configuration'
6
9
  require 'k_builder/configuration'
7
- require 'k_builder/data_helper'
8
- require 'k_builder/named_folders'
9
- require 'k_builder/layered_folders'
10
+ require 'k_builder/file_segments'
10
11
 
11
12
  require 'handlebars/helpers/template'
12
13
 
13
14
  module KBuilder
14
15
  # raise KBuilder::Error, 'Sample message'
15
16
  class Error < StandardError; end
17
+ end
16
18
 
17
- # Your code goes here...
19
+ if ENV['KLUE_DEBUG']&.to_s&.downcase == 'true'
20
+ namespace = 'KBuilder::Version'
21
+ file_path = $LOADED_FEATURES.find { |f| f.include?('k_builder/version') }
22
+ version = KBuilder::VERSION.ljust(9)
23
+ puts "#{namespace.ljust(40)} : #{version.ljust(9)} : #{file_path}"
18
24
  end
@@ -41,16 +41,6 @@ module KBuilder
41
41
 
42
42
  @target_folders = configuration.target_folders.clone
43
43
  @template_folders = configuration.template_folders.clone
44
-
45
- define_builder_setter_methods
46
- end
47
-
48
- # Return an array of symbols to represent the fluent
49
- # setter methods that you want on your builder.
50
- #
51
- # Abstract method
52
- def builder_setter_methods
53
- []
54
44
  end
55
45
 
56
46
  # @return [Hash/StrongType] Returns data object, can be a hash
@@ -91,8 +81,9 @@ module KBuilder
91
81
  # @option opts [String] :to Recipient email
92
82
  # @option opts [String] :body The email's body
93
83
  def add_file(file, **opts)
94
- full_file = target_file(file)
84
+ full_file = opts.key?(:folder_key) ? target_file(file, folder: opts[:folder_key]) : target_file(file)
95
85
 
86
+ # Need logging options that can log these internal details
96
87
  FileUtils.mkdir_p(File.dirname(full_file))
97
88
 
98
89
  content = process_any_content(**opts)
@@ -104,6 +95,42 @@ module KBuilder
104
95
 
105
96
  self
106
97
  end
98
+ alias touch add_file # it is expected that you would not supply any options, just a file name
99
+
100
+ # Add content to the clipboard
101
+ #
102
+ # @option opts [String] :content Supply the content that you want to write to the file
103
+ # @option opts [String] :template Supply the template that you want to write to the file, template will be processed ('nobody') From address
104
+ # @option opts [String] :content_file File with content, file location is based on where the program is running
105
+ # @option opts [String] :template_file File with handlebars templated content that will be transformed, file location is based on the configured template_path
106
+ #
107
+ # Extra options will be used as data for templates, e.g
108
+ # @option opts [String] :to Recipient email
109
+ # @option opts [String] :body The email's body
110
+ def add_clipboard(**opts)
111
+ content = process_any_content(**opts)
112
+
113
+ begin
114
+ IO.popen('pbcopy', 'w') { |f| f << content }
115
+ rescue Errno::ENOENT => e
116
+ if e.message == 'No such file or directory - pbcopy'
117
+ # May want to use this GEM in the future
118
+ # https://github.com/janlelis/clipboard
119
+ puts 'Clipboard paste is currently only supported on MAC'
120
+ end
121
+ end
122
+
123
+ self
124
+ end
125
+ alias clipboard_copy add_clipboard
126
+
127
+ def vscode(*file_parts, folder: current_folder_key)
128
+ file = target_file(*file_parts, folder: folder)
129
+
130
+ rc "code #{file}"
131
+
132
+ self
133
+ end
107
134
 
108
135
  # ----------------------------------------------------------------------
109
136
  # Attributes: Think getter/setter
@@ -144,8 +171,28 @@ module KBuilder
144
171
  end
145
172
 
146
173
  # Get target file
147
- def target_file(file_parts, folder: current_folder_key)
148
- File.join(target_folder(folder), file_parts)
174
+ #
175
+ # If you provide a relative folder, then it will be relative to the :folder parameter
176
+ #
177
+ # If the :folder is not set, then it will be relative to the current folder
178
+ #
179
+ # @examples
180
+ # target_file('abc.txt')
181
+ # target_file('xyz/abc.txt')
182
+ # target_file('xyz', 'abc.txt')
183
+ #
184
+ # If you provide an absolute folder, then it will ignore the :folder parameter
185
+ #
186
+ # @examples
187
+ # target_file('/abc.txt')
188
+ # target_file('/xyz/abc.txt')
189
+ # target_file('/xyz', 'abc.txt')
190
+ def target_file(*file_parts, folder: current_folder_key)
191
+ # Absolute path
192
+ return File.join(*file_parts) if Pathname.new(file_parts.first).absolute?
193
+
194
+ # Relative to :folder
195
+ File.join(target_folder(folder), *file_parts)
149
196
  end
150
197
 
151
198
  # Template folder & Files
@@ -254,63 +301,5 @@ module KBuilder
254
301
  system(build_command)
255
302
  end
256
303
  alias rc run_command
257
-
258
- # TODO
259
- # Support Nesting
260
- # Support Generation fo the following
261
- # - fluent set_
262
- # - Support setter (non-fluent)
263
- # - Support getter (non-fluent)
264
-
265
- # # builds a nested structure by either builder block or hash
266
- # # @param data_structure [type=DataStructure]
267
- # # @param builder [type=Builder]
268
- # # @param attributes [type=Hash|DataStructure instance]
269
- # # @param &block
270
- # #
271
- # # @return [type=Hash]
272
- # def build_nested(data_structure, builder, attributes = {}, &block)
273
- # if block_given?
274
- # builder.build(&block).to_h
275
- # else
276
- # build_hash(data_structure, attributes)
277
- # end
278
- # end
279
-
280
- private
281
-
282
- # #
283
- # # @param data_structure [type=DataStructure]
284
- # # @param attributes [type=Hash, DataStructure]
285
- # #
286
- # # @return [type=Hash]
287
- # def build_hash(data_structure, attributes)
288
- # if attributes.is_a?(data_structure)
289
- # attributes.to_h
290
- # else
291
- # data_structure.new(attributes).to_h
292
- # end
293
- # end
294
-
295
- # Defines all of the necessary builder setter methods
296
- #
297
- # @return [Builder] Returns the builder via fluent interface
298
- def define_builder_setter_methods
299
- builder_setter_methods.each { |method| define_builder_method(method) }
300
- self
301
- end
302
-
303
- # Defines a method using the convention set_[method_name]
304
- #
305
- # Convention: Setter methods (are Fluent) and use the prefix set_
306
- # Getter methods (are NOT fluent) and return the stored value
307
- #
308
- # @return [Builder] Returns the builder via fluent interface
309
- def define_builder_method(method_name)
310
- self.class.send(:define_method, "set_#{method_name}") do |value|
311
- @hash[method_name.to_s] = value
312
- self
313
- end
314
- end
315
304
  end
316
305
  end
@@ -1,55 +1,63 @@
1
- # frozen_string_literal: true
2
-
3
- module KBuilder
4
- # Base configuration object for all k_builder* GEM
5
- class BaseConfiguration
6
- def self.attach_to(klass_me, klass_target, accessor_name)
7
- # Create a memoized getter to an instance of the attaching class (:klass_me)
8
- #
9
- # def third_party
10
- # @third_party ||= KBuilder::ThirdPartyGem::Configuration.new
11
- # end
12
- klass_target.send(:define_method, accessor_name) do
13
- return instance_variable_get("@#{accessor_name}") if instance_variable_defined?("@#{accessor_name}")
14
-
15
- instance_variable_set("@#{accessor_name}", klass_me.new)
16
- end
17
- end
18
-
19
- # move out into module
20
- def to_h
21
- hash = {}
22
- instance_variables.each do |var|
23
- value = instance_variable_get(var)
24
-
25
- value = KBuilder.data.struct_to_hash(value) if complex_type?(value)
26
-
27
- hash[var.to_s.delete('@')] = value
28
- end
29
- hash
30
- end
31
-
32
- # Any basic (aka primitive) type
33
- def basic_type?(value)
34
- value.is_a?(String) ||
35
- value.is_a?(Symbol) ||
36
- value.is_a?(FalseClass) ||
37
- value.is_a?(TrueClass) ||
38
- value.is_a?(Integer) ||
39
- value.is_a?(Float)
40
- end
41
-
42
- # Anything container that is not a regular class
43
- def complex_type?(value)
44
- value.is_a?(Array) ||
45
- value.is_a?(Hash) ||
46
- value.is_a?(Struct) ||
47
- value.is_a?(OpenStruct) ||
48
- value.respond_to?(:to_h)
49
- end
50
-
51
- def kv(name, value)
52
- puts "#{name.rjust(30)} : #{value}"
53
- end
54
- end
55
- end
1
+ # frozen_string_literal: true
2
+
3
+ module KBuilder
4
+ # Base configuration object for all k_builder* GEM
5
+ class BaseConfiguration
6
+ class << self
7
+ # Attach a child configuration with it's own settings to a parent configuration
8
+ #
9
+ # @param [Class] klass_child what class would you like as the child
10
+ # @param [Class] klass_parent what class would you like to extend with a new child configuration
11
+ # @param [Symbol] accessor_name what is the name of the accessor that you are adding
12
+ def attach_config_to_parent(klass_child, klass_parent, accessor_name)
13
+ # Create a memoized getter to an instance of the attaching class (:klass_child)
14
+ #
15
+ # def third_party
16
+ # @third_party ||= KBuilder::ThirdPartyGem::Configuration.new
17
+ # end
18
+ klass_parent.send(:define_method, accessor_name) do
19
+ return instance_variable_get("@#{accessor_name}") if instance_variable_defined?("@#{accessor_name}")
20
+
21
+ instance_variable_set("@#{accessor_name}", klass_child.new)
22
+ end
23
+ end
24
+ alias attach_to attach_config_to_parent
25
+ end
26
+
27
+ # move out into module
28
+ def to_h
29
+ hash = {}
30
+ instance_variables.each do |var|
31
+ value = instance_variable_get(var)
32
+
33
+ value = KUtil.data.to_hash(value) if complex_type?(value)
34
+
35
+ hash[var.to_s.delete('@')] = value
36
+ end
37
+ hash
38
+ end
39
+
40
+ # Any basic (aka primitive) type
41
+ def basic_type?(value)
42
+ value.is_a?(String) ||
43
+ value.is_a?(Symbol) ||
44
+ value.is_a?(FalseClass) ||
45
+ value.is_a?(TrueClass) ||
46
+ value.is_a?(Integer) ||
47
+ value.is_a?(Float)
48
+ end
49
+
50
+ # Anything container that is not a regular class
51
+ def complex_type?(value)
52
+ value.is_a?(Array) ||
53
+ value.is_a?(Hash) ||
54
+ value.is_a?(Struct) ||
55
+ value.is_a?(OpenStruct) ||
56
+ value.respond_to?(:to_h)
57
+ end
58
+
59
+ def kv(name, value)
60
+ puts "#{name.rjust(30)} : #{value}"
61
+ end
62
+ end
63
+ end
@@ -1,61 +1,72 @@
1
- # frozen_string_literal: true
2
-
3
- # Attach configuration to the KBuilder module
4
- module KBuilder
5
- # Configuration for webpack5/builder
6
- class << self
7
- attr_writer :configuration
8
- end
9
-
10
- def self.configuration
11
- @configuration ||= Configuration.new
12
- end
13
-
14
- def self.reset
15
- @configuration = Configuration.new
16
- end
17
-
18
- def self.configure
19
- yield(configuration)
20
- end
21
-
22
- # Configuration class
23
- class Configuration < BaseConfiguration
24
- attr_accessor :target_folders
25
- attr_accessor :template_folders
26
-
27
- def initialize
28
- super
29
- # @target_folder = Dir.getwd
30
- # @template_folder = File.join(Dir.getwd, '.templates')
31
- # @global_template_folder = nil
32
- @target_folders = NamedFolders.new
33
- @template_folders = LayeredFolders.new
34
- end
35
-
36
- def initialize_copy(orig)
37
- super(orig)
38
-
39
- @target_folders = orig.target_folders.clone
40
- @template_folders = orig.template_folders.clone
41
- end
42
-
43
- # rubocop:disable Metrics/AbcSize
44
- def debug
45
- puts '-' * 120
46
- puts 'kbuilder base configuration'
47
-
48
- puts 'target_folders'
49
- target_folders.folders.each_key do |key|
50
- folder = target_folders.folders[key]
51
- kv key.to_s, folder
52
- end
53
-
54
- puts 'template folders (search order)'
55
- template_folders.ordered_folders.each do |folder|
56
- puts folder.to_s
57
- end
58
- end
59
- # rubocop:enable Metrics/AbcSize
60
- end
61
- end
1
+ # frozen_string_literal: true
2
+
3
+ # Attach configuration to the KBuilder module
4
+ module KBuilder
5
+ # Configuration for webpack5/builder
6
+ class << self
7
+ attr_writer :configuration
8
+ end
9
+
10
+ def self.configuration
11
+ @configuration ||= Configuration.new
12
+ end
13
+
14
+ def self.reset
15
+ @configuration = Configuration.new
16
+ end
17
+
18
+ def self.configure
19
+ yield(configuration)
20
+ end
21
+
22
+ # Does this class need to move out into k_types?
23
+ # It is being used with k_manager in a similar fashion
24
+ #
25
+ # Configuration class
26
+ class Configuration < BaseConfiguration
27
+ include KLog::Logging
28
+
29
+ # Target folders provide a set named folders that can be written to
30
+ attr_accessor :target_folders
31
+
32
+ # Template folders provides layered folders that templates can exist within
33
+ attr_accessor :template_folders
34
+
35
+ def initialize
36
+ super
37
+ # @target_folder = Dir.getwd
38
+ # @template_folder = File.join(Dir.getwd, '.templates')
39
+ # @global_template_folder = nil
40
+ @target_folders = KType::NamedFolders.new
41
+ @template_folders = KType::LayeredFolders.new
42
+ end
43
+
44
+ def initialize_copy(orig)
45
+ super(orig)
46
+
47
+ @target_folders = orig.target_folders.clone
48
+ @template_folders = orig.template_folders.clone
49
+ end
50
+
51
+ # rubocop:disable Metrics/AbcSize
52
+ def debug
53
+ log.subheading 'kbuilder base configuration'
54
+
55
+ log.section_heading 'target_folders'
56
+ target_folders.folders.each_key do |key|
57
+ folder = target_folders.folders[key]
58
+ log.kv key.to_s, folder
59
+ end
60
+ log.info ''
61
+
62
+ log.section_heading 'template folders (search order)'
63
+
64
+ template_folders.ordered_keys.each do |key|
65
+ folder = template_folders.folders[key]
66
+ log.kv key.to_s, folder
67
+ end
68
+ ''
69
+ end
70
+ # rubocop:enable Metrics/AbcSize
71
+ end
72
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module KBuilder
4
+ # Splits a file into its base parts (file, path, file_name, extension and file_name_only)
5
+ #
6
+ # Provides the interpolate helper to rebuild a different filename using those segments
7
+ class FileSegments
8
+ attr_reader :file
9
+ attr_reader :path
10
+ attr_reader :file_name
11
+ attr_reader :ext
12
+ attr_reader :file_name_only
13
+
14
+ def initialize(file)
15
+ @file = file
16
+ @path = File.dirname(file)
17
+ @file_name = File.basename(file)
18
+ @ext = File.extname(file)
19
+ @file_name_only = File.basename(file, @ext)
20
+ end
21
+
22
+ def interpolate(target_file)
23
+ # p str.gsub( /#{var}/, 'foo' ) # => "a test foo"
24
+ target_file
25
+ .gsub(/\$T_FILE\$/i, file)
26
+ .gsub(/\$T_PATH\$/i, path)
27
+ .gsub(/\$T_FILE_NAME\$/i, file_name)
28
+ .gsub(/\$T_EXT\$/i, ext)
29
+ .gsub(/\$T_FILE_NAME_ONLY\$/i, file_name_only)
30
+ end
31
+ end
32
+ end
@@ -1,5 +1,5 @@
1
- # frozen_string_literal: true
2
-
3
- module KBuilder
4
- VERSION = '0.0.39'
5
- end
1
+ # frozen_string_literal: true
2
+
3
+ module KBuilder
4
+ VERSION = '0.0.56'
5
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: k_builder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.39
4
+ version: 0.0.56
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Cruwys
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-03-20 00:00:00.000000000 Z
11
+ date: 2021-04-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: handlebars-helpers
@@ -24,6 +24,48 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: k_log
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: k_type
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: k_util
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
27
69
  description: " K Builder provides various fluent builders for initializing applications
28
70
  with different language requirements\n"
29
71
  email:
@@ -56,9 +98,7 @@ files:
56
98
  - lib/k_builder/base_builder.rb
57
99
  - lib/k_builder/base_configuration.rb
58
100
  - lib/k_builder/configuration.rb
59
- - lib/k_builder/data_helper.rb
60
- - lib/k_builder/layered_folders.rb
61
- - lib/k_builder/named_folders.rb
101
+ - lib/k_builder/file_segments.rb
62
102
  - lib/k_builder/version.rb
63
103
  - usage/_out1.png
64
104
  - usage/_out2.png
@@ -1,66 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Attach data helper to the KBuilder module
4
- module KBuilder
5
- # Data helpers/utils for Kbuilder
6
- class << self
7
- attr_writer :data
8
- end
9
-
10
- def self.data
11
- @data ||= DataHelper.new
12
- end
13
-
14
- # Helper methods attached to the namespace for working with Data
15
- #
16
- # Usage: KBuilder.data.to_struct(data)
17
- class DataHelper
18
- # Convert a hash into a deep OpenStruct or array an array
19
- # of objects into an array of OpenStruct
20
- def to_struct(data)
21
- case data
22
- when Hash
23
- OpenStruct.new(data.transform_values { |v| to_struct(v) })
24
-
25
- when Array
26
- data.map { |o| to_struct(o) }
27
-
28
- else
29
- # Some primitave type: String, True/False, Symbol or an ObjectStruct
30
- data
31
- end
32
- end
33
-
34
- # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
35
- def struct_to_hash(data)
36
- # No test yet
37
- if data.is_a?(Array)
38
- return data.map { |v| v.is_a?(OpenStruct) ? struct_to_hash(v) : v }
39
- end
40
-
41
- return struct_to_hash(data.to_h) if !data.is_a?(Hash) && data.respond_to?(:to_h)
42
-
43
- data.each_pair.with_object({}) do |(key, value), hash|
44
- case value
45
- when OpenStruct, Struct, Hash
46
- hash[key] = struct_to_hash(value)
47
- when Array
48
- # No test yet
49
- values = value.map do |v|
50
- v.is_a?(OpenStruct) || v.is_a?(Struct) || v.is_a?(Hash) ? struct_to_hash(v) : v
51
- end
52
- hash[key] = values
53
- else
54
- hash[key] = value
55
- end
56
- end
57
- end
58
- # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
59
-
60
- def clean_symbol(value)
61
- return value if value.nil?
62
-
63
- value.is_a?(Symbol) ? value.to_s : value
64
- end
65
- end
66
- end
@@ -1,104 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module KBuilder
4
- #
5
- # Named folders makes sense for generated/output folders because you may want
6
- # more than one type of location to generate output.
7
- #
8
- # Don't confuse multiple named output folders with sub-paths, when you want to
9
- # build up a file name in a child folder, you can do that as part of building
10
- # the filename.
11
- #
12
- # The idea behind named folders is for when you have two or more totally different
13
- # outputs that (may live in the a similar location) or live in different locations.
14
-
15
- # Layered folders allow files to be found in any of the searchable folders
16
- #
17
- # They derive from and thus work just like named folders in that they allow folders
18
- # to be stored with easy to remember names/alias's.
19
- #
20
- # Where they differ is that they are retrieved in preferential search order that is
21
- # by default (First In, Last Out) priority aka a Stack (Last In, First Out) or
22
- # optionally over ridden via the search_order method
23
- #
24
- # Layered folders makes sense for use with template files and source data/model
25
- # where you can have specific usage files available and if they are not found then
26
- # you can use fall-back files in other folders.
27
- #
28
- # example:
29
- # folders = LayeredFolders.new
30
- # folders.add(:global , '~/global_templates')
31
- # folders.add(:domain , '/my-project/domain_templates')
32
- # folders.add(:app , '/my-project/my-app/.templates')
33
- #
34
- # # Find a file and folder will in folders in this order
35
- # # app_templates, then domain_templates and then finally global templates
36
- # # ['/my-project/my-app/.templates', '/my-project/domain_templates', '~/global_templates']
37
- # #
38
- # # Find a file called template1.txt and return its fully-qualified path
39
- # folders.find_file('template1.txt')
40
- #
41
- # # As above, but returns the folder only, file name and sub-paths are ignored
42
- # folders.find_file_folder('template1.txt')
43
- # folders.find_file_folder('abc/xyz/deep-template.txt')
44
- #
45
- # # If an additional folder is added, say in child configuration that is designed
46
- # # to override some of the global templates, then you can run a search_order
47
- # # method to re-order the templates
48
- #
49
- # folders.add(:global_shim , '~/global_templates_shim')
50
- # folders.search_order(:app, :domain, :global_shim, :global)
51
- #
52
- # class Builder < KBuilder::BaseBuilder
53
- class LayeredFolders < KBuilder::NamedFolders
54
- attr_reader :ordered_keys
55
- attr_reader :ordered_folders
56
-
57
- def initialize
58
- super()
59
-
60
- @ordered_keys = []
61
- @ordered_folders = []
62
- end
63
-
64
- def initialize_copy(orig)
65
- super(orig)
66
-
67
- @ordered_keys = orig.ordered_keys.clone
68
- @ordered_folders = orig.ordered_folders.clone
69
- end
70
-
71
- def add(folder_key, folder)
72
- folder = super(folder_key, folder)
73
-
74
- ordered_keys.prepend(folder_key)
75
- ordered_folders.prepend(folder)
76
-
77
- folder
78
- end
79
-
80
- # File name or array of sub-paths plus file
81
- #
82
- # Return the folder that a file is found in
83
- def find_file(file_parts)
84
- folder = find_file_folder(file_parts)
85
- folder.nil? ? nil : File.join(folder, file_parts)
86
- end
87
-
88
- # File name or array of sub-paths plus file
89
- #
90
- # Return the folder that a file is found in
91
- def find_file_folder(file_parts)
92
- ordered_folders.find { |folder| File.exist?(File.join(folder, file_parts)) }
93
- end
94
-
95
- def to_h
96
- {
97
- ordered: {
98
- keys: ordered_keys,
99
- folders: ordered_folders
100
- }
101
- }.merge(@folders)
102
- end
103
- end
104
- end
@@ -1,100 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module KBuilder
4
- # Named folders allow folders to be stored with easy to remember names/alias's
5
- # Secondarily, you can also build up file names based on these named folders.
6
- #
7
- # Named folders makes sense for generated/output folders because you may want
8
- # more than one type of location to generate output.
9
- #
10
- # Don't confuse multiple named output folders with sub-paths, when you want to
11
- # build up a file name in a child folder, you can do that as part of building
12
- # the filename.
13
- #
14
- # The idea behind named folders is for when you have two or more totally different
15
- # outputs that (may live in the a similar location) or live in different locations.
16
- # Samples:
17
- # name: :code - generating source code into a project
18
- # name: :slide - generating slide deck into a documentation folder
19
- # name: :webpack - folder where you might generate webpack files, e.g. webpack.config.*.json
20
- #
21
- # example:
22
- # folders = NamedFolders.new
23
- # folders.add(:csharp , '~/dev/csharp/cool-project')
24
- # folders.add(:package_json , :csharp)
25
- # folders.add(:webpack , folders.join(:csharp, 'config'))
26
- # folders.add(:builder , folders.join(:csharp, 'builder'))
27
- # folders.add(:slides , '~/doc/csharp/cool-project')
28
- #
29
- # puts folders.get(:builder)
30
- #
31
- # puts folders.get_filename(:csharp, 'Program.cs')
32
- # puts folders.get_filename(:csharp, 'Models/Order.cs')
33
- # puts folders.get_filename(:csharp, 'Models', 'Order.cs')
34
- #
35
- # Do I need to support :default?
36
- class NamedFolders
37
- attr_reader :folders
38
-
39
- attr_reader :current
40
-
41
- def initialize
42
- @folders = {}
43
- @current = nil
44
- end
45
-
46
- def initialize_copy(orig)
47
- super(orig)
48
-
49
- @folders = orig.folders.clone
50
- end
51
-
52
- def current=(folder_key)
53
- guard_folder_key(folder_key)
54
- @current = folder_key
55
- end
56
-
57
- def add(folder_key, folder)
58
- # get a predefined folder by symbol
59
- if folder.is_a?(Symbol)
60
- folder = get(folder)
61
- elsif folder.start_with?('~')
62
- folder = File.expand_path(folder)
63
- end
64
-
65
- @current = folder_key if @current.nil?
66
- folders[folder_key] = folder
67
- end
68
-
69
- # Get a folder
70
- def get(folder_key)
71
- guard_folder_key(folder_key)
72
- folders[folder_key]
73
- end
74
-
75
- # Join the lookup folder key with the subpath folder parts (optionally + filename) and return the folder or filename
76
- #
77
- # Return fully qualified filename
78
- def join(folder_key, *file_folder_parts)
79
- folder = get(folder_key)
80
-
81
- File.join(folder, file_folder_parts)
82
- end
83
- # Get a file name using the lookup folder key and the file name or array of sub-paths plus filename
84
- alias get_filename join
85
-
86
- def folder_keys
87
- @folders.keys
88
- end
89
-
90
- def to_h
91
- @folders
92
- end
93
-
94
- private
95
-
96
- def guard_folder_key(folder_key)
97
- raise KBuilder::Error, "Folder not found, this folder key not found: #{folder_key}" unless folders.key?(folder_key)
98
- end
99
- end
100
- end