k_director 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a3e92a5f338e4a25768bc3de0b87f0c5a72f21cf2a19047912b53d825aabe07e
4
+ data.tar.gz: '080715415cbcd1aa473c6f9425fa4453e19a65b05be9457d799d24436b90b1aa'
5
+ SHA512:
6
+ metadata.gz: 1faaf9a00492813b5f2d90ef92106aa69629f3176eea5f605e5ba806b6a00c24367cc2ea7e1e02dd14f0f58b2f5ad44f1acf54eae873386718e2c2043747aab8
7
+ data.tar.gz: 477242c710691338688eebf2b1e1a41fd9ddfb4574f42bf30411fad3ecf50f069da734dbbded3d56a8f988c55f5a42734662fc822996176b83cbf06b24245f10
data/.builders/_.rb ADDED
@@ -0,0 +1,6 @@
1
+ require_relative './dsl/builders/dom_builder'
2
+ require_relative './dsl/builders/actions_builder'
3
+ require_relative './dsl/directors/base_director'
4
+ require_relative './dsl/directors/child_director'
5
+ require_relative './dsl/github_dsl'
6
+ require_relative './dsl/ruby_gem_dsl'
data/.builders/boot.rb ADDED
@@ -0,0 +1,71 @@
1
+ # Boot Sequence
2
+
3
+ include KLog::Logging
4
+
5
+ CONFIG_KEY = :k_director
6
+
7
+ log.kv 'working folder', Dir.pwd
8
+
9
+ Handlebars::Helpers.configure do |config|
10
+ config_file = File.join(Gem.loaded_specs['handlebars-helpers'].full_gem_path, '.handlebars_helpers.json')
11
+ config.helper_config_file = config_file
12
+
13
+ string_config_file = File.join(Gem.loaded_specs['handlebars-helpers'].full_gem_path, '.handlebars_string_formatters.json')
14
+ config.string_formatter_config_file = string_config_file
15
+ end
16
+
17
+ def camel
18
+ require 'handlebars/helpers/string_formatting/camel'
19
+ Handlebars::Helpers::StringFormatting::Camel.new
20
+ end
21
+
22
+ def titleize
23
+ require 'handlebars/helpers/string_formatting/titleize'
24
+ Handlebars::Helpers::StringFormatting::Titleize.new
25
+ end
26
+
27
+ def pluralize
28
+ require 'handlebars/helpers/inflection/pluralize'
29
+ Handlebars::Helpers::Inflection::Pluralize.new
30
+ end
31
+
32
+ def singularize
33
+ require 'handlebars/helpers/inflection/singularize'
34
+ Handlebars::Helpers::Inflection::Singularize.new
35
+ end
36
+
37
+ def dasherize
38
+ require 'handlebars/helpers/string_formatting/dasherize'
39
+ Handlebars::Helpers::StringFormatting::Dasherize.new
40
+ end
41
+
42
+ def k_builder
43
+ @k_builder ||= KBuilder::BaseBuilder.init(KBuilder.configuration(CONFIG_KEY))
44
+ end
45
+
46
+ KBuilder.configure(CONFIG_KEY) do |config|
47
+ builder_folder = Dir.pwd
48
+ base_folder = File.expand_path('../', builder_folder)
49
+ global_template = File.expand_path('~/dev/kgems/k_templates/templates')
50
+
51
+ config.template_folders.add(:global_template , global_template)
52
+ config.template_folders.add(:template , File.expand_path('.templates', Dir.pwd))
53
+
54
+ config.target_folders.add(:app , base_folder)
55
+ config.target_folders.add(:builder , builder_folder)
56
+ # config.target_folders.add(:tailwind_elements , global_template, 'tailwind', 'elements')
57
+ # config.target_folders.add(:data , :builder, 'data')
58
+ # config.target_folders.add(:database , :data, 'database')
59
+ end
60
+
61
+ KBuilder.configuration(CONFIG_KEY).debug
62
+
63
+ area = KManager.add_area(CONFIG_KEY)
64
+ resource_manager = area.resource_manager
65
+ resource_manager
66
+ .fileset
67
+ .glob('*.rb', exclude: ['boot.rb'])
68
+ .glob('generators/**/*.rb')
69
+ resource_manager.add_resources
70
+
71
+ KManager.fire_actions(:load_content, :register_document, :load_document)
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dsl
4
+ module Builders
5
+ class ActionsBuilder < Dsl::Builders::DomBuilder
6
+ def initialize
7
+ super(schema)
8
+ end
9
+
10
+ def queue_action(action)
11
+ dom[:actions] << current_node(action)
12
+ end
13
+
14
+ def actions
15
+ dom[:actions]
16
+ end
17
+
18
+ private
19
+
20
+ def schema
21
+ {
22
+ actions: []
23
+ }
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dsl
4
+ module Builders
5
+ class DomBuilder
6
+ attr_reader :dom
7
+ attr_reader :node
8
+
9
+ def initialize(dom = nil)
10
+ @dom = dom || schema
11
+ end
12
+
13
+ def current_node(node)
14
+ @node = node
15
+ end
16
+
17
+ alias last_node node
18
+
19
+ def reset
20
+ @dom = schema
21
+ @last_node = nil
22
+ end
23
+
24
+ def schema
25
+ {}
26
+ end
27
+
28
+ def logit
29
+ puts JSON.pretty_generate(dom)
30
+ # log.structure(dom)
31
+
32
+ self
33
+ end
34
+
35
+ def data
36
+ KUtil.data.to_open_struct(@dom)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,131 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dsl
4
+ module Directors
5
+ class BaseDirector
6
+ include KLog::Logging
7
+
8
+ class << self
9
+ def init(k_builder, builder = nil, **opts)
10
+ if builder.nil?
11
+ builder = Dsl::Builders::ActionsBuilder.new
12
+ else
13
+ builder.reset
14
+ end
15
+
16
+ new(k_builder, builder, **opts)
17
+ end
18
+ end
19
+
20
+ attr_reader :builder
21
+ attr_reader :k_builder
22
+ attr_reader :options
23
+ attr_accessor :dom
24
+
25
+ def initialize(k_builder, builder, **opts)
26
+ @k_builder = k_builder
27
+ @builder = builder
28
+ @options = OpenStruct.new(**opts)
29
+
30
+ @options.director_name ||= default_director_name
31
+ @options.template_base_folder ||= default_template_base_folder
32
+ @options.on_exist ||= :skip # %i[skip write compare]
33
+ @options.on_action ||= :queue # %i[queue execute]
34
+ end
35
+
36
+ def director_name
37
+ @options.director_name
38
+ end
39
+
40
+ def template_base_folder
41
+ @options.template_base_folder
42
+ end
43
+
44
+ def on_exist
45
+ @options.on_exist
46
+ end
47
+
48
+ def on_action
49
+ @options.on_action
50
+ end
51
+
52
+ def add_file(file, **opts)
53
+ opts = {
54
+ on_exist: on_exist
55
+ }.merge(opts)
56
+
57
+ opts[:dom] = dom if dom
58
+
59
+ handle_action(k_builder.add_file_action(file, **opts))
60
+
61
+ self
62
+ end
63
+
64
+ def set_current_folder_action(folder_key)
65
+ # RUN (not handle)
66
+ run_action(k_builder.set_current_folder_action(folder_key))
67
+
68
+ self
69
+ end
70
+ alias cd set_current_folder_action
71
+
72
+ def run_command(command)
73
+ handle_action(k_builder.run_command_action(command))
74
+
75
+ self
76
+ end
77
+
78
+ def run_script(script)
79
+ handle_action(k_builder.run_script_action(script))
80
+
81
+ self
82
+ end
83
+
84
+ def play_actions
85
+ k_builder.play_actions(builder.actions)
86
+ end
87
+
88
+ def debug
89
+ log.section_heading director_name
90
+
91
+ h = options.to_h.sort.to_h
92
+ h.keys.each do |key|
93
+ log.kv(titleize.parse(key.to_s), h[key])
94
+ end
95
+ nil
96
+ end
97
+
98
+ # def debug_info
99
+ # log.kv 'Template Root Folder' , k_builder.template_folders.folder_paths
100
+ # log.kv 'Template Base Folder' , template_base_folder
101
+ # log.kv 'on_exist' , on_exist
102
+ # log.kv 'on_action' , on_action
103
+ # end
104
+
105
+ private
106
+
107
+ def default_template_base_folder
108
+ ''
109
+ end
110
+
111
+ def default_director_name
112
+ titleize.parse(self.class.name.split("::").last)
113
+ end
114
+
115
+ def folder_parts(*parts)
116
+ parts.reject(&:blank?).map(&:to_s)
117
+ end
118
+
119
+ def handle_action(action)
120
+ builder.queue_action(action)
121
+ k_builder.play_action(action) if on_action == :execute
122
+ end
123
+
124
+ # run action will queue an action just like handle_action, but it will also run it immediately
125
+ def run_action(action)
126
+ builder.queue_action(action)
127
+ k_builder.run_action(action)
128
+ end
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dsl
4
+ module Directors
5
+ class ChildDirector < Dsl::Directors::BaseDirector
6
+ attr_reader :parent
7
+
8
+ def initialize(parent, **opts)
9
+ @parent = parent
10
+
11
+ opts = {
12
+ on_exist: parent.on_exist,
13
+ on_action: parent.on_action,
14
+ template_base_folder: parent.template_base_folder
15
+ }.merge(opts)
16
+
17
+ super(parent.k_builder, parent.builder, **opts)
18
+ end
19
+
20
+ def debug
21
+ parent.debug
22
+
23
+ super
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,129 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dsl
4
+ class Github < Dsl::Directors::ChildDirector
5
+ def initialize(parent, **opts)
6
+ super(parent, **opts)
7
+
8
+ @options.repo_name ||= parent.options.repo_name
9
+ @options.repo_organization ||= parent.options.repo_organization
10
+ end
11
+
12
+ def repo_name
13
+ @options.repo_name
14
+ end
15
+
16
+ def repo_organization
17
+ @options.repo_organization
18
+ end
19
+
20
+ def list_repositories
21
+ repos = api.all_repositories
22
+
23
+ KExt::Github::Printer::repositories_as_table repos
24
+
25
+ log.kv 'Repository count', repos.length
26
+ rescue StandardError => error
27
+ log.exception(error)
28
+ end
29
+
30
+ def open_repository(**opts)
31
+ info = repo_info(**opts)
32
+
33
+ system("open -a 'Google Chrome' #{info.link}")
34
+ end
35
+
36
+ def create_repository(**opts)
37
+ info = repo_info(**opts)
38
+
39
+ repo = api.all_repositories.find { |r| r.full_name == info.full_name }
40
+
41
+ if repo.nil?
42
+ log.heading 'Repository create'
43
+ log.kv 'Repository Name', info.name
44
+ log.kv 'Repository Full Name', info.full_name
45
+ log.kv 'Organization Name', info.organization if info.organization
46
+ success = api.create_repository(info.name, organization: info.organization)
47
+ log.info "Repository: #{info.full_name} created" if success
48
+ log.error "Repository: #{info.full_name} was not created" unless success
49
+
50
+ system("open -a 'Google Chrome' #{info.link}") if opts[:open]
51
+ else
52
+ log.warn 'Repository already exists, nothing to create'
53
+ end
54
+
55
+ log_repo_info(info)
56
+ rescue StandardError => error
57
+ log.exception(error)
58
+ end
59
+
60
+ def delete_repository(**opts)
61
+ info = repo_info(**opts)
62
+
63
+ repo = api.all_repositories.find { |r| r.full_name == info.full_name }
64
+
65
+ if repo.present?
66
+ log.heading 'Repository delete'
67
+ log.kv 'Repository Name', info.name
68
+ log.kv 'Repository Full Name', info.full_name
69
+ log.kv 'Organization Name', info.organization if info.organization
70
+ success = delete_api.delete_repository(info.full_name, organization: info.organization)
71
+ log.info "Repository: #{info.full_name} deleted" if success
72
+ log.error "Repository: #{info.full_name} was not deleted" unless success
73
+ # system("open -a 'Google Chrome' #{info.link}") if opts[:open]
74
+ else
75
+ log.warn 'Repository does not exist, nothing to delete'
76
+ end
77
+
78
+ log_repo_info(info)
79
+ rescue StandardError => error
80
+ log.exception(error)
81
+ end
82
+
83
+ def repo_info(**opts)
84
+ name = opts[:name] || self.repo_name
85
+ name = name.to_s
86
+ username = opts[:username] || self.username
87
+ organization = opts[:organization] || self.repo_organization
88
+ account = organization || username
89
+ full_name = [account, name].compact.join("/")
90
+ link = "https://github.com/#{full_name}"
91
+ ssh_link = "git@github.com:#{full_name}.git"
92
+
93
+ OpenStruct.new(
94
+ name: name,
95
+ full_name: full_name,
96
+ link: link,
97
+ ssh_link: ssh_link,
98
+ username: username,
99
+ organization: organization
100
+ )
101
+ end
102
+
103
+ private
104
+
105
+
106
+ def username
107
+ KExt::Github.configuration.user
108
+ end
109
+
110
+ def api
111
+ token = KExt::Github.configuration.personal_access_token
112
+ KExt::Github::Api.instance(token)
113
+ end
114
+
115
+ def delete_api
116
+ token = KExt::Github.configuration.personal_access_token_delete
117
+ KExt::Github::Api.instance(token)
118
+ end
119
+
120
+ def log_repo_info(info)
121
+ log.kv 'SSH', info.ssh_link
122
+ log.kv 'HTTPS', info.git_link
123
+ log.kv 'GITHUB', KUtil.console.hyperlink(info.link, info.link)
124
+
125
+ # log.json repo.to_h
126
+ end
127
+
128
+ end
129
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dsl
4
+ class RubyGemDsl < Dsl::Directors::BaseDirector
5
+ def default_director_name
6
+ 'Ruby Gem'
7
+ end
8
+
9
+ def repo_name
10
+ options.repo_name
11
+ end
12
+
13
+ def repo_account
14
+ options.repo_account
15
+ end
16
+
17
+ # def default_template_base_folder
18
+ # end
19
+ # def initialize(k_builder, builder, **opts)
20
+ # super(k_builder, builder, **opts)
21
+ # # @on_action = opts[:on_action] || :queue # %i[queue execute]
22
+ # end
23
+ def github(**opts, &block)
24
+ github = Dsl::Github.new(self, **opts)
25
+ github.instance_eval(&block)
26
+
27
+ self
28
+ end
29
+
30
+ def blueprint(**opts, &block)
31
+ blueprint = Dsl::RubyGemBlueprint.new(self, **opts)
32
+ blueprint.instance_eval(&block)
33
+
34
+ self
35
+ end
36
+ end
37
+
38
+ class RubyGemBlueprint < Dsl::Directors::ChildDirector
39
+ def template_content(template_filename)
40
+ template_parts = [template_base_folder, template_filename]
41
+ template_file = File.join(*template_parts)
42
+
43
+ file = k_builder.find_template_file(template_file)
44
+ File.read(file)
45
+ end
46
+
47
+ def run_template_script(template_filename, **opts)
48
+ template_parts = [template_base_folder, template_filename]
49
+ template_file = File.join(*template_parts)
50
+
51
+ script = k_builder.process_any_content(template_file: template_file, **opts)
52
+
53
+ run_script(script)
54
+ # action = k_builder.run_script_action(script)
55
+ # run_action(action)
56
+ end
57
+
58
+ # Create a single file
59
+ #
60
+ # @param [String] output_filename The output file name, this can be a relative path
61
+ # @param [Hash] **opts The options
62
+ # @option opts [String] :template_filename Template filename can be set or it will default to the same value as the output file name
63
+ # @option opts [String] :template_subfolder Template subfolder
64
+ def add(output_file, **opts)
65
+ template_file = opts[:template_file] || output_file
66
+ template_parts = [template_base_folder, opts[:template_subfolder], opts[:template_variant], template_file].reject(&:blank?)
67
+
68
+ opts[:template_file] = File.join(*template_parts)
69
+
70
+ add_file(output_file, **opts)
71
+ end
72
+
73
+ def oadd(name, **opts); add(name, **{ open: true }.merge(opts)); end
74
+ def tadd(name, **opts); add(name, **{ open_template: true }.merge(opts)); end
75
+ def fadd(name, **opts); add(name, **{ on_exist: :write }.merge(opts)); end
76
+ end
77
+ end
@@ -0,0 +1,127 @@
1
+
2
+ KManager.action :bootstrap do
3
+ def on_action
4
+ application_name = :k_director
5
+ director = Dsl::RubyGemDsl
6
+ .init(k_builder,
7
+ template_base_folder: 'ruby/gem',
8
+ on_exist: :skip, # %i[skip write compare]
9
+ on_action: :queue, # %i[queue execute]
10
+ ruby_version: '2.7',
11
+ repo_name: application_name,
12
+ application: application_name,
13
+ application_description: 'KDirector provides domain specific language implementations for code generation',
14
+ application_lib_path: application_name.to_s,
15
+ application_lib_namespace: 'KDirector',
16
+ namespaces: ['KDirector'],
17
+ author: 'David Cruwys',
18
+ author_email: 'david@ideasmen.com.au',
19
+ avatar: 'Developer',
20
+ initial_semver: '0.0.1',
21
+ main_story: 'As a Developer, I want to generate code using a DSL, so that I can speed up application development',
22
+ copyright_date: '2022',
23
+ website: 'http://appydave.com/gems/k_director'
24
+ )
25
+ .github do
26
+ parent.options.repo_info = repo_info
27
+
28
+ # create_repository # (:k_director)
29
+ # delete_repository # (:k_director)
30
+ # list_repositories
31
+ # open_repository # (:k_director)
32
+ # run_command('git init')
33
+ end
34
+ .blueprint(
35
+ name: :bin_hook,
36
+ description: 'BIN/Hook structures',
37
+ on_exist: :compare) do
38
+
39
+ cd(:app)
40
+ self.dom = OpenStruct.new(parent.options.to_h.merge(options.to_h))
41
+
42
+ # # add('bin/runonce/git-setup.sh', dom: dom)
43
+ # run_template_script('bin/runonce/git-setup.sh', dom: dom)
44
+
45
+ # add('.githooks/commit-msg') #, template_subfolder: 'ruby', template_file: 'commit-msg')
46
+ # add('.githooks/pre-commit') #, template_subfolder: 'ruby', template_file: 'pre-commit')
47
+
48
+ # run_command('chmod +x .githooks/commit-msg')
49
+ # run_command('chmod +x .githooks/pre-commit')
50
+
51
+ # add('.gitignore')
52
+
53
+ # add('bin/setup')
54
+ # add('bin/console')
55
+
56
+ # # enable sharable githooks (developer needs to turn this on before editing rep)
57
+ # run_command('git config core.hooksPath .githooks')
58
+
59
+ # run_command("git add .; git commit -m 'chore: #{self.options.description.downcase}'; git push")
60
+ end
61
+ .blueprint(
62
+ name: :opinionated,
63
+ description: 'opinionated GEM files',
64
+ on_exist: :write) do
65
+
66
+ cd(:app)
67
+ self.dom = OpenStruct.new(parent.options.to_h.merge(options.to_h))
68
+
69
+ # add("lib/#{dom.application}.rb" , template_file: 'lib/applet_name.rb' , dom: dom)
70
+ # add("lib/#{dom.application}/version.rb" , template_file: 'lib/applet_name/version.rb' , dom: dom)
71
+ # add(".ver", dom: dom)
72
+
73
+ # add('spec/spec_helper.rb')
74
+ # add("spec/#{dom.application}_spec.rb" , template_file: 'spec/applet_name_spec.rb', dom: dom)
75
+
76
+ # add("#{dom.application}.gemspec" , template_file: 'applet_name.gemspec', dom: dom)
77
+ # add('Gemfile', dom: dom)
78
+ # add('Guardfile', dom: dom)
79
+ # add('Rakefile', dom: dom)
80
+ # add('.rspec', dom: dom)
81
+ # add('.rubocop.yml', dom: dom)
82
+ # add('README.md', dom: dom)
83
+ # add('docs/CODE_OF_CONDUCT.md', dom: dom)
84
+ # add('docs/LICENSE.txt', dom: dom)
85
+
86
+ # run_command("rubocop -a")
87
+
88
+ # run_command("git add .; git commit -m 'chore: #{self.options.description.downcase}'; git push")
89
+ end
90
+ .blueprint(
91
+ name: :ci_cd,
92
+ description: 'github actions (CI/CD)',
93
+ on_exist: :write) do
94
+
95
+ cd(:app)
96
+ self.dom = OpenStruct.new(parent.options.to_h.merge(options.to_h))
97
+
98
+ # run_command("gh secret set SLACK_WEBHOOK --body \"$SLACK_REPO_WEBHOOK\"")
99
+ # add('.github/workflows/main.yml')
100
+ # add('.github/workflows/semver.yml')
101
+ # add('.releaserc')
102
+
103
+ # run_command("git add .; git commit -m 'chore: #{self.options.description.downcase}'; git push")
104
+ end
105
+ .blueprint(
106
+ name: :intitial_gem_release,
107
+ description: 'initial GEM release',
108
+ on_exist: :write) do
109
+
110
+ cd(:app)
111
+ self.dom = OpenStruct.new(parent.options.to_h.merge(options.to_h))
112
+
113
+ # run_command("rake publish && rake clean")
114
+ # run_command("gh secret set GEM_HOST_API_KEY --body \"$GEM_HOST_API_KEY\"")
115
+ # add('.github/workflows/main.yml')
116
+ # add('.github/workflows/semver.yml')
117
+ # add('.releaserc')
118
+
119
+ # run_command("git add .; git commit -m 'chore: #{self.options.description.downcase}'; git push")
120
+ end
121
+
122
+
123
+ # director.k_builder.debug
124
+ director.play_actions
125
+ # director.builder.logit
126
+ end
127
+ end
data/.builders/run.rb ADDED
@@ -0,0 +1,15 @@
1
+ KManager.action :run do
2
+ def on_action
3
+ puts 'run away, run away'
4
+ end
5
+ end
6
+
7
+ KManager.opts.app_name = 'RubyGem Generator'
8
+ KManager.opts.sleep = 2
9
+ KManager.opts.reboot_on_kill = 0
10
+ KManager.opts.reboot_sleep = 4
11
+ KManager.opts.exception_style = :short
12
+ KManager.opts.show.time_taken = true
13
+ KManager.opts.show.finished = true
14
+ KManager.opts.show.finished_message = 'FINISHED :)'
15
+
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # template_variant: :ruby
4
+
5
+ if ! head -1 "$1" | grep -qE "^.{1,200}$"; then
6
+ echo -e "\033[41mAborting commit. Your commit message is too long.\033[0m" >&2
7
+ exit 1
8
+ fi
9
+ if ! head -1 "$1" | grep -qE "^(merge master)"; then
10
+ exit 0
11
+ fi
12
+ if ! head -1 "$1" | grep -qE "^(feat|fix|ci|chore|docs|test|style|refactor|perf|build|revert)(\(.+?\))?!?: .{1,}$"; then
13
+ echo -e "\033[41mWARNING: this commit does not follow conventional commit message guidelines\033[0m" >&2
14
+ fi