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.
- checksums.yaml +4 -4
- data/.builders/generators/01-bootstrap.rb +16 -16
- data/.rubocop.yml +14 -0
- data/CHANGELOG.md +7 -0
- data/Gemfile +22 -0
- data/README.md +1 -1
- data/exe/k_starter +15 -0
- data/ext/k_starter/extconf.rb +5 -0
- data/ext/k_starter/k_starter.c +9 -0
- data/ext/k_starter/k_starter.h +6 -0
- data/lib/k_starter/app.rb +16 -0
- data/lib/k_starter/app_generator.rb +198 -0
- data/lib/k_starter/cli.rb +63 -0
- data/lib/k_starter/commands/.keep +1 -0
- data/lib/k_starter/commands/command.rb +54 -0
- data/lib/k_starter/commands/configuration/configuration_menu.rb +46 -0
- data/lib/k_starter/commands/project/bootstrap_project.rb +28 -0
- data/lib/k_starter/commands/project/edit_project.rb +34 -0
- data/lib/k_starter/commands/project/new_project.rb +28 -0
- data/lib/k_starter/commands/project/project_menu.rb +51 -0
- data/lib/k_starter/commands/project/select_new_project_type.rb +44 -0
- data/lib/k_starter/database/base_model.rb +21 -0
- data/lib/k_starter/database/config_model.rb +99 -0
- data/lib/k_starter/database/project_model.rb +94 -0
- data/lib/k_starter/map.rb +46 -0
- data/lib/k_starter/questions/ask_questions.rb +20 -0
- data/lib/k_starter/questions/base_question.rb +208 -0
- data/lib/k_starter/questions/gem.rb +132 -0
- data/lib/k_starter/questions/rails.rb +162 -0
- data/lib/k_starter/questions/svelte.rb +52 -0
- data/lib/k_starter/r7_hotwire.rb +98 -0
- data/lib/k_starter/schema.rb +89 -0
- data/lib/k_starter/starters/base.rb +80 -0
- data/lib/k_starter/starters/gem.rb +71 -0
- data/lib/k_starter/starters/nuxt.rb +29 -0
- data/lib/k_starter/starters/rails.rb +29 -0
- data/lib/k_starter/starters/svelte.rb +45 -0
- data/lib/k_starter/tty_helpers.rb +118 -0
- data/lib/k_starter/version.rb +1 -1
- data/lib/k_starter.rb +44 -1
- data/package-lock.json +2 -2
- data/package.json +1 -1
- metadata +172 -1
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module KStarter
|
4
|
+
module Commands
|
5
|
+
# Submenu for project
|
6
|
+
class ProjectMenu < KStarter::Commands::Command
|
7
|
+
def initialize(subcommand, options)
|
8
|
+
@subcommand = (subcommand || '').to_sym
|
9
|
+
|
10
|
+
@options = options
|
11
|
+
super()
|
12
|
+
end
|
13
|
+
|
14
|
+
def execute(input: $stdin, output: $stdout)
|
15
|
+
command = nil
|
16
|
+
|
17
|
+
loop do
|
18
|
+
case @subcommand
|
19
|
+
when :new
|
20
|
+
command = KStarter::Commands::SelectNewProjectType.new(:menu)
|
21
|
+
when :edit
|
22
|
+
command = KStarter::Commands::EditProject.new
|
23
|
+
when :bootstrap
|
24
|
+
command = KStarter::Commands::BootstrapProject.new
|
25
|
+
end
|
26
|
+
command&.execute(input: input, output: output) if command
|
27
|
+
break if menu.nil?
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def menu
|
34
|
+
display_exiting_projects
|
35
|
+
|
36
|
+
choices = [
|
37
|
+
{ name: 'New project settings', value: :new },
|
38
|
+
{ name: 'Edit project settings', value: :edit },
|
39
|
+
{ name: 'Bootstrap a project', value: :bootstrap }
|
40
|
+
]
|
41
|
+
|
42
|
+
subcommand = prompt.select('Select your subcommand?', choices, per_page: 15, cycle: true)
|
43
|
+
|
44
|
+
command = KStarter::Commands::ProjectMenu.new(subcommand, {})
|
45
|
+
command.execute(input: @input, output: @output)
|
46
|
+
rescue KStarter::EscapePressed
|
47
|
+
nil
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module KStarter
|
4
|
+
module Commands
|
5
|
+
# Submenu for forms
|
6
|
+
class SelectNewProjectType < KStarter::Commands::Command
|
7
|
+
def initialize(subcommand, **options)
|
8
|
+
@subcommand = (subcommand || '').to_sym
|
9
|
+
|
10
|
+
@options = options
|
11
|
+
super()
|
12
|
+
end
|
13
|
+
|
14
|
+
def execute(input: $stdin, output: $stdout)
|
15
|
+
command = nil
|
16
|
+
case @subcommand
|
17
|
+
when :menu
|
18
|
+
command = select_new_project_type
|
19
|
+
end
|
20
|
+
command&.execute(input: input, output: output)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def select_new_project_type
|
26
|
+
prompt.warn('Forms for project settings')
|
27
|
+
|
28
|
+
choices = [
|
29
|
+
{ name: 'Rails' , value: { type: :rails, variant: nil } },
|
30
|
+
{ name: 'Ruby library (GEM)' , value: { type: :gem, variant: :library } },
|
31
|
+
{ name: 'Ruby Command line Ruby (GEM)', value: { type: :gem, variant: :cli } },
|
32
|
+
{ name: 'Svelte' , value: { type: :svelte, variant: nil } }
|
33
|
+
]
|
34
|
+
|
35
|
+
prompt.warn('What type of project are you creating?')
|
36
|
+
form = prompt.select('Select project type?', choices, per_page: 15, cycle: true)
|
37
|
+
|
38
|
+
KStarter::Commands::NewProject.new(form_type: form[:type], form_variant: form[:variant])
|
39
|
+
rescue KStarter::EscapePressed
|
40
|
+
nil
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module KStarter
|
4
|
+
module Database
|
5
|
+
# Handle access to project data and configuration JSON files
|
6
|
+
class BaseModel
|
7
|
+
attr_reader :folder
|
8
|
+
attr_reader :backup_folder
|
9
|
+
attr_reader :filename
|
10
|
+
attr_reader :data
|
11
|
+
|
12
|
+
# Split Config and Data into two classes
|
13
|
+
def initialize(**args)
|
14
|
+
@folder = args[:folder] || '~/.config'
|
15
|
+
@folder = File.expand_path(folder)
|
16
|
+
@backup_folder = File.join(folder, 'klue_backup')
|
17
|
+
@filename = File.join(@folder, args[:file])
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module KStarter
|
4
|
+
module Database
|
5
|
+
# Handle access to configuration data files
|
6
|
+
class ConfigModel < KStarter::Database::BaseModel
|
7
|
+
DEFAULT_FILE_NAME = 'k_starter.config.json'
|
8
|
+
|
9
|
+
def initialize(**args)
|
10
|
+
args = { file: DEFAULT_FILE_NAME }.merge(args)
|
11
|
+
super(**args)
|
12
|
+
|
13
|
+
initialize_model
|
14
|
+
end
|
15
|
+
|
16
|
+
# rubocop:disable Naming/AccessorMethodName
|
17
|
+
def set_project_type(project_type)
|
18
|
+
project_type = project_type.to_h unless project_type.is_a?(Hash)
|
19
|
+
|
20
|
+
index = project_type_index(project_type[:type], project_type[:variant])
|
21
|
+
|
22
|
+
if index.nil?
|
23
|
+
data[:project_types] << project_type
|
24
|
+
else
|
25
|
+
data[:project_types][index] = project_type
|
26
|
+
end
|
27
|
+
|
28
|
+
write
|
29
|
+
end
|
30
|
+
# rubocop:enable Naming/AccessorMethodName
|
31
|
+
|
32
|
+
def get_project_type(type, variant = nil)
|
33
|
+
index = project_type_index(type, variant)
|
34
|
+
|
35
|
+
return nil if index.nil?
|
36
|
+
|
37
|
+
@data[:project_types][index]
|
38
|
+
end
|
39
|
+
|
40
|
+
def project_variants(type)
|
41
|
+
type = as_sym(type)
|
42
|
+
|
43
|
+
# project variants without nil or empty
|
44
|
+
data[:project_types]
|
45
|
+
.select { |t| t[:type]&.to_sym == type }
|
46
|
+
.map { |t| t[:variant]&.to_sym }
|
47
|
+
.compact
|
48
|
+
end
|
49
|
+
|
50
|
+
def github_user
|
51
|
+
data[:github][:user]
|
52
|
+
end
|
53
|
+
|
54
|
+
def github_organizations
|
55
|
+
data[:github][:organizations]
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def initialize_model
|
61
|
+
if File.exist?(filename)
|
62
|
+
read
|
63
|
+
return
|
64
|
+
end
|
65
|
+
|
66
|
+
@data = {
|
67
|
+
github: {
|
68
|
+
user: 'not_set',
|
69
|
+
organizations: []
|
70
|
+
},
|
71
|
+
project_types: []
|
72
|
+
}
|
73
|
+
|
74
|
+
write
|
75
|
+
end
|
76
|
+
|
77
|
+
def read
|
78
|
+
@data = JSON.parse(File.read(filename), symbolize_names: true)
|
79
|
+
end
|
80
|
+
|
81
|
+
def write
|
82
|
+
FileUtils.mkdir_p(File.dirname(filename))
|
83
|
+
File.write(filename, JSON.pretty_generate(data))
|
84
|
+
end
|
85
|
+
|
86
|
+
def project_type_index(type, variant = nil)
|
87
|
+
type = as_sym(type)
|
88
|
+
variant = as_sym(variant)
|
89
|
+
|
90
|
+
@data[:project_types].find_index { |t| t[:type]&.to_sym == type && (variant.nil? || t[:variant]&.to_sym == variant) }
|
91
|
+
end
|
92
|
+
|
93
|
+
def as_sym(value)
|
94
|
+
value.to_sym if value.is_a?(String)
|
95
|
+
value
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module KStarter
|
4
|
+
module Database
|
5
|
+
# Handle access to project data files
|
6
|
+
class ProjectModel < KStarter::Database::BaseModel
|
7
|
+
DEFAULT_FILE_NAME = 'k_starter.projects.json'
|
8
|
+
|
9
|
+
# def reset_data
|
10
|
+
# require 'fileutils'
|
11
|
+
|
12
|
+
# source_file = App.data.find_file
|
13
|
+
|
14
|
+
# return unless File.exist?(source_file)
|
15
|
+
|
16
|
+
# backup_folder = App.backup_folder
|
17
|
+
# time = Time.now.strftime('%Y%m%d%H%M%S')
|
18
|
+
|
19
|
+
# target_file = File.join(backup_folder, "#{time}_#{App::DATA_FILE}")
|
20
|
+
|
21
|
+
# FileUtils.mkdir_p backup_folder
|
22
|
+
# FileUtils.cp(source_file, target_file)
|
23
|
+
# File.delete(source_file)
|
24
|
+
|
25
|
+
# @data = nil
|
26
|
+
# end
|
27
|
+
|
28
|
+
def initialize(**args)
|
29
|
+
args = { file: DEFAULT_FILE_NAME }.merge(args)
|
30
|
+
super(**args)
|
31
|
+
|
32
|
+
initialize_model
|
33
|
+
end
|
34
|
+
|
35
|
+
def project_list
|
36
|
+
@project_list ||= begin
|
37
|
+
projects = data[:projects]
|
38
|
+
projects.map { |project| KStarter::Map.project(project) }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def find_project(name, variant = nil)
|
43
|
+
index = find_project_index(name, variant)
|
44
|
+
|
45
|
+
return project_list[index] if index
|
46
|
+
end
|
47
|
+
|
48
|
+
def find_project_index(name, variant = nil)
|
49
|
+
project_list.find_index { |p| p.name == name && (variant.nil? || p.variant == variant) }
|
50
|
+
end
|
51
|
+
|
52
|
+
def save_project(project, project_index = nil)
|
53
|
+
project = project.to_h unless project.is_a?(Hash)
|
54
|
+
|
55
|
+
index = project_index || find_project_index(project[:name])
|
56
|
+
|
57
|
+
if index.nil?
|
58
|
+
data[:projects] << project
|
59
|
+
else
|
60
|
+
data[:projects][index] = project
|
61
|
+
end
|
62
|
+
|
63
|
+
write
|
64
|
+
clear_memoization
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def initialize_model
|
70
|
+
if File.exist?(filename)
|
71
|
+
read
|
72
|
+
return
|
73
|
+
end
|
74
|
+
|
75
|
+
@data = { projects: [] }
|
76
|
+
|
77
|
+
write
|
78
|
+
end
|
79
|
+
|
80
|
+
def clear_memoization
|
81
|
+
@project_list = nil
|
82
|
+
end
|
83
|
+
|
84
|
+
def read
|
85
|
+
@data = JSON.parse(File.read(filename), symbolize_names: true)
|
86
|
+
end
|
87
|
+
|
88
|
+
def write
|
89
|
+
FileUtils.mkdir_p(File.dirname(filename))
|
90
|
+
File.write(filename, JSON.pretty_generate(data))
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'pry'
|
4
|
+
require 'date'
|
5
|
+
require 'thor'
|
6
|
+
|
7
|
+
module KStarter
|
8
|
+
# Handle the global access such as configuration
|
9
|
+
class Map
|
10
|
+
class << self
|
11
|
+
def project(project_hash)
|
12
|
+
case project_hash[:type].to_sym
|
13
|
+
when :gem
|
14
|
+
KStarter::Schema::GemProject.new(project_hash)
|
15
|
+
when :rails
|
16
|
+
KStarter::Schema::RailsProject.new(project_hash)
|
17
|
+
when :svelte
|
18
|
+
KStarter::Schema::SvelteProject.new(project_hash)
|
19
|
+
when :nuxt
|
20
|
+
KStarter::Schema::NuxtProject.new(project_hash)
|
21
|
+
else
|
22
|
+
raise "Unknown project type: #{project_hash[:type]}"
|
23
|
+
end
|
24
|
+
rescue StandardError => e
|
25
|
+
puts e.message
|
26
|
+
end
|
27
|
+
|
28
|
+
def starter(project_data)
|
29
|
+
project = project_data.is_a?(Hash) ? project(project_data) : project_data
|
30
|
+
|
31
|
+
raise "Unknown project type: #{project_data[:type]}" if project.nil?
|
32
|
+
|
33
|
+
case project.type
|
34
|
+
when :gem
|
35
|
+
KStarter::Starters::Gem.new(project)
|
36
|
+
when :rails
|
37
|
+
KStarter::Starters::Rails.new(project)
|
38
|
+
when :svelte
|
39
|
+
KStarter::Starters::Svelte.new(project)
|
40
|
+
when :nuxt
|
41
|
+
KStarter::Starters::Nuxt.new(project)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module KStarter
|
4
|
+
module Questions
|
5
|
+
# Select a form with questions and load it up as a New form or
|
6
|
+
# an Edit form by optionally providing data
|
7
|
+
class AskQuestions
|
8
|
+
class << self
|
9
|
+
def for(form_type, form_variant = nil, **data)
|
10
|
+
return KStarter::Questions::Rails.new(**data) if form_type == :rails
|
11
|
+
return KStarter::Questions::LibraryGem.new(**data) if form_type == :gem && form_variant == :library
|
12
|
+
return KStarter::Questions::CliGem.new(**data) if form_type == :gem && form_variant == :cli
|
13
|
+
return KStarter::Questions::Svelte.new(**data) if form_type == :svelte
|
14
|
+
|
15
|
+
raise "Unknown form type: #{form_type}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,208 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# see: bundle --help
|
4
|
+
# example: bundle gem --coc --test=rspec --mit k_project
|
5
|
+
# km2 new k_project -t ruby_gem \
|
6
|
+
# --description "k_project is a command line GEM for building new ruby, rails and other language projects" \
|
7
|
+
# --user-story "As a Developer, I want a simple path to creating new projects in different languages, so that I be productive quickly"
|
8
|
+
|
9
|
+
module KStarter
|
10
|
+
module Questions
|
11
|
+
# Ask code generations for a new projects.
|
12
|
+
class BaseQuestion
|
13
|
+
include TtyHelpers
|
14
|
+
|
15
|
+
attr_reader :name # project name
|
16
|
+
attr_reader :type # project type
|
17
|
+
attr_reader :variant # project variant
|
18
|
+
attr_reader :root_path # project root path
|
19
|
+
attr_reader :sub_path # project sub path, useful for folders under the root such as klueless projects
|
20
|
+
attr_reader :github_key # github user_name or organization name
|
21
|
+
attr_reader :description # project description
|
22
|
+
attr_reader :story_active # is story required?
|
23
|
+
attr_reader :actor # who is the actor
|
24
|
+
attr_reader :problem # what problem do they have
|
25
|
+
attr_reader :solution # what is the intended solution
|
26
|
+
attr_reader :user_story # what is the primary user story
|
27
|
+
attr_reader :klue_template_active # is klue_template used?
|
28
|
+
attr_reader :klue_template_name # name of the klue template
|
29
|
+
|
30
|
+
def initialize(**args)
|
31
|
+
initialize_attributes(**args)
|
32
|
+
apply_attribute_defaults
|
33
|
+
clean_attributes
|
34
|
+
end
|
35
|
+
|
36
|
+
def default_questions; end
|
37
|
+
|
38
|
+
def question
|
39
|
+
@question ||= prompt
|
40
|
+
end
|
41
|
+
|
42
|
+
def ask_root_path
|
43
|
+
project_type_config = App.config.get_project_type(type, variant)
|
44
|
+
configured_path = project_type_config.nil? ? '~/unknown_project' : project_type_config[:path]
|
45
|
+
|
46
|
+
@root_path = question.ask('Root project path') do |q|
|
47
|
+
q.default(configured_path)
|
48
|
+
q.required(true)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def ask_sub_path
|
53
|
+
project_type_config = App.config.get_project_type(type, variant)
|
54
|
+
configured_path = project_type_config.nil? ? '~/unknown_project' : project_type_config[:sub_path]
|
55
|
+
|
56
|
+
@sub_path = question.ask('Sub path within the project') do |q|
|
57
|
+
q.default(configured_path)
|
58
|
+
q.required(true)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def ask_github_key
|
63
|
+
choices = [App.config.github_user] + App.config.github_organizations
|
64
|
+
@github_key = prompt.select('Select Github user or organization', choices, cycle: true, filter: true, default: @github_key)
|
65
|
+
end
|
66
|
+
|
67
|
+
def ask_description
|
68
|
+
@description = question.ask('Description', default: @description)
|
69
|
+
end
|
70
|
+
|
71
|
+
def ask_story_active?
|
72
|
+
@story_active = question.yes?('Is a user story required?', default: @story_active)
|
73
|
+
show_story(actor: @actor, problem: @problem, solution: @solution)
|
74
|
+
@story_active
|
75
|
+
end
|
76
|
+
|
77
|
+
def ask_actor
|
78
|
+
@actor = prompt.ask('Who is the primary actor for this project?', default: @actor || 'Developer')
|
79
|
+
# show_story(actor: @actor)
|
80
|
+
end
|
81
|
+
|
82
|
+
def ask_problem
|
83
|
+
@problem = question.ask('What problem are you solving?', default: @problem)
|
84
|
+
# show_story(actor: @actor, problem: @problem)
|
85
|
+
end
|
86
|
+
|
87
|
+
def ask_solution
|
88
|
+
@solution = question.ask('What is the intended solution?', default: @solution)
|
89
|
+
# show_story(actor: @actor, problem: @problem, solution: @solution)
|
90
|
+
end
|
91
|
+
|
92
|
+
def show_story(**args)
|
93
|
+
prompt.warn("As a #{args[:actor] || 'ACTOR'}, I want to #{args[:problem] || 'SOLVE PROBLEM'} so that I can #{args[:solution] || 'HAVE BENEFIT'}")
|
94
|
+
end
|
95
|
+
|
96
|
+
def ask_user_story
|
97
|
+
@user_story = question.ask('User Story', default: "As a #{actor}, I want to #{problem} so that I can #{solution}")
|
98
|
+
end
|
99
|
+
|
100
|
+
def story_questions
|
101
|
+
return unless ask_story_active?
|
102
|
+
|
103
|
+
ask_actor
|
104
|
+
ask_problem
|
105
|
+
ask_solution
|
106
|
+
ask_user_story
|
107
|
+
end
|
108
|
+
|
109
|
+
# ask_user_story
|
110
|
+
|
111
|
+
def ask_klue_template_active?
|
112
|
+
@klue_template_active = question.yes?('Does this project use a Klue Templates?', default: @klue_template_active)
|
113
|
+
@klue_template_active
|
114
|
+
end
|
115
|
+
|
116
|
+
def ask_klue_template_name
|
117
|
+
prompt.warn('Location: ~/dev/kgems/k_templates/definitions/starter')
|
118
|
+
@klue_template_name = prompt.ask('Klue starter template name', default: infer_klue_template_name(@klue_template_name)) do |q|
|
119
|
+
q.required(true)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def klue_template_questions
|
124
|
+
return unless ask_klue_template_active?
|
125
|
+
|
126
|
+
ask_klue_template_name
|
127
|
+
end
|
128
|
+
|
129
|
+
def infer_klue_template_name(klue_template_name)
|
130
|
+
return klue_template_name unless klue_template_name.nil?
|
131
|
+
|
132
|
+
case type
|
133
|
+
when :rails, :svelte, :nuxt3
|
134
|
+
return type.to_s
|
135
|
+
when :gem
|
136
|
+
# return variant == :library ? 'ruby_gem' : 'ruby_gem_cli'
|
137
|
+
return 'ruby_gem'
|
138
|
+
end
|
139
|
+
nil
|
140
|
+
end
|
141
|
+
|
142
|
+
def default_story_active
|
143
|
+
@story_active = true if @story_active.nil?
|
144
|
+
end
|
145
|
+
|
146
|
+
def default_klue_template_active
|
147
|
+
@klue_template_active = true if @klue_template_active.nil?
|
148
|
+
end
|
149
|
+
|
150
|
+
def to_h
|
151
|
+
{
|
152
|
+
name: name,
|
153
|
+
type: type,
|
154
|
+
variant: variant,
|
155
|
+
root_path: root_path,
|
156
|
+
description: description,
|
157
|
+
github_key: github_key,
|
158
|
+
story: {
|
159
|
+
active: story_active,
|
160
|
+
actor: actor,
|
161
|
+
problem: problem,
|
162
|
+
solution: solution,
|
163
|
+
user_story: user_story
|
164
|
+
},
|
165
|
+
klue_template: {
|
166
|
+
active: klue_template_active,
|
167
|
+
name: klue_template_name
|
168
|
+
}
|
169
|
+
}
|
170
|
+
end
|
171
|
+
|
172
|
+
private
|
173
|
+
|
174
|
+
def initialize_attributes(**args)
|
175
|
+
@name = args[:name]
|
176
|
+
@type = args[:type]
|
177
|
+
@variant = args[:variant]
|
178
|
+
@root_path = args[:root_path]
|
179
|
+
@sub_path = args[:sub_path]
|
180
|
+
@github_key = args[:github_key]
|
181
|
+
@description = args[:description]
|
182
|
+
@story_active = args.dig(:story, :active)
|
183
|
+
@actor = args.dig(:story, :actor)
|
184
|
+
@problem = args.dig(:story, :problem)
|
185
|
+
@solution = args.dig(:story, :solution)
|
186
|
+
@user_story = args.dig(:story, :user_story)
|
187
|
+
@klue_template_active = args.dig(:klue_template, :active)
|
188
|
+
@klue_template_name = args.dig(:klue_template, :name)
|
189
|
+
end
|
190
|
+
|
191
|
+
def apply_attribute_defaults; end
|
192
|
+
|
193
|
+
def clean_attributes
|
194
|
+
@story_active = handle_boolean(@story_active)
|
195
|
+
@klue_template_active = handle_boolean(@klue_template_active)
|
196
|
+
end
|
197
|
+
|
198
|
+
def handle_boolean(value)
|
199
|
+
case value
|
200
|
+
when true, 'true', 't', 'yes', 'y', '1'
|
201
|
+
true
|
202
|
+
else
|
203
|
+
false
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|