k_builder 0.0.40 → 0.0.57

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 323fb5218f6098e38b7aedb951f8ff7c6aa93e891a9bbe77ffecf4ef2b0385ad
4
- data.tar.gz: '085e4f77356020cb7bbbf8b45332d635ef915c80d109fe5101b81ae101446874'
3
+ metadata.gz: 85fabea0178e317cd8bd8658d91b8813a143e48a8af8710465f5531cfba00535
4
+ data.tar.gz: b86a69632dac4f08256af550addfea622cd78d26dec7b92e5801f087bd917da7
5
5
  SHA512:
6
- metadata.gz: 86eb1f2f02fea68c10bfa428e4e415931378ca6d696b041abeb995590f14488e01aa90a19832e697c4faff6dca97b9522d7ac5e3ca734a004ff3b2f7c821c1c3
7
- data.tar.gz: 76c486d493078154cafe97ab96870b856cbd9813a18fc6b353210c1aed82a11df7ae039fcef291c4806c505788acef4d85fa1f3199e324cbab293405c653743d
6
+ metadata.gz: e23dfcad31466228dca0ada1a183ff422878a0d5893358f3561fb545748c5a91f1b1e6ed123f5bae2d1117b72c4605cfc08e68c7c2993fb86df0387a2abe7325
7
+ data.tar.gz: 8c563d0d7aebb402540852839b55e14c639c1a451e837345b3913f72f6674a3db894089a966d107cc80b3d65ea1c3f720d3716e278bfeac4397c3231dca5c141
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(35)} : #{version.ljust(9)} : #{file_path}"
18
24
  end
@@ -81,8 +81,9 @@ module KBuilder
81
81
  # @option opts [String] :to Recipient email
82
82
  # @option opts [String] :body The email's body
83
83
  def add_file(file, **opts)
84
- full_file = target_file(file)
84
+ full_file = opts.key?(:folder_key) ? target_file(file, folder: opts[:folder_key]) : target_file(file)
85
85
 
86
+ # Need logging options that can log these internal details
86
87
  FileUtils.mkdir_p(File.dirname(full_file))
87
88
 
88
89
  content = process_any_content(**opts)
@@ -94,6 +95,42 @@ module KBuilder
94
95
 
95
96
  self
96
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
97
134
 
98
135
  # ----------------------------------------------------------------------
99
136
  # Attributes: Think getter/setter
@@ -134,8 +171,28 @@ module KBuilder
134
171
  end
135
172
 
136
173
  # Get target file
137
- def target_file(file_parts, folder: current_folder_key)
138
- 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)
139
196
  end
140
197
 
141
198
  # Template folder & Files
@@ -3,17 +3,25 @@
3
3
  module KBuilder
4
4
  # Base configuration object for all k_builder* GEM
5
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)
6
+ class << self
7
+ # Attach a child configuration with it's own settings to a parent configuration
8
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}")
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}")
14
20
 
15
- instance_variable_set("@#{accessor_name}", klass_me.new)
21
+ instance_variable_set("@#{accessor_name}", klass_child.new)
22
+ end
16
23
  end
24
+ alias attach_to attach_config_to_parent
17
25
  end
18
26
 
19
27
  # move out into module
@@ -22,13 +30,14 @@ module KBuilder
22
30
  instance_variables.each do |var|
23
31
  value = instance_variable_get(var)
24
32
 
25
- value = KBuilder.data.struct_to_hash(value) if complex_type?(value)
33
+ value = KUtil.data.to_hash(value) if complex_type?(value)
26
34
 
27
35
  hash[var.to_s.delete('@')] = value
28
36
  end
29
37
  hash
30
38
  end
31
39
 
40
+ # This code is being moved into k_util (data)
32
41
  # Any basic (aka primitive) type
33
42
  def basic_type?(value)
34
43
  value.is_a?(String) ||
@@ -19,9 +19,17 @@ module KBuilder
19
19
  yield(configuration)
20
20
  end
21
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
+ #
22
25
  # Configuration class
23
26
  class Configuration < BaseConfiguration
27
+ include KLog::Logging
28
+
29
+ # Target folders provide a set named folders that can be written to
24
30
  attr_accessor :target_folders
31
+
32
+ # Template folders provides layered folders that templates can exist within
25
33
  attr_accessor :template_folders
26
34
 
27
35
  def initialize
@@ -29,8 +37,8 @@ module KBuilder
29
37
  # @target_folder = Dir.getwd
30
38
  # @template_folder = File.join(Dir.getwd, '.templates')
31
39
  # @global_template_folder = nil
32
- @target_folders = NamedFolders.new
33
- @template_folders = LayeredFolders.new
40
+ @target_folders = KType::NamedFolders.new
41
+ @template_folders = KType::LayeredFolders.new
34
42
  end
35
43
 
36
44
  def initialize_copy(orig)
@@ -42,19 +50,22 @@ module KBuilder
42
50
 
43
51
  # rubocop:disable Metrics/AbcSize
44
52
  def debug
45
- puts '-' * 120
46
- puts 'kbuilder base configuration'
53
+ log.subheading 'kbuilder base configuration'
47
54
 
48
- puts 'target_folders'
55
+ log.section_heading 'target_folders'
49
56
  target_folders.folders.each_key do |key|
50
57
  folder = target_folders.folders[key]
51
- kv key.to_s, folder
58
+ log.kv key.to_s, folder
52
59
  end
60
+ log.info ''
61
+
62
+ log.section_heading 'template folders (search order)'
53
63
 
54
- puts 'template folders (search order)'
55
- template_folders.ordered_folders.each do |folder|
56
- puts folder.to_s
64
+ template_folders.ordered_keys.each do |key|
65
+ folder = template_folders.folders[key]
66
+ log.kv key.to_s, folder
57
67
  end
68
+ ''
58
69
  end
59
70
  # rubocop:enable Metrics/AbcSize
60
71
  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
1
  # frozen_string_literal: true
2
2
 
3
3
  module KBuilder
4
- VERSION = '0.0.40'
4
+ VERSION = '0.0.57'
5
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.40
4
+ version: 0.0.57
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-19 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