k_builder 0.0.1 → 0.0.23

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: d63754fbda587b7ea17d7ae17d4fb33029fac853280ce5125bfb1d7924c4ddfc
4
- data.tar.gz: 62d174cd9cf2b5ad60a43319875efffc6845a409ea1067b4cb01d916f69456cf
3
+ metadata.gz: 1e1de8ff91bc3e273459d6970c8c1c136184e9c0990b0645fa426888317640eb
4
+ data.tar.gz: b6a5856f4bbb628422968a80a212fc6fbb1515b19c2cc29160d9cf984faa2b40
5
5
  SHA512:
6
- metadata.gz: 53b98c935cb446629725ccb9a4bd4fa6babe87e985e7886ab2308592cb5413604063cb54eee5f439dfe79263b3d73d03c32c94cbe9ccb89eaf0599b1c655e9ea
7
- data.tar.gz: 985ad06c8e9a92f5e79eab2167b35cebee0940ae87bd9044e3de466c09786364444cbffafe7441bef59f8d031186106ffc317d9ddc91dc6c9288066db670f548
6
+ metadata.gz: 62e85ea3f17a20cbc3bd180b74a057caab722d37de1bdb008353839f5f0159f564b69a4bcee9124857c7d24fe5b7b46afe967b86e52aaac7009960a663294886
7
+ data.tar.gz: 51a3c0374b57f0cfebc099df6d86c7657b50815185ea60f71e37cc9f27c5edf4afbb1933e727c1e68b81b179b079f7666c89a9273e971d7aa72fdb74e0411942
data/.rubocop.yml CHANGED
@@ -60,6 +60,9 @@ Naming/MemoizedInstanceVariableName:
60
60
  Naming/VariableNumber:
61
61
  Exclude:
62
62
  - "**/spec/**/*"
63
+ Naming/AccessorMethodName:
64
+ Exclude:
65
+ - "**/*builder*.rb"
63
66
  Style/EmptyMethod:
64
67
  Exclude:
65
68
  - "**/spec/**/*"
