k_builder 0.0.63 → 0.0.68

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1 @@
1
+ /Users/davidcruwys/dev/slides-addons/highlight_css
@@ -0,0 +1,7 @@
1
+ <html>
2
+ <head><title>404 Not Found</title></head>
3
+ <body bgcolor="white">
4
+ <center><h1>404 Not Found</h1></center>
5
+ <hr><center>nginx</center>
6
+ </body>
7
+ </html>
@@ -1,21 +1,38 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module KBuilder
4
+ # TODO: Why is this called BaseBuilder, why not just builder
5
+ # TODO: Is this really the builder pattern, it could be the class used by a director
6
+ # but it is not really storing information for builder purposes.
7
+ #
4
8
  # Base builder defines builder methods, build method and configuration
5
9
  #
6
10
  # Convention: Setter methods (are Fluent) and use the prefix set_
7
11
  # Getter methods (are NOT fluent) and return the stored value
8
12
  # Setter methods (are NOT fluent) can be created as needed
9
13
  # these methods would not be prefixed with the set_
14
+
15
+ # process_any_content(content: 'abc')
16
+ # process_any_content(content_file: 'abc.txt')
17
+ # process_any_content(template: 'abc {{name}}', name: 'sean')
18
+ # process_any_content(template_file: 'abc.txt', name: 'sean')
19
+
20
+ # process_any_content(content_gist: 'https://gist.github.com/klueless-io/8d4b6d199dbe4a5d40807a47fff8ed1c')
21
+ # process_any_content(template_gist: 'https://gist.github.com/klueless-io/8d4b6d199dbe4a5d40807a47fff8ed1c', name: 'sean')
22
+
10
23
  class BaseBuilder
11
24
  include KLog::Logging
12
25
 
13
26
  attr_reader :configuration
14
27
 
15
28
  attr_accessor :target_folders
16
-
17
29
  attr_accessor :template_folders
18
30
 
31
+ attr_accessor :last_output_file
32
+ attr_accessor :last_output_folder
33
+ # attr_accessor :last_template
34
+ attr_accessor :last_template_file
35
+
19
36
  # Factory method that provides a builder for a specified structure
20
37
  # runs through a configuration block and then builds the final structure
21
38
  #
@@ -59,6 +76,7 @@ module KBuilder
59
76
  }
60
77
  end
61
78
 
79
+ # rubocop:disable Metrics/AbcSize
62
80
  def debug
63
81
  log.subheading 'kbuilder'
64
82
 
@@ -69,8 +87,16 @@ module KBuilder
69
87
  log.info ''
70
88
 
71
89
  template_folders.debug(title: 'template folders (search order)')
90
+
91
+ log.info ''
92
+ log.kv 'last output file' , last_output_file
93
+ log.kv 'last output folder' , last_output_folder
94
+ # log.kv 'last template' , last_template
95
+ log.kv 'last template file' , last_template_file
96
+
72
97
  ''
73
98
  end
99
+ # rubocop:enable Metrics/AbcSize
74
100
 
75
101
  # ----------------------------------------------------------------------
76
102
  # Fluent interface
@@ -95,31 +121,92 @@ module KBuilder
95
121
  # Extra options will be used as data for templates, e.g
96
122
  # @option opts [String] :to Recipient email
97
123
  # @option opts [String] :body The email's body
124
+ def add_file_command(file, **opts)
125
+ {
126
+ action: :add_file,
127
+ file: file,
128
+ opts: opts
129
+ }
130
+ end
131
+
132
+ # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
98
133
  def add_file(file, **opts)
99
134
  # move to command
100
- full_file = opts.key?(:folder_key) ? target_file(file, folder: opts[:folder_key]) : target_file(file)
135
+ full_file = target_file(file, **opts) # opts.key?(:folder_key) || opts.key?(:folder) ? target_file(file, folder: opts[:folder], folder_key: opts[:folder_key]) : target_file(file)
101
136
 
102
137
  # Need logging options that can log these internal details
103
- FileUtils.mkdir_p(File.dirname(full_file))
138
+ mkdir_p(File.dirname(full_file))
104
139
 
105
140
  content = process_any_content(**opts)
106
141
 
107
- File.write(full_file, content)
142
+ file_write(full_file, content, on_exist: opts[:on_exist])
108
143
 
109
144
  # Prettier needs to work with the original file name
110
- run_prettier file if opts.key?(:pretty)
145
+ run_prettier file if opts.key?(:pretty)
146
+ # TODO: Add test
147
+ run_cop(full_file, fix_safe: true) if opts.key?(:cop) || opts.key?(:ruby_cop)
148
+
111
149
  # Need support for rubocop -a
150
+ open_file(last_output_file) if opts.key?(:open)
151
+ open_file(last_template_file) if opts.key?(:open_template)
152
+ browse_file(last_output_file) if opts.key?(:browse)
153
+ pause(opts[:pause]) if opts[:pause]
112
154
 
113
155
  self
114
156
  end
157
+ # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity
158
+
159
+ def replay_commands(commands)
160
+ commands.each do |command|
161
+ case command[:action]
162
+ when :add_file
163
+ add_file(command[:file], command[:opts])
164
+ when :delete_file
165
+ delete_file(command[:file], command[:opts])
166
+ else
167
+ log.error "Unknown command: #{command[:action]}"
168
+ end
169
+ end
170
+ end
171
+
115
172
  alias touch add_file # it is expected that you would not supply any options, just a file name
116
173
 
174
+ def delete_file_command(file, **opts)
175
+ {
176
+ action: :delete_file,
177
+ file: file,
178
+ opts: opts
179
+ }
180
+ end
181
+
182
+ def delete_file(file, **opts)
183
+ full_file = target_file(file, **opts) # = opts.key?(:folder_key) ? target_file(file, folder: opts[:folder_key]) : target_file(file)
184
+
185
+ File.delete(full_file) if File.exist?(full_file)
186
+
187
+ self
188
+ end
189
+
190
+ def file_exist?(file, **opts)
191
+ # full_file = opts.key?(:folder_key) ? target_file(file, folder_key: opts[:folder_key]) : target_file(file)
192
+ full_file = target_file(file, **opts)
193
+
194
+ File.exist?(full_file)
195
+ end
196
+
197
+ # ToDo
198
+ # def delete_folder(file)
199
+ # FileUtils.remove_dir(path_to_directory) if File.directory?(path_to_directory)
200
+
201
+ # self
202
+ # end
203
+
117
204
  def make_folder(folder_key = nil, sub_path: nil)
118
205
  folder_key = current_folder_key if folder_key.nil?
119
206
  folder = target_folder(folder_key)
120
207
  folder = File.join(folder, sub_path) unless sub_path.nil?
121
208
 
122
- FileUtils.mkdir_p(folder)
209
+ mkdir_p(folder)
123
210
 
124
211
  self
125
212
  end
@@ -140,6 +227,8 @@ module KBuilder
140
227
 
141
228
  begin
142
229
  IO.popen('pbcopy', 'w') { |f| f << content }
230
+
231
+ open_file(last_template_file) if opts.key?(:open_template)
143
232
  rescue Errno::ENOENT => e
144
233
  if e.message == 'No such file or directory - pbcopy'
145
234
  # May want to use this GEM in the future
@@ -152,15 +241,82 @@ module KBuilder
152
241
  end
153
242
  alias clipboard_copy add_clipboard
154
243
 
155
- def vscode(*file_parts, folder: current_folder_key)
244
+ def vscode_command(*file_parts, folder_key: current_folder_key, file: nil)
245
+ {
246
+ action: :vscode,
247
+ file_parts: file_parts,
248
+ opts: { folder_key: folder_key, file: file }
249
+ }
250
+ end
251
+
252
+ def vscode(*file_parts, folder_key: current_folder_key, file: nil)
156
253
  # move to command
157
- file = target_file(*file_parts, folder: folder)
254
+ file = target_file(*file_parts, folder_key: folder_key) if file.nil?
158
255
 
159
256
  rc "code #{file}"
160
257
 
161
258
  self
162
259
  end
163
260
 
261
+ def browse_command(*file_parts, folder_key: current_folder_key, file: nil)
262
+ {
263
+ action: :browse,
264
+ file_parts: file_parts,
265
+ opts: { folder_key: folder_key, file: file }
266
+ }
267
+ end
268
+
269
+ def browse(*file_parts, folder_key: current_folder_key, file: nil)
270
+ # move to command
271
+ file = target_file(*file_parts, folder_key: folder_key) if file.nil?
272
+
273
+ rc "open -a \"Google Chrome\" #{file}"
274
+
275
+ self
276
+ end
277
+
278
+ def open
279
+ open_file(last_output_file)
280
+
281
+ self
282
+ end
283
+ alias o open
284
+
285
+ def open_template
286
+ open_file(last_template_file)
287
+
288
+ self
289
+ end
290
+ alias ot open_template
291
+
292
+ def open_file(file)
293
+ if file.nil?
294
+ log.warn('open_file will not open when file is nil')
295
+ return self
296
+ end
297
+
298
+ vscode(file: file)
299
+
300
+ self
301
+ end
302
+
303
+ def browse_file(file)
304
+ if file.nil?
305
+ log.warn('browse_file will not browse when file is nil')
306
+ return self
307
+ end
308
+
309
+ browse(file: file)
310
+
311
+ self
312
+ end
313
+
314
+ def pause(seconds = 1)
315
+ sleep(seconds)
316
+
317
+ self
318
+ end
319
+
164
320
  # ----------------------------------------------------------------------
165
321
  # Attributes: Think getter/setter
166
322
  #
@@ -216,12 +372,18 @@ module KBuilder
216
372
  # target_file('/abc.txt')
217
373
  # target_file('/xyz/abc.txt')
218
374
  # target_file('/xyz', 'abc.txt')
219
- def target_file(*file_parts, folder: current_folder_key)
375
+ def target_file(*file_parts, folder_key: current_folder_key, folder: nil, **)
376
+ # TODO: Mismatch (sometimes called folder, sometimes called folder_key:)
377
+ if folder
378
+ log.error("Change folder: to folder_key: for #{folder} - #{file_parts}")
379
+ return
380
+ end
381
+
220
382
  # Absolute path
221
383
  return File.join(*file_parts) if Pathname.new(file_parts.first).absolute?
222
384
 
223
- # Relative to :folder
224
- File.join(target_folder(folder), *file_parts)
385
+ # Relative to :folder_key
386
+ File.join(target_folder(folder_key), *file_parts)
225
387
  end
226
388
 
227
389
  # Template folder & Files
@@ -242,7 +404,8 @@ module KBuilder
242
404
  # Gets a template_file relative to the template folder, looks first in
243
405
  # local template folder and if not found, looks in global template folder
244
406
  def find_template_file(file_parts)
245
- template_folders.find_file(file_parts)
407
+ self.last_template_file = template_folders.find_file(file_parts)
408
+ last_template_file
246
409
  end
247
410
 
248
411
  # Building content from templates
@@ -268,15 +431,6 @@ module KBuilder
268
431
 
269
432
  return "content not found: #{opts[:content_file]}" if cf.nil?
270
433
 
271
- # cf = opts[:content_file]
272
-
273
- # unless File.exist?(cf)
274
- # cf_from_template_folders = find_template_file(cf)
275
- # return "Content not found: #{File.expand_path(cf)}" unless File.exist?(cf_from_template_folders)
276
-
277
- # cf = cf_from_template_folders
278
- # end
279
-
280
434
  File.read(cf)
281
435
  end
282
436
 
@@ -340,7 +494,7 @@ module KBuilder
340
494
  # Deep path create if needed
341
495
  tf = target_folder
342
496
 
343
- FileUtils.mkdir_p(tf)
497
+ mkdir_p(tf)
344
498
 
345
499
  build_command = "cd #{tf} && #{command}"
346
500
 
@@ -351,5 +505,46 @@ module KBuilder
351
505
  system(build_command)
352
506
  end
353
507
  alias rc run_command
508
+
509
+ def file_write(file, content, on_exist: :skip)
510
+ self.last_output_file = file # if file not found, we still want to record this as the last_output_file
511
+
512
+ not_found = !File.exist?(file)
513
+
514
+ if not_found
515
+ File.write(file, content)
516
+ return
517
+ end
518
+
519
+ return if %i[skip ignore].include?(on_exist)
520
+
521
+ if %i[overwrite write].include?(on_exist)
522
+ File.write(file, content)
523
+ return
524
+ end
525
+
526
+ return unless on_exist == :compare
527
+
528
+ vscompare(file, content)
529
+ end
530
+
531
+ def vscompare(file, content)
532
+ # need to use some sort of caching folder for this
533
+ ext = File.extname(file)
534
+ fn = File.basename(file, ext)
535
+ temp_file = Tempfile.new([fn, ext])
536
+
537
+ temp_file.write(content)
538
+ temp_file.close
539
+
540
+ return if File.read(file) == content
541
+
542
+ system("code -d #{file} #{temp_file.path}")
543
+ sleep 2
544
+ end
545
+
546
+ def mkdir_p(folder)
547
+ @last_output_folder = FileUtils.mkdir_p(folder).first
548
+ end
354
549
  end
355
550
  end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ module KBuilder
4
+ module Commands
5
+ # Run CodeSyntaxHighlighter against source code and produce a styled HTML representation
6
+ #
7
+ # Alternatives to Highlighter-js could be carbon-now and ray.so
8
+ class CodeSyntaxHighlighterCommand < BaseCommand
9
+ attr_reader :source_code
10
+ attr_reader :formatted_code
11
+
12
+ def initialize(source_code, **opts)
13
+ super(**opts)
14
+
15
+ self.source_code = source_code
16
+ end
17
+
18
+ def execute
19
+ return unless valid?
20
+
21
+ run
22
+ end
23
+
24
+ private
25
+
26
+ def source_code=(value)
27
+ @source_code = value
28
+
29
+ guard('Source code is required for formatting') if value.nil? || value.empty?
30
+ end
31
+
32
+ def run
33
+ # @formatted_code = ExecJS.eval("'red yellow blue'.split(' ')")
34
+
35
+ # # highlight_source = 'lib/k_builder/assets/a.js'
36
+ # highlight_source = 'lib/k_builder/assets/highlight.min.js'
37
+
38
+ # log.error ExecJS.runtime.name
39
+
40
+ # a = File.read(highlight_source)
41
+ # # context = ExecJS.compile(a)
42
+ # context = ExecJS.compile(highlight_source)
43
+ # context.call("html = hljs.highlightAuto('<h1>Hello World!</h1>').value")
44
+
45
+ # get_js_asset('highlight')
46
+ # get_js_asset('ruby')
47
+ end
48
+
49
+ # https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.0.1/highlight.min.js
50
+ # https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.0.1/languages/ruby.min.js
51
+
52
+ def get_js_asset(name)
53
+ url = "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.0.1/#{name}.min.js"
54
+ target_folder = 'lib/k_builder/assets'
55
+ file = "#{name}.min.js"
56
+
57
+ get_asset(url, target_folder, file)
58
+ end
59
+
60
+ def get_asset(url, target_folder, file)
61
+ local_asset_file = File.join(target_folder, file)
62
+
63
+ return if File.exist?(local_asset_file)
64
+
65
+ content = Net::HTTP.get(URI.parse(url))
66
+
67
+ File.write(local_asset_file, content)
68
+ end
69
+ end
70
+ end
71
+ end
@@ -5,18 +5,24 @@ module KBuilder
5
5
  # Configuration for webpack5/builder
6
6
  class << self
7
7
  attr_writer :configuration
8
- end
9
8
 
10
- def self.configuration
11
- @configuration ||= Configuration.new
12
- end
9
+ def configuration(name = :default)
10
+ @configuration ||= Hash.new do |h, key|
11
+ h[key] = KBuilder::Configuration.new
12
+ end
13
+ @configuration[name]
14
+ end
13
15
 
14
- def self.reset
15
- @configuration = Configuration.new
16
- end
16
+ def reset(name = :default)
17
+ @configuration ||= Hash.new do |h, key|
18
+ h[key] = KBuilder::Configuration.new
19
+ end
20
+ @configuration[name] = KBuilder::Configuration.new
21
+ end
17
22
 
18
- def self.configure
19
- yield(configuration)
23
+ def configure(name = :default)
24
+ yield(configuration(name))
25
+ end
20
26
  end
21
27
 
22
28
  # Does this class need to move out into k_types?
@@ -48,12 +54,16 @@ module KBuilder
48
54
  @template_folders = orig.template_folders.clone
49
55
  end
50
56
 
51
- def debug
52
- log.subheading 'kbuilder base configuration'
57
+ def debug(heading: 'kbuilder base configuration')
58
+ log.section_heading 'kbuilder base configuration' if heading
59
+
60
+ # TODO: Add name to configuration object
61
+ # Don't have support for name on the configuration object yet
62
+ # log.kv 'config name', name
53
63
 
54
64
  target_folders.debug(title: 'target_folders')
55
65
 
56
- log.info ''
66
+ # log.info ''
57
67
 
58
68
  template_folders.debug(title: 'template folders (search order)')
59
69
  ''
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module KBuilder
4
- VERSION = '0.0.63'
4
+ VERSION = '0.0.68'
5
5
  end
data/lib/k_builder.rb CHANGED
@@ -10,8 +10,11 @@ require 'k_builder/base_builder'
10
10
  require 'k_builder/base_configuration'
11
11
  require 'k_builder/configuration'
12
12
  require 'k_builder/file_segments'
13
+
14
+ # should commands be in their own gem?
13
15
  require 'k_builder/commands/base_command'
14
16
  require 'k_builder/commands/rubo_cop_command'
17
+ require 'k_builder/commands/code_syntax_highlighter_command'
15
18
 
16
19
  require 'handlebars/helpers/template'
17
20
 
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.63
4
+ version: 0.0.68
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-07-01 00:00:00.000000000 Z
11
+ date: 2022-01-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: handlebars-helpers
@@ -99,6 +99,9 @@ files:
99
99
  - README.md
100
100
  - Rakefile
101
101
  - STORIES.md
102
+ - Sample-original.xml
103
+ - Sample.drawio
104
+ - Sample.xml
102
105
  - USAGE.md
103
106
  - bin/console
104
107
  - bin/k
@@ -109,9 +112,15 @@ files:
109
112
  - hooks/update-version
110
113
  - k_builder.gemspec
111
114
  - lib/k_builder.rb
115
+ - lib/k_builder/assets/a.html
116
+ - lib/k_builder/assets/b.html
117
+ - lib/k_builder/assets/highlight.min.js
118
+ - lib/k_builder/assets/highlight_css
119
+ - lib/k_builder/assets/ruby.min.js
112
120
  - lib/k_builder/base_builder.rb
113
121
  - lib/k_builder/base_configuration.rb
114
122
  - lib/k_builder/commands/base_command.rb
123
+ - lib/k_builder/commands/code_syntax_highlighter_command.rb
115
124
  - lib/k_builder/commands/rubo_cop_command.rb
116
125
  - lib/k_builder/configuration.rb
117
126
  - lib/k_builder/file_segments.rb
@@ -145,7 +154,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
145
154
  - !ruby/object:Gem::Version
146
155
  version: '0'
147
156
  requirements: []
148
- rubygems_version: 3.2.7
157
+ rubygems_version: 3.2.33
149
158
  signing_key:
150
159
  specification_version: 4
151
160
  summary: K Builder provides various fluent builders for initializing applications