boothby 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +164 -0
- data/Gemfile +14 -0
- data/Gemfile.lock +221 -0
- data/LICENSE.txt +20 -0
- data/README.md +37 -0
- data/Rakefile +12 -0
- data/boothby.gemspec +44 -0
- data/config/database.yml +12 -0
- data/config/initializers/boothby.rb +5 -0
- data/db/seeds.yml +0 -0
- data/docs/CHANGELOG.md +5 -0
- data/docs/CODE_OF_CONDUCT.md +84 -0
- data/docs/_config.yml +1 -0
- data/docs/index.md +37 -0
- data/exe/boothby +18 -0
- data/lib/boothby/base.rb +6 -0
- data/lib/boothby/cli.rb +63 -0
- data/lib/boothby/command.rb +121 -0
- data/lib/boothby/commands/seed.rb +18 -0
- data/lib/boothby/commands/setup.rb +18 -0
- data/lib/boothby/commands/update.rb +18 -0
- data/lib/boothby/configuration.rb +61 -0
- data/lib/boothby/key_ring.rb +43 -0
- data/lib/boothby/maintenance.rb +99 -0
- data/lib/boothby/seeds.rb +173 -0
- data/lib/boothby/templates/.gitkeep +1 -0
- data/lib/boothby/templates/seed/.gitkeep +1 -0
- data/lib/boothby/templates/setup/.gitkeep +1 -0
- data/lib/boothby/templates/update/.gitkeep +1 -0
- data/lib/boothby/version.rb +5 -0
- data/lib/boothby/yaml_reader.rb +77 -0
- data/lib/boothby.rb +20 -0
- data/node_modules/.yarn-integrity +10 -0
- data/sig/boothby.rbs +4 -0
- data/yarn.lock +4 -0
- metadata +181 -0
data/exe/boothby
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
lib_path = File.expand_path('../lib', __dir__)
|
5
|
+
$LOAD_PATH.unshift(lib_path) unless $LOAD_PATH.include?(lib_path)
|
6
|
+
require 'boothby/cli'
|
7
|
+
|
8
|
+
Signal.trap('INT') do
|
9
|
+
warn("\n#{caller.join("\n")}: interrupted")
|
10
|
+
exit(1)
|
11
|
+
end
|
12
|
+
|
13
|
+
begin
|
14
|
+
Boothby::CLI.start
|
15
|
+
rescue Boothby::CLI::Error => e
|
16
|
+
puts("ERROR: #{e.message}")
|
17
|
+
exit(1)
|
18
|
+
end
|
data/lib/boothby/base.rb
ADDED
data/lib/boothby/cli.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'thor'
|
4
|
+
|
5
|
+
module Boothby
|
6
|
+
# Handle the application command line parsing
|
7
|
+
# and the dispatch to various command objects
|
8
|
+
#
|
9
|
+
# @api public
|
10
|
+
class CLI < Thor
|
11
|
+
# Error raised by this runner
|
12
|
+
Error = Class.new(StandardError)
|
13
|
+
|
14
|
+
desc 'version', 'boothby version'
|
15
|
+
def version
|
16
|
+
require_relative('version')
|
17
|
+
puts("v#{Boothby::VERSION}")
|
18
|
+
end
|
19
|
+
map %w[--version -v] => :version
|
20
|
+
|
21
|
+
desc 'seed', 'Command description...'
|
22
|
+
method_option :help,
|
23
|
+
aliases: '-h',
|
24
|
+
type: :boolean,
|
25
|
+
desc: 'Display usage information'
|
26
|
+
def seed(*)
|
27
|
+
if options[:help]
|
28
|
+
invoke(:help, ['seed'])
|
29
|
+
else
|
30
|
+
require_relative('commands/seed')
|
31
|
+
Boothby::Commands::Seed.new(options).execute
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
desc 'update', 'Command description...'
|
36
|
+
method_option :help,
|
37
|
+
aliases: '-h',
|
38
|
+
type: :boolean,
|
39
|
+
desc: 'Display usage information'
|
40
|
+
def update(*)
|
41
|
+
if options[:help]
|
42
|
+
invoke(:help, ['update'])
|
43
|
+
else
|
44
|
+
require_relative('commands/update')
|
45
|
+
Boothby::Commands::Update.new(options).execute
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
desc 'setup', 'Command description...'
|
50
|
+
method_option :help,
|
51
|
+
aliases: '-h',
|
52
|
+
type: :boolean,
|
53
|
+
desc: 'Display usage information'
|
54
|
+
def setup(*)
|
55
|
+
if options[:help]
|
56
|
+
invoke(:help, ['setup'])
|
57
|
+
else
|
58
|
+
require_relative('commands/setup')
|
59
|
+
Boothby::Commands::Setup.new(options).execute
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'forwardable'
|
4
|
+
|
5
|
+
module Boothby
|
6
|
+
class Command
|
7
|
+
extend Forwardable
|
8
|
+
|
9
|
+
def_delegators :command, :run
|
10
|
+
|
11
|
+
# Execute this command
|
12
|
+
#
|
13
|
+
# @api public
|
14
|
+
def execute(*)
|
15
|
+
raise(
|
16
|
+
NotImplementedError,
|
17
|
+
"#{self.class}##{__method__} must be implemented"
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
# The external commands runner
|
22
|
+
#
|
23
|
+
# @see http://www.rubydoc.info/gems/tty-command
|
24
|
+
#
|
25
|
+
# @api public
|
26
|
+
def command(**options)
|
27
|
+
require('tty-command')
|
28
|
+
TTY::Command.new(options)
|
29
|
+
end
|
30
|
+
|
31
|
+
# The cursor movement
|
32
|
+
#
|
33
|
+
# @see http://www.rubydoc.info/gems/tty-cursor
|
34
|
+
#
|
35
|
+
# @api public
|
36
|
+
def cursor
|
37
|
+
require('tty-cursor')
|
38
|
+
TTY::Cursor
|
39
|
+
end
|
40
|
+
|
41
|
+
# Open a file or text in the user's preferred editor
|
42
|
+
#
|
43
|
+
# @see http://www.rubydoc.info/gems/tty-editor
|
44
|
+
#
|
45
|
+
# @api public
|
46
|
+
def editor
|
47
|
+
require('tty-editor')
|
48
|
+
TTY::Editor
|
49
|
+
end
|
50
|
+
|
51
|
+
# File manipulation utility methods
|
52
|
+
#
|
53
|
+
# @see http://www.rubydoc.info/gems/tty-file
|
54
|
+
#
|
55
|
+
# @api public
|
56
|
+
def generator
|
57
|
+
require('tty-file')
|
58
|
+
TTY::File
|
59
|
+
end
|
60
|
+
|
61
|
+
# Terminal output paging
|
62
|
+
#
|
63
|
+
# @see http://www.rubydoc.info/gems/tty-pager
|
64
|
+
#
|
65
|
+
# @api public
|
66
|
+
def pager(**options)
|
67
|
+
require('tty-pager')
|
68
|
+
TTY::Pager.new(options)
|
69
|
+
end
|
70
|
+
|
71
|
+
# Terminal platform and OS properties
|
72
|
+
#
|
73
|
+
# @see http://www.rubydoc.info/gems/tty-pager
|
74
|
+
#
|
75
|
+
# @api public
|
76
|
+
def platform
|
77
|
+
require('tty-platform')
|
78
|
+
TTY::Platform.new
|
79
|
+
end
|
80
|
+
|
81
|
+
# The interactive prompt
|
82
|
+
#
|
83
|
+
# @see http://www.rubydoc.info/gems/tty-prompt
|
84
|
+
#
|
85
|
+
# @api public
|
86
|
+
def prompt(**options)
|
87
|
+
require('tty-prompt')
|
88
|
+
TTY::Prompt.new(options)
|
89
|
+
end
|
90
|
+
|
91
|
+
# Get terminal screen properties
|
92
|
+
#
|
93
|
+
# @see http://www.rubydoc.info/gems/tty-screen
|
94
|
+
#
|
95
|
+
# @api public
|
96
|
+
def screen
|
97
|
+
require('tty-screen')
|
98
|
+
TTY::Screen
|
99
|
+
end
|
100
|
+
|
101
|
+
# The unix which utility
|
102
|
+
#
|
103
|
+
# @see http://www.rubydoc.info/gems/tty-which
|
104
|
+
#
|
105
|
+
# @api public
|
106
|
+
def which(*args)
|
107
|
+
require('tty-which')
|
108
|
+
TTY::Which.which(*args)
|
109
|
+
end
|
110
|
+
|
111
|
+
# Check if executable exists
|
112
|
+
#
|
113
|
+
# @see http://www.rubydoc.info/gems/tty-which
|
114
|
+
#
|
115
|
+
# @api public
|
116
|
+
def exec_exist?(*args)
|
117
|
+
require('tty-which')
|
118
|
+
TTY::Which.exist?(*args)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../command'
|
4
|
+
require_relative '../app'
|
5
|
+
|
6
|
+
module Boothby
|
7
|
+
module Commands
|
8
|
+
class Seed < Boothby::Command
|
9
|
+
def initialize(options)
|
10
|
+
@options = options
|
11
|
+
end
|
12
|
+
|
13
|
+
def execute(input: $stdin, output: $stdout)
|
14
|
+
Boothby::Seed.seed!
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../command'
|
4
|
+
require_relative '../app'
|
5
|
+
|
6
|
+
module Boothby
|
7
|
+
module Commands
|
8
|
+
class Setup < Boothby::Command
|
9
|
+
def initialize(options)
|
10
|
+
@options = options
|
11
|
+
end
|
12
|
+
|
13
|
+
def execute(input: $stdin, output: $stdout)
|
14
|
+
Boothby::App.setup
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../command'
|
4
|
+
require_relative '../app'
|
5
|
+
|
6
|
+
module Boothby
|
7
|
+
module Commands
|
8
|
+
class Update < Boothby::Command
|
9
|
+
def initialize(options)
|
10
|
+
@options = options
|
11
|
+
end
|
12
|
+
|
13
|
+
def execute(input: $stdin, output: $stdout)
|
14
|
+
Boothby::App.update
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Boothby
|
4
|
+
module Configuration
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
add_config :root
|
9
|
+
add_config :seeds_configuration
|
10
|
+
add_config :configuration_directory
|
11
|
+
|
12
|
+
# set default values
|
13
|
+
reset_config
|
14
|
+
end
|
15
|
+
|
16
|
+
module ClassMethods
|
17
|
+
def add_config(name)
|
18
|
+
class_eval(<<-METHODS, __FILE__, __LINE__ + 1)
|
19
|
+
@#{name} = nil
|
20
|
+
def self.#{name}(value=nil)
|
21
|
+
@#{name} = value if value
|
22
|
+
return @#{name} if self.object_id == #{object_id} || defined?(@#{name})
|
23
|
+
name = superclass.#{name}
|
24
|
+
return nil if name.nil? && !instance_variable_defined?(:@#{name})
|
25
|
+
@#{name} = name && !name.is_a?(Module) && !name.is_a?(Symbol) && !name.is_a?(Numeric) && !name.is_a?(TrueClass) && !name.is_a?(FalseClass) ? name.dup : name
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.#{name}=(value)
|
29
|
+
@#{name} = value
|
30
|
+
end
|
31
|
+
|
32
|
+
def #{name}=(value)
|
33
|
+
@#{name} = value
|
34
|
+
end
|
35
|
+
|
36
|
+
def #{name}
|
37
|
+
value = @#{name} if instance_variable_defined?(:@#{name})
|
38
|
+
value = self.class.#{name} unless instance_variable_defined?(:@#{name})
|
39
|
+
if value.instance_of?(Proc)
|
40
|
+
value.arity >= 1 ? value.call(self) : value.call
|
41
|
+
else
|
42
|
+
value
|
43
|
+
end
|
44
|
+
end
|
45
|
+
METHODS
|
46
|
+
end
|
47
|
+
|
48
|
+
def configure
|
49
|
+
yield(self)
|
50
|
+
end
|
51
|
+
|
52
|
+
def reset_config
|
53
|
+
configure do |config|
|
54
|
+
config.root = -> { Rails.root }
|
55
|
+
config.seeds_configuration = 'db/seeds.yml'
|
56
|
+
config.configuration_directory = 'config'
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'singleton'
|
4
|
+
require_relative 'yaml_reader'
|
5
|
+
|
6
|
+
# Store configuration YAML files
|
7
|
+
module Boothby
|
8
|
+
class KeyRing
|
9
|
+
include Singleton
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
config_files = Dir[Rails.root.join('config/*.y{a,}ml{.erb,}')]
|
13
|
+
@configs = config_files.to_h do |config|
|
14
|
+
config_name = File.basename(config).split('.').first.to_sym
|
15
|
+
[config_name, Boothby::YAMLReader.new(config)]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.method_missing(method_name, *arguments, **kwargs, &block)
|
20
|
+
if instance.respond_to?(method_name)
|
21
|
+
instance.public_send(method_name)
|
22
|
+
else
|
23
|
+
super
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.respond_to_missing?(method_name, include_private = false)
|
28
|
+
instance.respond_to?(method_name) || super
|
29
|
+
end
|
30
|
+
|
31
|
+
def method_missing(method_name, *arguments, **kwargs, &block)
|
32
|
+
if @configs.key?(method_name.to_sym)
|
33
|
+
@configs[method_name.to_sym]
|
34
|
+
else
|
35
|
+
super
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def respond_to_missing?(method_name, include_private = false)
|
40
|
+
@configs.key?(method_name.to_sym) || super
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
require 'tty-command'
|
5
|
+
|
6
|
+
module Boothby
|
7
|
+
class Toolbox
|
8
|
+
class << self
|
9
|
+
attr_writer :root
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.setup_application
|
13
|
+
FileUtils.chdir(app_dir) do
|
14
|
+
copy_example_files
|
15
|
+
install_dependencies
|
16
|
+
rake_task('db:prepare', 'db:test:prepare', label: 'Preparing database')
|
17
|
+
rake_task('log:clear', 'tmp:clear', label: 'Cleaning old files')
|
18
|
+
rake_task('restart', label: 'Restarting application server')
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.update_application
|
23
|
+
FileUtils.chdir(app_dir) do
|
24
|
+
copy_example_files
|
25
|
+
install_dependencies
|
26
|
+
rake_task('db:migrate', label: 'Updating database')
|
27
|
+
rake_task('log:clear', 'tmp:clear', label: 'Cleaning old files')
|
28
|
+
rake_task('restart', label: 'Restarting application server')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.upgrade_application
|
33
|
+
FileUtils.chdir(app_dir) do
|
34
|
+
copy_example_files
|
35
|
+
install_dependencies
|
36
|
+
rake_task('db:migrate', label: 'Updating database')
|
37
|
+
rake_task('log:clear', 'tmp:clear', label: 'Cleaning old files')
|
38
|
+
rake_task('restart', label: 'Restarting application server')
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
private_class_method def self.install_dependencies
|
43
|
+
puts("\n== Installing dependencies ==")
|
44
|
+
bundle_install
|
45
|
+
yarn_install
|
46
|
+
end
|
47
|
+
|
48
|
+
private_class_method def self.yarn_install
|
49
|
+
return unless File.exist?('package.json')
|
50
|
+
|
51
|
+
system('command', '-v', 'yarn') || system('npm', 'install', '-g', 'yarn')
|
52
|
+
run!(:yarn, :install)
|
53
|
+
end
|
54
|
+
|
55
|
+
private_class_method def self.bundle_install
|
56
|
+
return unless File.exist?('Gemfile')
|
57
|
+
|
58
|
+
system('bundle', 'check') || run!(:bundle, :install)
|
59
|
+
end
|
60
|
+
|
61
|
+
private_class_method def self.copy_example_files
|
62
|
+
example_files = Dir['**/*.example*'].filter_map do |example_file|
|
63
|
+
real_file = example_file.gsub('.example', '')
|
64
|
+
[example_file, real_file] unless File.exist?(real_file)
|
65
|
+
end
|
66
|
+
|
67
|
+
return unless example_files.any?
|
68
|
+
|
69
|
+
puts("\n== Copying example files ==")
|
70
|
+
example_files.each { |ef, rf| run(:cp, ef, rf) }
|
71
|
+
end
|
72
|
+
|
73
|
+
private_class_method def self.rake_task(*args, label:)
|
74
|
+
puts("\n== #{label} ==")
|
75
|
+
run(:bundle, :exec, :rails, *args)
|
76
|
+
end
|
77
|
+
|
78
|
+
private_class_method def self.run(*args, **kwargs)
|
79
|
+
kwargs[:only_output_on_error] = true
|
80
|
+
cmd.run!(*args, **kwargs)
|
81
|
+
end
|
82
|
+
|
83
|
+
private_class_method def self.run!(*args, **kwargs)
|
84
|
+
kwargs[:only_output_on_error] = false
|
85
|
+
cmd.run!(*args, **kwargs)
|
86
|
+
end
|
87
|
+
|
88
|
+
private_class_method def self.cmd
|
89
|
+
@cmd ||= TTY::Command.new(
|
90
|
+
uuid: false,
|
91
|
+
color: true
|
92
|
+
)
|
93
|
+
end
|
94
|
+
|
95
|
+
private_class_method def self.app_dir
|
96
|
+
(@root || File.expand_path('../..', __dir__))
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,173 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'tty-spinner'
|
4
|
+
|
5
|
+
module Boothby
|
6
|
+
class Plant
|
7
|
+
class << self
|
8
|
+
attr_writer :root, :config_file, :rails_env
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.seed!
|
12
|
+
require_seed_modules!
|
13
|
+
|
14
|
+
seed(environment: :base)
|
15
|
+
seed(environment: rails_env)
|
16
|
+
end
|
17
|
+
|
18
|
+
private_class_method def self.seed(environment:)
|
19
|
+
label = environment == :base ? 'ALL ENVIRONMENTS' : environment.to_s.upcase
|
20
|
+
env_class = environment.to_s.classify
|
21
|
+
multi_spinner = TTY::Spinner::Multi.new(
|
22
|
+
"[:spinner] SEEDING MODELS FOR #{label}",
|
23
|
+
hide_cursor: true,
|
24
|
+
success_mark: pastel.green('✓'),
|
25
|
+
error_mark: pastel.red('×'),
|
26
|
+
interval: 5,
|
27
|
+
format: :arc,
|
28
|
+
style: {
|
29
|
+
top: ' ',
|
30
|
+
middle: ' ',
|
31
|
+
bottom: ' '
|
32
|
+
}
|
33
|
+
)
|
34
|
+
|
35
|
+
config(environment).each do |seed_class|
|
36
|
+
seed_from(seed_class)
|
37
|
+
end
|
38
|
+
multi_spinner.auto_spin
|
39
|
+
end
|
40
|
+
|
41
|
+
private_class_method def self.root(*args)
|
42
|
+
@root ||= File.expand_path('../..', __dir__)
|
43
|
+
File.join(@root, *args)
|
44
|
+
end
|
45
|
+
|
46
|
+
private_class_method def self.rails_env
|
47
|
+
(@rails_env || 'development').to_sym
|
48
|
+
end
|
49
|
+
|
50
|
+
private_class_method def self.seeds_available?(*path)
|
51
|
+
Dir[root(:db, :seeds, *path, '*.rb"')].count > 0
|
52
|
+
end
|
53
|
+
|
54
|
+
private_class_method def self.config_file
|
55
|
+
(@config_file || root('db/seeds.yml'))
|
56
|
+
end
|
57
|
+
|
58
|
+
private_class_method def self.require_modules(*path)
|
59
|
+
Dir[root(:db, :seeds, *path, '*.rb"')].sort.each { |s| require(s) }
|
60
|
+
end
|
61
|
+
|
62
|
+
private_class_method def self.config
|
63
|
+
@config ||= begin
|
64
|
+
content = File.read(config_file)
|
65
|
+
yml = YAML.safe_load(content, [Time, Date], aliases: true)
|
66
|
+
yml.with_indifferent_access
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.seed_from(seed_class)
|
71
|
+
multi_spinner.register(
|
72
|
+
'[:spinner] :title',
|
73
|
+
hide_cursor: true,
|
74
|
+
success_mark: pastel.green('✓'),
|
75
|
+
error_mark: pastel.red('×'),
|
76
|
+
interval: 5,
|
77
|
+
format: :arc
|
78
|
+
) do |spinner|
|
79
|
+
title = seed_method[4..-1].titleize
|
80
|
+
spinner.update(title: "Seeding #{title}")
|
81
|
+
seed_class.public_send(seed_method)
|
82
|
+
spinner.update(title: "Seeded #{title}")
|
83
|
+
spinner.success
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.seed_methods(seed_class)
|
88
|
+
methods = seed_class.methods.map(&:to_s).select do |method|
|
89
|
+
method.starts_with?('seed_')
|
90
|
+
end
|
91
|
+
methods.sort_by { |method| seed_class.method(method).source_location.last }
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# :nodoc:
|
97
|
+
module Seeds
|
98
|
+
# rubocop:disable Style/OpenStructUse
|
99
|
+
def self.departments
|
100
|
+
[
|
101
|
+
Department.master_department,
|
102
|
+
Department.executive_health,
|
103
|
+
Department.signature_care,
|
104
|
+
OpenStruct.new(name: 'General', key: 'general')
|
105
|
+
]
|
106
|
+
end
|
107
|
+
# rubocop:enable Style/OpenStructUse
|
108
|
+
|
109
|
+
def self.sprout
|
110
|
+
return if Rails.env.test?
|
111
|
+
|
112
|
+
require_seed_modules!
|
113
|
+
|
114
|
+
seed_by_departments(environment: :base)
|
115
|
+
seed_by_departments(environment: Rails.env.to_sym)
|
116
|
+
end
|
117
|
+
|
118
|
+
def self.seed(environment:)
|
119
|
+
label = environment == :base ? 'ALL ENVIRONMENTS' : environment.to_s.upcase
|
120
|
+
env_class = environment.to_s.classify
|
121
|
+
multi_spinner = TTY::Spinner::Multi.new(
|
122
|
+
"[:spinner] SEEDING MODELS FOR #{label}",
|
123
|
+
hide_cursor: true,
|
124
|
+
success_mark: pastel.green('✓'),
|
125
|
+
error_mark: pastel.red('×'),
|
126
|
+
interval: 5,
|
127
|
+
format: :arc
|
128
|
+
)
|
129
|
+
|
130
|
+
departments.each do |department|
|
131
|
+
next unless seeds_available?(environment, department)
|
132
|
+
|
133
|
+
seed_class = "Seeds::#{env_class}::#{department.key.classify}".constantize
|
134
|
+
|
135
|
+
display(department.name.upcase, indent: 1)
|
136
|
+
seed_from(seed_class, department: department)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def self.require_seed_modules!
|
141
|
+
Dir[Rails.root.join('db/seeds/**/*.rb')].sort.each { |s| require(s) }
|
142
|
+
end
|
143
|
+
|
144
|
+
def self.seed_from(seed_class, department:)
|
145
|
+
seed_methods(seed_class).each do |seed_method|
|
146
|
+
title = seed_method[4..-1].titleize
|
147
|
+
display("Seeding #{title}...\n", indent: 2)
|
148
|
+
seed_class.public_send(seed_method, department)
|
149
|
+
display("Seeded: #{title}\n", indent: 2)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def self.seed_methods(seed_class)
|
154
|
+
methods = seed_class.methods.map(&:to_s).select do |method|
|
155
|
+
method.starts_with?('seed_')
|
156
|
+
end
|
157
|
+
methods.sort_by { |method| seed_class.method(method).source_location.last }
|
158
|
+
end
|
159
|
+
|
160
|
+
def self.display(text, indent: 0, header: false)
|
161
|
+
text = "\n====== #{text}" if header
|
162
|
+
text = "#{' ' * indent}- #{text}" if indent > 0
|
163
|
+
|
164
|
+
puts(text)
|
165
|
+
end
|
166
|
+
|
167
|
+
def self.seeds_available?(environment, department)
|
168
|
+
seed_path = "db/seeds/#{environment}/#{department.key}/*.rb"
|
169
|
+
Dir[Rails.root.join(seed_path)].count > 0
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
Seeds.sprout
|
@@ -0,0 +1 @@
|
|
1
|
+
#
|
@@ -0,0 +1 @@
|
|
1
|
+
#
|
@@ -0,0 +1 @@
|
|
1
|
+
#
|
@@ -0,0 +1 @@
|
|
1
|
+
#
|