data/Guardfile ADDED
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ guard :bundler, cmd: 'bundle install' do
4
+ watch('Gemfile')
5
+ watch('k_builder.gemspec')
6
+ end
7
+
8
+ group :green_pass_then_cop, halt_on_fail: true do
9
+ guard :rspec, cmd: 'bundle exec rspec -f doc' do
10
+ require 'guard/rspec/dsl'
11
+ dsl = Guard::RSpec::Dsl.new(self)
12
+
13
+ # RSpec files
14
+ rspec = dsl.rspec
15
+ watch(rspec.spec_helper) { rspec.spec_dir }
16
+ watch(rspec.spec_support) { rspec.spec_dir }
17
+ watch(rspec.spec_files)
18
+
19
+ # Ruby files
20
+ ruby = dsl.ruby
21
+ dsl.watch_spec_files_for(ruby.lib_files)
22
+ watch(%r{^lib/k_builder/(.+)\.rb$}) { |m| "spec/unit/#{m[1]}_spec.rb" }
23
+ watch(%r{^lib/k_builder/commands/(.+)\.rb$}) { |m| "spec/unit/commands/#{m[1]}_spec.rb" }
24
+ end
25
+
26
+ guard :rubocop, all_on_start: false, cli: ['--format', 'clang'] do
27
+ watch(/{.+\.rb$/)
28
+ watch(%r{(?:.+/)?\.rubocop(?:_todo)?\.yml$}) { |m| File.dirname(m[0]) }
29
+ end
30
+ end
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # K Builder
2
2
 
3
- > K Builder provides various fluent builders for initializing applications with different language requirements
3
+ > KBuilder provides various fluent builders and code generators for initializing applications with different language requirements
4
4
 
5
5
  ## Installation
6
6
 
@@ -26,16 +26,52 @@ gem install k_builder
26
26
 
27
27
  ### Main Story
28
28
 
29
-
29
+ 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
30
30
 
31
31
  See all [stories](./STORIES.md)
32
32
 
33
-
34
33
  ## Usage
35
34
 
36
35
  See all [usage examples](./USAGE.md)
37
36
 
37
+ ### Basic Example
38
+
39
+ #### Configure and Run
40
+
41
+ Setup configuration for KBuilder
42
+
43
+ Generate two files:
38
44
 
45
+ 1. main.rb is based on class.rb from app_template
46
+ 2. configuration.log.txt is based on an inline template
47
+
48
+ Check out usage.md for more details
49
+
50
+ ```ruby
51
+ usecases_folder = File.join(Dir.getwd, 'spec', 'usecases')
52
+
53
+ KBuilder.configure do |config|
54
+ config.template_folder = File.join(usecases_folder, '.app_template')
55
+ config.global_template_folder = File.join(usecases_folder, '.global_template')
56
+ config.target_folder = File.join(usecases_folder, '.output')
57
+ end
58
+
59
+ template = <<~TEXT
60
+ Configured Template Folder : {{a}}
61
+ Configured Global Template Folder : {{b}}
62
+ Configured Output Folder : {{c}}
63
+ TEXT
64
+
65
+ builder = KBuilder::Builder.init
66
+
67
+ builder.add_file('main.rb', template_file: 'class.rb', name: 'main').add_file(
68
+ 'configuration.log.txt',
69
+ template: template,
70
+ a: builder.template_folder,
71
+ b: builder.global_template_folder,
72
+ c: builder.target_folder
73
+ )
74
+ ```
39
75
 
40
76
  ## Development
41
77
 
@@ -45,7 +81,7 @@ Checkout the repo
45
81
  git clone klueless-io/k_builder
46
82
  ```
47
83
 
48
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests.
84
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests.
49
85
 
50
86
  You can also run `bin/console` for an interactive prompt that will allow you to experiment.
51
87
 
data/STORIES.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # K Builder
2
2
 
3
- > K Builder provides various fluent builders for initializing applications with different language requirements
3
+ > KBuilder provides various fluent builders and code generators for initializing applications with different language requirements
4
4
 
5
5
  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
6
6
 
@@ -8,26 +8,21 @@ As a Polyglot Developer, I want to be up and running in any development language
8
8
 
9
9
  ### Stories next on list
10
10
 
11
- As a Developer, I can DO_SOMETHING, so that I QUALITY_OF_LIFE
12
-
13
- - Subtask
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]
14
12
 
15
13
  ### Tasks next on list
16
14
 
17
- Setup RubyGems and RubyDoc
18
-
19
- - Build and deploy gem to [rubygems.org](https://rubygems.org/gems/k_builder)
20
- - Attach documentation to [rubydoc.info](https://rubydoc.info/github/to-do-/k_builder/master)
21
-
22
- Setup GitHub Action (test and lint)
23
-
24
- - Setup Rspec action
25
- - Setup RuboCop action
15
+ BaseBuilder
26
16
 
27
17
  ## Stories and tasks
28
18
 
29
19
  ### Tasks - completed
30
20
 
21
+ Setup RubyGems and RubyDoc
22
+
23
+ - Build and deploy gem to [rubygems.org](https://rubygems.org/gems/k_builder)
24
+ - Attach documentation to [rubydoc.info](https://rubydoc.info/github/to-do-/k_builder/master)
25
+
31
26
  Setup project management, requirement and SCRUM documents
32
27
 
33
28
  - Setup readme file
@@ -35,6 +30,11 @@ Setup project management, requirement and SCRUM documents
35
30
  - Setup a project backlog
36
31
  - Setup an examples/usage document
37
32
 
33
+ Setup GitHub Action (test and lint)
34
+
35
+ - Setup Rspec action
36
+ - Setup RuboCop action
37
+
38
38
  Setup new Ruby GEM
39
39
 
40
40
  - Build out a standard GEM structure
data/USAGE.md CHANGED
@@ -1,19 +1,104 @@
1
1
  # K Builder
2
2
 
3
- > K Builder provides various fluent builders for initializing applications with different language requirements
3
+ > KBuilder provides various fluent builders and code generators for initializing applications with different language requirements
4
4
 
5
5
  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
6
6
 
7
7
  ## Usage
8
8
 
9
- ### Sample Classes
9
+ ### Configure And Build
10
10
 
11
- #### Simple example
12
-
13
- Description for a simple example that shows up in the USAGE.MD
11
+ Print the configuration
14
12
 
15
13
  ```ruby
16
- class SomeRuby
17
- def initialize; end
14
+ usecases_folder = File.join(Dir.getwd, 'spec', 'usecases')
15
+
16
+ KBuilder.configure do |config|
17
+ config.template_folder = File.join(usecases_folder, '.app_template')
18
+ config.global_template_folder = File.join(usecases_folder, '.global_template')
19
+ config.target_folder = File.join(usecases_folder, '.output')
18
20
  end
21
+
22
+ puts JSON.pretty_generate(KBuilder.configuration.to_hash)
23
+ ```
24
+
25
+ ```javascript
26
+ {
27
+ "target_folder": "/Users/name/dev/kgems/k_builder/spec/usecases/.output",
28
+ "template_folder": "/Users/name/dev/kgems/k_builder/spec/usecases/.app_template",
29
+ "global_template_folder": "/Users/name/dev/kgems/k_builder/spec/usecases/.global_template"
30
+ }
19
31
  ```
32
+
33
+ #### Folder Structure (starting)
34
+
35
+ Example folder structure for this usecase before running the builder
36
+
37
+ > Note: app-templates will take preference over global templates
38
+
39
+ ![](_usage_folder_before.png)
40
+
41
+ #### Run builder
42
+
43
+ This example builder will add 4 files into the output folder.
44
+
45
+ 1. `main.rb` is based on `class.rb` from `app_template`
46
+ 2. `person.rb` & `address.rb` are based on `model.rb` from `global_template`
47
+ 3. `configuration.log.txt` is based on an inline template
48
+
49
+ ```ruby
50
+ template = <<~TEXT
51
+ Configured Template Folder : {{a}}
52
+ Configured Global Template Folder : {{b}}
53
+ Configured Output Folder : {{c}}
54
+ TEXT
55
+
56
+ builder = KBuilder::Builder.init
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
+
78
+ ```
79
+
80
+ #### Folder Structure (after)
81
+
82
+ Folder structure after running the builder
83
+
84
+ ![](_usage_folder_after.png)
85
+
86
+ #### main.rb
87
+
88
+ ![main.rb](_out1.png)
89
+
90
+ #### person.rb
91
+
92
+ ![](_out2.png)
93
+
94
+ #### address.rb
95
+
96
+ ![person.rb](_out3.png)
97
+
98
+ #### configuration.log.txt
99
+
100
+ ![configuration.log.txt](_out4.png)
101
+
102
+ #### css/index.css
103
+
104
+ ![css/index.css](_out5.png)
data/_out1.png ADDED
Binary file
data/_out2.png ADDED
Binary file
data/_out3.png ADDED
Binary file
data/_out4.png ADDED
Binary file
data/_out5.png ADDED
Binary file
Binary file
Binary file
data/k_builder.gemspec CHANGED
@@ -13,7 +13,7 @@ Gem::Specification.new do |spec|
13
13
  spec.description = <<-TEXT
14
14
  K Builder provides various fluent builders for initializing applications with different language requirements
15
15
  TEXT
16
- spec.homepage = 'http://appydave.com/gems/k-builder'
16
+ spec.homepage = 'http://appydave.com' # /gems/k-builder'
17
17
  spec.license = 'MIT'
18
18
 
19
19
  # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
@@ -38,5 +38,7 @@ Gem::Specification.new do |spec|
38
38
  spec.require_paths = ['lib']
39
39
  # spec.extensions = ['ext/k_builder/extconf.rb']
40
40
 
41
- # spec.add_dependency 'tty-box', '~> 0.5.0'
41
+ spec.add_dependency 'handlebars-helpers', '~> 0'
42
+ # spec.add_dependency "anyway_config" , ">= 2.0.0"
43
+ # spec.add_dependency "config" , ">= 3.0.0"
42
44
  end
data/lib/k_builder.rb CHANGED
@@ -1,6 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'k_builder/version'
4
+ require 'k_builder/base_configuration'
5
+ require 'k_builder/configuration'
6
+ require 'k_builder/base_builder'
7
+ require 'k_builder/builder'
8
+
9
+ require 'handlebars/helpers/template'
4
10
 
5
11
  module KBuilder
6
12
  # raise KBuilder::Error, 'Sample message'
@@ -0,0 +1,131 @@
1
+ # frozen_string_literal: true
2
+
3
+ module KBuilder
4
+ # Base builder defines builder methods, build method and configuration
5
+ #
6
+ # Convention: Setter methods (are Fluent) and use the prefix set_
7
+ # Getter methods (are NOT fluent) and return the stored value
8
+ # Setter methods (are NOT fluent) can be created as needed
9
+ # these methods would not be prefixed with the set_
10
+ class BaseBuilder
11
+ attr_reader :hash
12
+
13
+ # Factory method that provides a builder for a specified structure
14
+ # runs through a configuration block and then builds the final structure
15
+ #
16
+ # @return [type=Object] data structure
17
+ def self.build
18
+ init.build
19
+ end
20
+
21
+ # Create and initialize the builder.
22
+ #
23
+ # Initialization can be done via any of these three sequential steps.
24
+ # - Configuration hash
25
+ # - After new event
26
+ # - Configuration block (lambda)
27
+ #
28
+ # @return [Builder] Returns the builder via fluent interface
29
+ def self.init(configuration = nil)
30
+ builder = new(configuration)
31
+
32
+ builder.after_new
33
+
34
+ yield(builder) if block_given?
35
+
36
+ builder
37
+ end
38
+
39
+ # Use after_new to massage hash values that come in via
40
+ # configuration into more complex values
41
+ #
42
+ # Abstract method
43
+ def after_new; end
44
+
45
+ # assigns a builder hash and defines builder methods
46
+ def initialize(configuration = nil)
47
+ @hash = {}
48
+
49
+ unless configuration.nil?
50
+ raise KBuilder::StandardError, 'Unknown configuration object' unless configuration.is_a?(Hash)
51
+
52
+ hash.merge!(configuration)
53
+ end
54
+
55
+ define_builder_setter_methods
56
+ end
57
+
58
+ # Return an array of symbols to represent the fluent
59
+ # setter methods that you want on your builder.
60
+ #
61
+ # Abstract method
62
+ def builder_setter_methods
63
+ raise NotImplementedError
64
+ end
65
+
66
+ # @return [Hash/StrongType] Returns data object, can be a hash
67
+ # or strong typed object that you
68
+ # have wrapped around the hash
69
+ def build
70
+ hash
71
+ end
72
+
73
+ # TODO
74
+ # Support Nesting
75
+ # Support Generation fo the following
76
+ # - fluent set_
77
+ # - Support setter (non-fluent)
78
+ # - Support getter (non-fluent)
79
+
80
+ # # builds a nested structure by either builder block or hash
81
+ # # @param data_structure [type=DataStructure]
82
+ # # @param builder [type=Builder]
83
+ # # @param attributes [type=Hash|DataStructure instance]
84
+ # # @param &block
85
+ # #
86
+ # # @return [type=Hash]
87
+ # def build_nested(data_structure, builder, attributes = {}, &block)
88
+ # if block_given?
89
+ # builder.build(&block).to_h
90
+ # else
91
+ # build_hash(data_structure, attributes)
92
+ # end
93
+ # end
94
+
95
+ private
96
+
97
+ # #
98
+ # # @param data_structure [type=DataStructure]
99
+ # # @param attributes [type=Hash, DataStructure]
100
+ # #
101
+ # # @return [type=Hash]
102
+ # def build_hash(data_structure, attributes)
103
+ # if attributes.is_a?(data_structure)
104
+ # attributes.to_h
105
+ # else
106
+ # data_structure.new(attributes).to_h
107
+ # end
108
+ # end
109
+
110
+ # Defines all of the necessary builder setter methods
111
+ #
112
+ # @return [Builder] Returns the builder via fluent interface
113
+ def define_builder_setter_methods
114
+ builder_setter_methods.each { |method| define_builder_method(method) }
115
+ self
116
+ end
117
+
118
+ # Defines a method using the convention set_[method_name]
119
+ #
120
+ # Convention: Setter methods (are Fluent) and use the prefix set_
121
+ # Getter methods (are NOT fluent) and return the stored value
122
+ #
123
+ # @return [Builder] Returns the builder via fluent interface
124
+ def define_builder_method(method_name)
125
+ self.class.send(:define_method, "set_#{method_name}") do |value|
126
+ @hash[method_name.to_s] = value
127
+ self
128
+ end
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ module KBuilder
4
+ # Base configuration object for all k_builder* GEM
5
+ class BaseConfiguration
6
+ def to_hash
7
+ hash = {}
8
+ instance_variables.each { |var| hash[var.to_s.delete('@')] = instance_variable_get(var) }
9
+ hash
10
+ end
11
+
12
+ def kv(name, value)
13
+ puts "#{name.rjust(30)} : #{value}"
14
+ end
15
+
16
+ # All of this code should be extracted into a module
17
+ #
18
+ # The module should then be extracted out into a GEM so that
19
+ # I can include it as needed. The GEM might be called
20
+ # (dynamic attributes) and would allow a regular class to act like an OpenStruct
21
+ # K-DSL uses data hash, while base configuration uses instance variables
22
+
23
+ def respond_to_missing?(name, *_args, &_block)
24
+ # puts 'respond_to_missing?'
25
+ # puts "respond_to_missing: #{name}"
26
+ n = name.to_s
27
+ n = n[0..-2] if n.end_with?('=')
28
+
29
+ if n.end_with?('?')
30
+ super
31
+ else
32
+ # This has not been fully tested
33
+ instance_variable_defined?("@#{n}") || super
34
+ end
35
+ end
36
+
37
+ def method_missing(name, *args, &_block)
38
+ # puts "method_missing: #{name}"
39
+ # puts "args.length : #{args.length}"
40
+
41
+ add_getter_or_param_method(name)
42
+ add_setter_method(name)
43
+
44
+ send(name, args[0]) if args.length == 1 # name.end_with?('=')
45
+
46
+ super unless self.class.method_defined?(name)
47
+ end
48
+
49
+ # Handles Getter method and method with single parameter
50
+ # object.my_name
51
+ # object.my_name('david')
52
+ def add_getter_or_param_method(name)
53
+ # L.progress(1, 'add_getter_or_param_method')
54
+ self.class.class_eval do
55
+ # L.progress(2, 'add_getter_or_param_method')
56
+ name = name.to_s.gsub(/=$/, '')
57
+ # L.progress(3, 'add_getter_or_param_method')
58
+ # L.kv 'name', name
59
+ define_method(name) do |*args|
60
+ # L.progress(4, 'add_getter_or_param_method')
61
+ # L.kv 'add_getter_or_param_method', name
62
+ raise KBuilder::Error, 'Multiple setting values is not supported' if args.length > 1
63
+
64
+ if args.length.zero?
65
+ get_value(name)
66
+ else
67
+ send("#{name}=", args[0])
68
+ end
69
+ end
70
+ end
71
+ end
72
+
73
+ # Handles Setter method
74
+ # object.my_name = 'david'
75
+ def add_setter_method(name)
76
+ # L.progress(1, 'add_setter_method')
77
+ self.class.class_eval do
78
+ # L.progress(2, 'add_setter_method')
79
+ name = name.to_s.gsub(/=$/, '')
80
+ # L.progress(3, 'add_setter_method')
81
+ # L.kv 'add_setter_method', name
82
+ define_method("#{name}=") do |value|
83
+ # L.progress(4, 'add_setter_method')
84
+ # L.kv 'name', name
85
+ # L.kv 'value', value
86
+ instance_variable_set("@#{name}", value)
87
+ # my_data[name.to_s] = value
88
+ end
89
+ end
90
+ end
91
+
92
+ def get_value(name)
93
+ instance_variable_get("@#{name}")
94
+ end
95
+ end
96
+
97
+ # class L
98
+ # def self.progress(index, label)
99
+ # puts "#{index} - #{label}"
100
+ # end
101
+
102
+ # def self.kv(name, value)
103
+ # puts "#{name.rjust(30)} : #{value}"
104
+ # end
105
+ # end
106
+ end
@@ -0,0 +1,258 @@
1
+ # frozen_string_literal: true
2
+
3
+ module KBuilder
4
+ # Base builder defines builder methods, build method and configuration
5
+ class Builder < KBuilder::BaseBuilder
6
+ # builder_setter_methods = %w[].freeze
7
+ # target_folder
8
+ # template_folder
9
+ # global_template_folder
10
+
11
+ def initialize(configuration = nil)
12
+ configuration = KBuilder.configuration.to_hash if configuration.nil?
13
+
14
+ super(configuration)
15
+ end
16
+
17
+ # rubocop:disable Metrics/AbcSize
18
+ def after_new
19
+ # ensure that any configured folders are expanded
20
+ self.target_folder = hash['target_folder'] unless hash['target_folder'].nil?
21
+ self.template_folder = hash['template_folder'] unless hash['template_folder'].nil?
22
+ self.global_template_folder = hash['global_template_folder'] unless hash['global_template_folder'].nil?
23
+ end
24
+ # rubocop:enable Metrics/AbcSize
25
+
26
+ # Return an array of symbols to represent the fluent setter methods in this builder.
27
+ def builder_setter_methods
28
+ # Currently I have manually created my settings because I needed custom
29
+ # logic in the settings to handle path expansion
30
+ []
31
+ end
32
+
33
+ # def build
34
+ # # SomeDryStruct.new(hash)
35
+ # end
36
+
37
+ # ----------------------------------------------------------------------
38
+ # Fluent interface
39
+ # ----------------------------------------------------------------------
40
+
41
+ # Add a file to the target location
42
+ #
43
+ # @param [String] file The file name with or without relative path, eg. my_file.json or src/my_file.json
44
+ # @option opts [String] :content Supply the content that you want to write to the file
45
+ # @option opts [String] :template Supply the template that you want to write to the file, template will be processed ('nobody') From address
46
+ # @option opts [String] :content_file File with content, file location is based on where the program is running
47
+ # @option opts [String] :template_file File with handlebars templated content that will be transformed, file location is based on the configured template_path
48
+ #
49
+ # Extra options will be used as data for templates, e.g
50
+ # @option opts [String] :to Recipient email
51
+ # @option opts [String] :body The email's body
52
+ def add_file(file, **opts)
53
+ full_file = target_file(file)
54
+
55
+ FileUtils.mkdir_p(File.dirname(full_file))
56
+
57
+ content = process_any_content(**opts)
58
+
59
+ File.write(full_file, content)
60
+
61
+ # Prettier needs to work with the original file name
62
+ run_prettier file if opts.key?(:pretty)
63
+
64
+ self
65
+ end
66
+
67
+ # ----------------------------------------------------------------------
68
+ # Attributes: Think getter/setter
69
+ #
70
+ # The following getter/setters can be referenced both inside and outside
71
+ # of the fluent builder fluent API. They do not implement the fluent
72
+ # interface unless prefixed by set_.
73
+ #
74
+ # set_: Only setters with the prefix _set are considered fluent.
75
+ # ----------------------------------------------------------------------
76
+
77
+ # Target folder
78
+ # ----------------------------------------------------------------------
79
+
80
+ # Fluent setter for target folder
81
+ def set_target_folder(value)
82
+ self.target_folder = value
83
+
84
+ self
85
+ end
86
+
87
+ # Setter for target folder
88
+ def target_folder=(value)
89
+ hash['target_folder'] = File.expand_path(value)
90
+ end
91
+
92
+ # Getter for target folder
93
+ def target_folder
94
+ hash['target_folder']
95
+ end
96
+
97
+ # Template folder
98
+ # ----------------------------------------------------------------------
99
+
100
+ # Fluent setter for template folder
101
+ def set_template_folder(value)
102
+ self.template_folder = value
103
+
104
+ self
105
+ end
106
+
107
+ # Setter for template folder
108
+ # Refactor: Make Private
109
+ def template_folder=(value)
110
+ hash['template_folder'] = File.expand_path(value)
111
+ end
112
+
113
+ # Getter for template folder
114
+ # Refactor: generate
115
+ def template_folder
116
+ hash['template_folder']
117
+ end
118
+
119
+ # Global Target folder
120
+ # ----------------------------------------------------------------------
121
+
122
+ # Fluent setter for global template folder
123
+ def set_global_template_folder(value)
124
+ self.global_template_folder = value
125
+
126
+ self
127
+ end
128
+
129
+ # Setter for global template folder
130
+ # Refactor: Make Private
131
+ def global_template_folder=(value)
132
+ hash['global_template_folder'] = File.expand_path(value)
133
+ end
134
+
135
+ # Setter for global template folder
136
+ # Refactor: generate
137
+ def global_template_folder
138
+ hash['global_template_folder']
139
+ end
140
+
141
+ # Internal Actions are considered helpers for the builder, they do
142
+ # something useful, but they do not tend to implement fluent interfaces.
143
+ #
144
+ # They some times do actions, they sometimes return information.
145
+ #
146
+ # NOTE: [SRP] - These methods should probably be converted into objects
147
+ # ----------------------------------------------------------------------
148
+
149
+ # Gets a target_file relative to target folder
150
+ def target_file(file)
151
+ File.join(target_folder, file)
152
+ end
153
+
154
+ # Gets a template_file relative to the template folder
155
+ def template_file(file)
156
+ File.join(template_folder, file)
157
+ end
158
+
159
+ # Gets a global_template_file relative to the global template folder
160
+ def global_template_file(file)
161
+ File.join(global_template_folder, file)
162
+ end
163
+
164
+ # Gets a template_file relative to the template folder, looks first in
165
+ # local template folder and if not found, looks in global template folder
166
+ def find_template_file(file)
167
+ full_file = template_file(file)
168
+ return full_file if File.exist?(full_file)
169
+
170
+ full_file = global_template_file(file)
171
+ return full_file if File.exist?(full_file)
172
+
173
+ # File not found
174
+ nil
175
+ end
176
+
177
+ # Use content from a a selection of content sources
178
+ #
179
+ # @option opts [String] :content Just pass through the :content as is.
180
+ # @option opts [String] :content_file Read content from the :content_file
181
+ #
182
+ # Future options
183
+ # @option opts [String] :content_loren [TODO]Create Loren Ipsum text as a :content_loren count of words
184
+ # @option opts [String] :content_url Read content from the :content_url
185
+ #
186
+ # @return Returns some content
187
+ def use_content(**opts)
188
+ return opts[:content] unless opts[:content].nil?
189
+
190
+ return unless opts[:content_file]
191
+
192
+ cf = opts[:content_file]
193
+
194
+ return "Content not found: #{File.expand_path(cf)}" unless File.exist?(cf)
195
+
196
+ File.read(cf)
197
+ end
198
+
199
+ # Use template from a a selection of template sources
200
+ #
201
+ # @option opts [String] :template Just pass through the :template as is.
202
+ # @option opts [String] :template_file Read template from the :template_file
203
+ #
204
+ # @return Returns some template
205
+ def use_template(**opts)
206
+ return opts[:template] unless opts[:template].nil?
207
+
208
+ return unless opts[:template_file]
209
+
210
+ tf = find_template_file(opts[:template_file])
211
+
212
+ return "template not found: #{opts[:template_file]}" if tf.nil?
213
+
214
+ File.read(tf)
215
+ end
216
+
217
+ # Process content will take any one of the following
218
+ # - Raw content
219
+ # - File based content
220
+ # - Raw template (translated via handlebars)
221
+ # - File base template (translated via handlebars)
222
+ #
223
+ # Process any of the above inputs to create final content output
224
+ #
225
+ # @option opts [String] :content Supply the content that you want to write to the file
226
+ # @option opts [String] :template Supply the template that you want to write to the file, template will be transformed using handlebars
227
+ # @option opts [String] :content_file File with content, file location is based on where the program is running
228
+ # @option opts [String] :template_file File with handlebars templated content that will be transformed, file location is based on the configured template_path
229
+ def process_any_content(**opts)
230
+ raw_content = use_content(**opts)
231
+
232
+ return raw_content if raw_content
233
+
234
+ template_content = use_template(**opts)
235
+
236
+ Handlebars::Helpers::Template.render(template_content, opts) unless template_content.nil?
237
+ end
238
+
239
+ def run_prettier(file, log_level: :log)
240
+ # command = "prettier --check #{file} --write #{file}"
241
+ command = "npx prettier --loglevel #{log_level} --write #{file}"
242
+
243
+ run_command command
244
+ end
245
+
246
+ def run_command(command)
247
+ # Deep path create if needed
248
+ FileUtils.mkdir_p(target_folder)
249
+
250
+ build_command = "cd #{target_folder} && #{command}"
251
+
252
+ puts build_command
253
+
254
+ system(build_command)
255
+ end
256
+ alias rc run_command
257
+ end
258
+ end
@@ -0,0 +1,43 @@
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_folder
25
+ attr_accessor :template_folder
26
+ attr_accessor :global_template_folder
27
+
28
+ def initialize
29
+ super
30
+ @target_folder = Dir.getwd
31
+ @template_folder = File.join(Dir.getwd, '.templates')
32
+ @global_template_folder = nil
33
+ end
34
+
35
+ def debug
36
+ puts '-' * 120
37
+ puts 'kbuilder base configuration'
38
+ kv 'target_folder' , target_folder
39
+ kv 'template_folder' , template_folder
40
+ kv 'global_template_folder', global_template_folder
41
+ end
42
+ end
43
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module KBuilder
4
- VERSION = '0.0.1'
4
+ VERSION = '0.0.23'
5
5
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: k_builder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.23
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-10 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2021-03-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: handlebars-helpers
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  description: " K Builder provides various fluent builders for initializing applications
14
28
  with different language requirements\n"
15
29
  email:
@@ -24,11 +38,19 @@ files:
24
38
  - ".rubocop.yml"
25
39
  - CODE_OF_CONDUCT.md
26
40
  - Gemfile
41
+ - Guardfile
27
42
  - LICENSE.txt
28
43
  - README.md
29
44
  - Rakefile
30
45
  - STORIES.md
31
46
  - USAGE.md
47
+ - _out1.png
48
+ - _out2.png
49
+ - _out3.png
50
+ - _out4.png
51
+ - _out5.png
52
+ - _usage_folder_after.png
53
+ - _usage_folder_before.png
32
54
  - bin/console
33
55
  - bin/k
34
56
  - bin/kgitsync
@@ -38,12 +60,16 @@ files:
38
60
  - hooks/update-version
39
61
  - k_builder.gemspec
40
62
  - lib/k_builder.rb
63
+ - lib/k_builder/base_builder.rb
64
+ - lib/k_builder/base_configuration.rb
65
+ - lib/k_builder/builder.rb
66
+ - lib/k_builder/configuration.rb
41
67
  - lib/k_builder/version.rb
42
- homepage: http://appydave.com/gems/k-builder
68
+ homepage: http://appydave.com
43
69
  licenses:
44
70
  - MIT
45
71
  metadata:
46
- homepage_uri: http://appydave.com/gems/k-builder
72
+ homepage_uri: http://appydave.com
47
73
  source_code_uri: https://github.com/klueless-io/k_builder
48
74
  changelog_uri: https://github.com/klueless-io/k_builder/commits/master
49
75
  post_install_message: