k_builder 0.0.1 → 0.0.23

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: 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: