k_starter 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|