k_starter 0.1.0 → 0.1.1

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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/.builders/generators/01-bootstrap.rb +16 -16
  3. data/.rubocop.yml +14 -0
  4. data/CHANGELOG.md +7 -0
  5. data/Gemfile +22 -0
  6. data/README.md +1 -1
  7. data/exe/k_starter +15 -0
  8. data/ext/k_starter/extconf.rb +5 -0
  9. data/ext/k_starter/k_starter.c +9 -0
  10. data/ext/k_starter/k_starter.h +6 -0
  11. data/lib/k_starter/app.rb +16 -0
  12. data/lib/k_starter/app_generator.rb +198 -0
  13. data/lib/k_starter/cli.rb +63 -0
  14. data/lib/k_starter/commands/.keep +1 -0
  15. data/lib/k_starter/commands/command.rb +54 -0
  16. data/lib/k_starter/commands/configuration/configuration_menu.rb +46 -0
  17. data/lib/k_starter/commands/project/bootstrap_project.rb +28 -0
  18. data/lib/k_starter/commands/project/edit_project.rb +34 -0
  19. data/lib/k_starter/commands/project/new_project.rb +28 -0
  20. data/lib/k_starter/commands/project/project_menu.rb +51 -0
  21. data/lib/k_starter/commands/project/select_new_project_type.rb +44 -0
  22. data/lib/k_starter/database/base_model.rb +21 -0
  23. data/lib/k_starter/database/config_model.rb +99 -0
  24. data/lib/k_starter/database/project_model.rb +94 -0
  25. data/lib/k_starter/map.rb +46 -0
  26. data/lib/k_starter/questions/ask_questions.rb +20 -0
  27. data/lib/k_starter/questions/base_question.rb +208 -0
  28. data/lib/k_starter/questions/gem.rb +132 -0
  29. data/lib/k_starter/questions/rails.rb +162 -0
  30. data/lib/k_starter/questions/svelte.rb +52 -0
  31. data/lib/k_starter/r7_hotwire.rb +98 -0
  32. data/lib/k_starter/schema.rb +89 -0
  33. data/lib/k_starter/starters/base.rb +80 -0
  34. data/lib/k_starter/starters/gem.rb +71 -0
  35. data/lib/k_starter/starters/nuxt.rb +29 -0
  36. data/lib/k_starter/starters/rails.rb +29 -0
  37. data/lib/k_starter/starters/svelte.rb +45 -0
  38. data/lib/k_starter/tty_helpers.rb +118 -0
  39. data/lib/k_starter/version.rb +1 -1
  40. data/lib/k_starter.rb +44 -1
  41. data/package-lock.json +2 -2
  42. data/package.json +1 -1
  43. metadata +172 -1
@@ -0,0 +1,132 @@
1
+ # frozen_string_literal: true
2
+
3
+ module KStarter
4
+ module Questions
5
+ # Ask code generations for a new GEM.
6
+ class BaseGem < BaseQuestion
7
+ attr_reader :exe # has executable folder
8
+ attr_reader :coc # has code of conduct
9
+ attr_reader :mit # has MIT license
10
+ attr_reader :rspec # has rspec tests
11
+
12
+ def initialize(**args)
13
+ args = { type: :gem }.merge(args)
14
+ super(**args)
15
+ end
16
+
17
+ def ask_questions
18
+ ask_name
19
+ ask_root_path
20
+ ask_github_key
21
+ ask_description
22
+ story_questions
23
+ klue_template_questions
24
+
25
+ ask_exe
26
+ ask_coc
27
+ ask_mit
28
+ ask_rspec
29
+ end
30
+
31
+ def to_h
32
+ super.merge(
33
+ {
34
+ exe: exe,
35
+ coc: coc,
36
+ mit: mit,
37
+ rspec: rspec
38
+ }
39
+ )
40
+ end
41
+
42
+ def to_dom
43
+ KStarter::Schema::GemProject.new(to_h)
44
+ end
45
+
46
+ private
47
+
48
+ def initialize_attributes(**args)
49
+ super(**args)
50
+
51
+ @exe = args[:exe]
52
+ @coc = args[:coc]
53
+ @mit = args[:mit]
54
+ @rspec = args[:rspec]
55
+ end
56
+
57
+ def apply_attribute_defaults
58
+ default_story_active
59
+ default_klue_template_active
60
+
61
+ default_exe
62
+ default_coc
63
+ default_mit
64
+ default_rspec
65
+ end
66
+
67
+ def question
68
+ @question ||= prompt
69
+ end
70
+
71
+ def ask_name
72
+ @name = question.ask('Name (ruby GEM)') do |q|
73
+ q.default(name) unless name.nil?
74
+ q.required(true, 'GEM name is required, and can only contain letters, numbers, and underscores.')
75
+ q.validate(/\A\w+\Z/)
76
+ end
77
+ end
78
+
79
+ def ask_exe
80
+ @exe = question.yes?('Has executable folder?', default: exe)
81
+ end
82
+
83
+ def default_exe
84
+ @exe = false if @exe.nil?
85
+ end
86
+
87
+ def ask_coc
88
+ @coc = question.yes?('Has code of conduct?', default: coc)
89
+ end
90
+
91
+ def default_coc
92
+ @coc = true if @coc.nil?
93
+ end
94
+
95
+ def ask_mit
96
+ @mit = question.yes?('Has MIT license?', default: mit)
97
+ end
98
+
99
+ def default_mit
100
+ @mit = true if @mit.nil?
101
+ end
102
+
103
+ def ask_rspec
104
+ @rspec = question.yes?('Has rspec tests?', default: rspec)
105
+ end
106
+
107
+ def default_rspec
108
+ @rspec = true if @rspec.nil?
109
+ end
110
+ end
111
+
112
+ # Ask code generations for a new Ruby GEM project.
113
+ class LibraryGem < KStarter::Questions::BaseGem
114
+ def initialize(**args)
115
+ args = { variant: :library }.merge(args)
116
+ super(**args)
117
+ end
118
+ end
119
+
120
+ # Ask code generations for a new Ruby command line GEM project.
121
+ class CliGem < KStarter::Questions::BaseGem
122
+ def initialize(**args)
123
+ args = { variant: :cli }.merge(args)
124
+ super(**args)
125
+ end
126
+
127
+ def default_exe
128
+ @exe = true if @exe.nil?
129
+ end
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,162 @@
1
+ # frozen_string_literal: true
2
+
3
+ module KStarter
4
+ module Questions
5
+ # Ask code generations for a new GEM.
6
+ class Rails < BaseQuestion
7
+ attr_reader :include_action_text
8
+ attr_reader :include_active_storage
9
+ attr_reader :include_sample_models
10
+ attr_reader :include_javascript_libraries
11
+ attr_reader :include_devise
12
+ attr_reader :include_rspec
13
+ attr_reader :include_common_pages
14
+ attr_reader :run_db_migrate
15
+
16
+ def initialize(**args)
17
+ args = { type: 'rails' }.merge(args)
18
+ super(**args)
19
+ end
20
+
21
+ def ask_questions
22
+ ask_name
23
+ ask_root_path
24
+ ask_github_key
25
+ ask_description
26
+ story_questions
27
+ klue_template_questions
28
+
29
+ ask_include_action_text
30
+ ask_include_active_storage
31
+ ask_include_sample_models
32
+ ask_include_javascript_libraries
33
+ ask_include_devise
34
+ ask_include_rspec
35
+ ask_include_common_pages
36
+ ask_run_db_migrate
37
+ end
38
+
39
+ def to_h
40
+ super.merge(
41
+ {
42
+ include_action_text: include_action_text,
43
+ include_active_storage: include_active_storage,
44
+ include_sample_models: include_sample_models,
45
+ include_javascript_libraries: include_javascript_libraries,
46
+ include_devise: include_devise,
47
+ include_rspec: include_rspec,
48
+ include_common_pages: include_common_pages,
49
+ run_db_migrate: run_db_migrate
50
+ }
51
+ )
52
+ end
53
+
54
+ def to_dom
55
+ KStarter::Schema::RailsProject.new(to_h)
56
+ end
57
+
58
+ private
59
+
60
+ def initialize_attributes(**args)
61
+ super(**args)
62
+
63
+ @include_action_text = args[:include_action_text]
64
+ @include_active_storage = args[:include_active_storage]
65
+ @include_sample_models = args[:include_sample_models]
66
+ @include_javascript_libraries = args[:include_javascript_libraries]
67
+ @include_devise = args[:include_devise]
68
+ @include_rspec = args[:include_rspec]
69
+ @include_common_pages = args[:include_common_pages]
70
+ @run_db_migrate = args[:run_db_migrate]
71
+ end
72
+
73
+ def apply_attribute_defaults
74
+ default_story_active
75
+ default_klue_template_active
76
+
77
+ default_include_action_text
78
+ default_include_active_storage
79
+ default_include_sample_models
80
+ default_include_javascript_libraries
81
+ default_include_devise
82
+ default_include_rspec
83
+ default_include_common_pages
84
+ default_run_db_migrate
85
+ end
86
+
87
+ def ask_name
88
+ @name = question.ask('Name (rails application)') do |q|
89
+ q.default(name) unless name.nil?
90
+ q.required(true, 'Rails application name is required, and can only contain letters, numbers, and underscores.')
91
+ q.validate(/\A\w+\Z/)
92
+ end
93
+ end
94
+
95
+ def ask_include_action_text
96
+ @include_action_text = question.yes?('Include Action Text', default: include_action_text)
97
+ end
98
+
99
+ def ask_include_active_storage
100
+ @include_active_storage = question.yes?('Include Active Storage', default: include_active_storage)
101
+ end
102
+
103
+ def ask_include_sample_models
104
+ @include_sample_models = question.yes?('Include Sample Models', default: include_sample_models)
105
+ end
106
+
107
+ def ask_include_javascript_libraries
108
+ @include_javascript_libraries = question.yes?('Include Javascript Libraries', default: include_javascript_libraries)
109
+ end
110
+
111
+ def ask_include_devise
112
+ @include_devise = question.yes?('Include Devise', default: include_devise)
113
+ end
114
+
115
+ def ask_include_rspec
116
+ @include_rspec = question.yes?('Include Rspec', default: include_rspec)
117
+ end
118
+
119
+ def ask_include_common_pages
120
+ @include_common_pages = question.yes?('Include Common Pages', default: include_common_pages)
121
+ end
122
+
123
+ def ask_run_db_migrate
124
+ @run_db_migrate = question.yes?('DB Migrate', default: run_db_migrate)
125
+ end
126
+
127
+ # defaults
128
+
129
+ def default_include_action_text
130
+ @include_action_text = true if @include_action_text.nil?
131
+ end
132
+
133
+ def default_include_active_storage
134
+ @include_active_storage = true if @include_active_storage.nil?
135
+ end
136
+
137
+ def default_include_sample_models
138
+ @include_sample_models = true if @include_sample_models.nil?
139
+ end
140
+
141
+ def default_include_javascript_libraries
142
+ @include_javascript_libraries = true if @include_javascript_libraries.nil?
143
+ end
144
+
145
+ def default_include_devise
146
+ @include_devise = true if @include_devise.nil?
147
+ end
148
+
149
+ def default_include_rspec
150
+ @include_rspec = true if @include_rspec.nil?
151
+ end
152
+
153
+ def default_include_common_pages
154
+ @include_common_pages = true if @include_common_pages.nil?
155
+ end
156
+
157
+ def default_run_db_migrate
158
+ @run_db_migrate = true if @run_db_migrate.nil?
159
+ end
160
+ end
161
+ end
162
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module KStarter
4
+ module Questions
5
+ # Ask code generations for a new GEM.
6
+ class Svelte < BaseQuestion
7
+ def initialize(**args)
8
+ args = { type: :svelte }.merge(args)
9
+ super(**args)
10
+ end
11
+
12
+ def ask_questions
13
+ ask_name
14
+ ask_root_path
15
+ ask_github_key
16
+ ask_description
17
+ story_questions
18
+ klue_template_questions
19
+ end
20
+
21
+ def to_h
22
+ super.merge(
23
+ {
24
+ }
25
+ )
26
+ end
27
+
28
+ def to_dom
29
+ KStarter::Schema::SvelteProject.new(to_h)
30
+ end
31
+
32
+ private
33
+
34
+ def apply_attribute_defaults
35
+ default_story_active
36
+ default_klue_template_active
37
+ end
38
+
39
+ def question
40
+ @question ||= prompt
41
+ end
42
+
43
+ def ask_name
44
+ @name = question.ask('Name (Svelte Application)') do |q|
45
+ q.default(name) unless name.nil?
46
+ q.required(true, 'Svelte application name is required, and can only contain letters, numbers, and underscores.')
47
+ q.validate(/\A\w+\Z/)
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+
3
+ # require 'uri'
4
+ # require 'net/http'
5
+ require 'active_model'
6
+ require 'pry'
7
+ require_relative 'base_template'
8
+
9
+ # R7HotwireTemplate
10
+ class R7HotwireTemplate < BaseTemplate
11
+ attr_reader :host
12
+
13
+ def customize_template
14
+ gac('Base Rails 7 image created')
15
+
16
+ settings_for_asset_management
17
+
18
+ ask_questions
19
+ add_gems
20
+ add_gem_groups
21
+ end
22
+
23
+ # ./bin/rails javascript:install:esbuild
24
+ def after_bundle
25
+ add_action_text if action_text?
26
+ add_active_storage if active_storage?
27
+ add_devise if devise?
28
+ add_rspec if rspec?
29
+ add_javascript_libraries if javascript_libraries?
30
+
31
+ gac('Base Rails 7 default structure created')
32
+
33
+ setup_models if sample_models?
34
+ setup_common_pages if common_pages?
35
+
36
+ rails_command('db:migrate') if db_migrate?
37
+ end
38
+
39
+ private
40
+
41
+ def add_devise
42
+ run 'bundle add devise'
43
+
44
+ Bundler.with_unbundled_env { run 'bundle install' }
45
+
46
+ rails_command 'generate devise:install'
47
+
48
+ run 'rails generate devise User role:integer'
49
+
50
+ alter_first_file('db/migrate/*_create_users.rb') do |file|
51
+ host.in_root do
52
+ host.gsub_file(file,
53
+ 't.integer :role',
54
+ 't.integer :role, default: 0')
55
+ end
56
+ end
57
+
58
+ rails_command 'generate devise:views'
59
+ end
60
+
61
+ def ask_questions
62
+ self.include_action_text = no?("Add action text 'Rails'?")
63
+ self.include_active_storage = no?("Add active storage 'Rails'?")
64
+ self.include_javascript_libraries = no?("Add javascript libraries 'Pinned'?") # this is if using importmap
65
+ self.include_sample_models = no?('Add sample models?')
66
+ self.include_common_pages = yes?('Add common pages?')
67
+ self.include_devise = no?('Add devise?') # Alter t.integer :role, default: 0
68
+ self.include_rspec = no?('Add rspec?')
69
+ self.run_db_migrate = yes?('Run db:migrate?')
70
+ end
71
+
72
+ def setup_models
73
+ g_scaffold('post', 'title', 'content:text')
74
+ g_scaffold('book', 'title', 'content:text')
75
+ g_resource('comment', 'post:references', 'content:text')
76
+ g_mailer('posts', 'submitted', 'broken')
77
+ end
78
+
79
+ def setup_common_pages
80
+ g_controller('home', 'index')
81
+ host.route("root to: 'home#index'")
82
+ # g_controller("pages", "home", "about")
83
+ # host.route("root to: 'pages#home'")
84
+ end
85
+
86
+ def add_javascript_libraries
87
+ # see: https://youtube.com/clip/Ugkx_tDcsUclZ-GR1Ck6liDKrlvmf38r92mw
88
+ # host.run("bin/importmap pin local-time")
89
+ host.run('bin/importmap pin local-time --download')
90
+ end
91
+ end
92
+
93
+ setup_rails = R7HotwireTemplate.new(self)
94
+ setup_rails.customize_template
95
+
96
+ after_bundle do
97
+ setup_rails.after_bundle
98
+ end
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Types
4
+ include Dry.Types()
5
+ end
6
+
7
+ module KStarter
8
+ # Schema for storing model data for projects and other configuration data
9
+ module Schema
10
+ # Configuration class for the project types
11
+ class ProjectType < Dry::Struct
12
+ attribute :type , Types::Coercible::Symbol
13
+ attribute :variant , Types::Coercible::Symbol.optional.default(nil)
14
+ attribute :path , Types::Strict::String
15
+ end
16
+
17
+ class Github < Dry::Struct
18
+ attribute :user , Types::Strict::String
19
+ attribute :organizations , Types::Array.of(Types::Coercible::String)
20
+ end
21
+
22
+ # User story node
23
+ class Story < Dry::Struct
24
+ attribute :active , Types::Strict::Bool
25
+ attribute :actor , Types::Strict::String.optional.default(nil)
26
+ attribute :problem , Types::Strict::String.optional.default(nil)
27
+ attribute :solution , Types::Strict::String.optional.default(nil)
28
+ attribute :user_story , Types::Strict::String.optional.default(nil)
29
+ end
30
+
31
+ # Klue template node
32
+ class KlueTemplate < Dry::Struct
33
+ attribute :active , Types::Strict::Bool
34
+ attribute :name , Types::Strict::String.optional.default(nil)
35
+ end
36
+
37
+ # Base class for project data
38
+ class BaseProject < Dry::Struct
39
+ attribute :name , Types::Strict::String
40
+ attribute :type , Types::Coercible::Symbol
41
+ attribute :variant , Types::Coercible::Symbol.optional.default(nil)
42
+ attribute :root_path , Types::Strict::String # .constructor { |path| File.expand_path(path) }
43
+ attribute :description , Types::Strict::String.optional.default(nil)
44
+ attribute :story , KStarter::Schema::Story
45
+ attribute :klue_template , KStarter::Schema::KlueTemplate
46
+ attribute :github_key , Types::Strict::String
47
+
48
+ def expanded_project_path
49
+ File.join(expanded_root_path, name)
50
+ end
51
+
52
+ def expanded_root_path
53
+ File.expand_path(root_path)
54
+ end
55
+
56
+ def github_account_type
57
+ github_key == App.config.github_user ? :user : :organization
58
+ end
59
+
60
+ def github_organization
61
+ github_account_type == :organization ? github_key : nil
62
+ end
63
+ end
64
+
65
+ class RailsProject < BaseProject
66
+ attribute :include_action_text , Types::Strict::Bool
67
+ attribute :include_active_storage , Types::Strict::Bool
68
+ attribute :include_sample_models , Types::Strict::Bool
69
+ attribute :include_javascript_libraries , Types::Strict::Bool
70
+ attribute :include_devise , Types::Strict::Bool
71
+ attribute :include_rspec , Types::Strict::Bool
72
+ attribute :include_common_pages , Types::Strict::Bool
73
+ attribute :run_db_migrate , Types::Strict::Bool
74
+ end
75
+
76
+ class GemProject < BaseProject
77
+ attribute :exe , Types::Strict::Bool
78
+ attribute :coc , Types::Strict::Bool
79
+ attribute :mit , Types::Strict::Bool
80
+ attribute :rspec , Types::Strict::Bool
81
+ end
82
+
83
+ class SvelteProject < BaseProject
84
+ end
85
+
86
+ class NuxtProject < BaseProject
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ module KStarter
4
+ module Starters
5
+ # Generate command line for a new ruby gem project.
6
+ class Base
7
+ include TtyHelpers
8
+
9
+ attr_reader :project
10
+ attr_reader :code_open_delay
11
+
12
+ def initialize(project, **args)
13
+ @project = project
14
+ @code_open_delay = args[:code_open_delay] || 0
15
+ end
16
+
17
+ def system_in_root(script)
18
+ Dir.chdir(project.expanded_root_path) do
19
+ system script
20
+ end
21
+ end
22
+
23
+ def system_in_project(script)
24
+ Dir.chdir(project.expanded_project_path) do
25
+ system script
26
+ end
27
+ end
28
+
29
+ def project_path_exist?
30
+ File.exist?(project.expanded_project_path)
31
+ end
32
+
33
+ def project_path_delete
34
+ return unless project_path_exist?
35
+
36
+ FileUtils.rm_rf(project.expanded_project_path)
37
+ end
38
+
39
+ def project_open_in_vscode
40
+ sleep code_open_delay if code_open_delay.positive?
41
+
42
+ Dir.chdir(project.expanded_project_path) do
43
+ system('code .')
44
+ end
45
+ end
46
+
47
+ def ask_destroy_existing_project
48
+ question.yes?('Do you want to destroy the existing project folder')
49
+ end
50
+
51
+ def ask_exit_if_project_exists
52
+ question.yes?('This project exists. Do you want to cancel new project creation?')
53
+ end
54
+
55
+ def exiting(message = 'Exiting')
56
+ question.warn(message)
57
+ nil
58
+ end
59
+
60
+ def create_kbuilder
61
+ KManager::Cli::Commands::New.new.call(
62
+ project_folder: project.expanded_project_path,
63
+ builder_folder: File.join(project.expanded_project_path, '.builders'),
64
+ description: project.description,
65
+ user_story: project.story.user_story,
66
+ repo_organization: project.github_organization,
67
+ template: project.klue_template.name,
68
+ log_level: nil,
69
+ force: true
70
+ )
71
+ end
72
+
73
+ private
74
+
75
+ def question
76
+ @question ||= prompt
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Examples
4
+ # bundle gem --coc --ci=github --exe --linter=rubocop --test=rspec --mit k_genesis
5
+ # bundle gem --coc --test=rspec --mit k_genesis
6
+ # bundle gem --coc --test=rspec --mit conventional_gitflow
7
+ # bundle gem --coc --test=rspec --mit k_director
8
+ # bundle gem --coc --test=rspec --mit k_config
9
+ # bundle gem --coc --test=rspec --mit funky
10
+ # bundle gem --coc --test=rspec --mit --linter=rubocop --ci-github cmdlet
11
+ # bundle gem --coc --test=rspec --mit cmdlet
12
+ # bundle gem --coc --test=rspec --mit drawio_dsl
13
+ # bundle gem --coc --test=rspec --mit tailwind_dsl
14
+ # bundle gem --coc --test=rspec --mit test-google-cloud-functions
15
+ # bundle gem --coc --test=rspec --mit handlebarsjs
16
+ # bundle gem --coc --test=rspec --mit k_starter
17
+
18
+ module KStarter
19
+ module Starters
20
+ # Generate command line for a new ruby gem project.
21
+ class Gem < KStarter::Starters::Base
22
+ def execute
23
+ create_gem
24
+ create_kbuilder
25
+
26
+ project_open_in_vscode
27
+ end
28
+
29
+ private
30
+
31
+ def create_gem
32
+ if project_path_exist?
33
+ return exiting if ask_exit_if_project_exists
34
+
35
+ project_path_delete if ask_destroy_existing_project
36
+ end
37
+
38
+ system_in_root(build_create_gem_bash)
39
+ end
40
+
41
+ def build_create_gem_bash
42
+ <<-BASH
43
+
44
+ echo "Generating gem project #{project.name}..."
45
+ echo "Ruby version:"
46
+ ruby -v
47
+ echo "Current folder: "
48
+ pwd
49
+ # create the gem
50
+ #{build_bundle_gem}
51
+
52
+ BASH
53
+ end
54
+
55
+ # rubocop:disable Metrics/AbcSize
56
+ def build_bundle_gem
57
+ # bundle gem --coc --exe --test=rspec --mit k_genesis
58
+
59
+ bundle_gem = []
60
+ bundle_gem << 'bundle gem'
61
+ bundle_gem << '--coc' if project.coc
62
+ bundle_gem << '--exe' if project.exe
63
+ bundle_gem << '--mit' if project.mit
64
+ bundle_gem << '--test=rspec' if project.rspec
65
+ bundle_gem << project.name.to_s
66
+ bundle_gem.join(' ')
67
+ end
68
+ # rubocop:enable Metrics/AbcSize
69
+ end
70
+ end
71
+ end