hanami-cli 0.3.0 → 2.0.0.alpha3
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/.github/workflows/ci.yml +42 -0
- data/.gitignore +4 -2
- data/.rspec +1 -0
- data/.rubocop.yml +25 -1
- data/CHANGELOG.md +30 -1
- data/CODE_OF_CONDUCT.md +84 -0
- data/Gemfile +13 -6
- data/LICENSE.txt +21 -0
- data/README.md +12 -605
- data/Rakefile +9 -12
- data/bin/console +1 -0
- data/exe/hanami +10 -0
- data/hanami-cli.gemspec +25 -18
- data/lib/hanami/cli/bundler.rb +73 -0
- data/lib/hanami/cli/command.rb +16 -355
- data/lib/hanami/cli/command_line.rb +17 -0
- data/lib/hanami/cli/commands/application.rb +63 -0
- data/lib/hanami/cli/commands/db/utils/database.rb +122 -0
- data/lib/hanami/cli/commands/db/utils/database_config.rb +48 -0
- data/lib/hanami/cli/commands/db/utils/mysql.rb +27 -0
- data/lib/hanami/cli/commands/db/utils/postgres.rb +49 -0
- data/lib/hanami/cli/commands/db/utils/sqlite.rb +37 -0
- data/lib/hanami/cli/commands/gem/new.rb +77 -0
- data/lib/hanami/cli/commands/gem/version.rb +18 -0
- data/lib/hanami/cli/commands/gem.rb +21 -0
- data/lib/hanami/cli/commands/monolith/console.rb +50 -0
- data/lib/hanami/cli/commands/monolith/db/create.rb +25 -0
- data/lib/hanami/cli/commands/monolith/db/create_migration.rb +29 -0
- data/lib/hanami/cli/commands/monolith/db/drop.rb +25 -0
- data/lib/hanami/cli/commands/monolith/db/migrate.rb +40 -0
- data/lib/hanami/cli/commands/monolith/db/reset.rb +26 -0
- data/lib/hanami/cli/commands/monolith/db/rollback.rb +55 -0
- data/lib/hanami/cli/commands/monolith/db/sample_data.rb +40 -0
- data/lib/hanami/cli/commands/monolith/db/seed.rb +40 -0
- data/lib/hanami/cli/commands/monolith/db/setup.rb +24 -0
- data/lib/hanami/cli/commands/monolith/db/structure/dump.rb +25 -0
- data/lib/hanami/cli/commands/monolith/db/version.rb +26 -0
- data/lib/hanami/cli/commands/monolith/generate/action.rb +62 -0
- data/lib/hanami/cli/commands/monolith/generate/slice.rb +62 -0
- data/lib/hanami/cli/commands/monolith/generate.rb +14 -0
- data/lib/hanami/cli/commands/monolith/install.rb +16 -0
- data/lib/hanami/cli/commands/monolith/version.rb +18 -0
- data/lib/hanami/cli/commands/monolith.rb +55 -0
- data/lib/hanami/cli/commands.rb +26 -0
- data/lib/hanami/cli/error.rb +8 -0
- data/lib/hanami/cli/generators/context.rb +38 -0
- data/lib/hanami/cli/generators/gem/application/monolith/action.erb +21 -0
- data/lib/hanami/cli/generators/gem/application/monolith/application.erb +8 -0
- data/lib/hanami/cli/generators/gem/application/monolith/config_ru.erb +5 -0
- data/lib/hanami/cli/generators/gem/application/monolith/entities.erb +9 -0
- data/lib/hanami/cli/generators/gem/application/monolith/env.erb +0 -0
- data/lib/hanami/cli/generators/gem/application/monolith/functions.erb +13 -0
- data/lib/hanami/cli/generators/gem/application/monolith/gemfile.erb +19 -0
- data/lib/hanami/cli/generators/gem/application/monolith/keep.erb +0 -0
- data/lib/hanami/cli/generators/gem/application/monolith/operation.erb +18 -0
- data/lib/hanami/cli/generators/gem/application/monolith/rakefile.erb +3 -0
- data/lib/hanami/cli/generators/gem/application/monolith/readme.erb +1 -0
- data/lib/hanami/cli/generators/gem/application/monolith/repository.erb +13 -0
- data/lib/hanami/cli/generators/gem/application/monolith/routes.erb +4 -0
- data/lib/hanami/cli/generators/gem/application/monolith/settings.erb +6 -0
- data/lib/hanami/cli/generators/gem/application/monolith/types.erb +10 -0
- data/lib/hanami/cli/generators/gem/application/monolith/validation_contract.erb +14 -0
- data/lib/hanami/cli/generators/gem/application/monolith/view_context.erb +15 -0
- data/lib/hanami/cli/generators/gem/application/monolith.rb +83 -0
- data/lib/hanami/cli/generators/gem/application.rb +21 -0
- data/lib/hanami/cli/generators/monolith/action/action.erb +13 -0
- data/lib/hanami/cli/generators/monolith/action/template.erb +0 -0
- data/lib/hanami/cli/generators/monolith/action/template.html.erb +2 -0
- data/lib/hanami/cli/generators/monolith/action/view.erb +13 -0
- data/lib/hanami/cli/generators/monolith/action.rb +123 -0
- data/lib/hanami/cli/generators/monolith/action_context.rb +76 -0
- data/lib/hanami/cli/generators/monolith/slice/action.erb +9 -0
- data/lib/hanami/cli/generators/monolith/slice/entities.erb +9 -0
- data/lib/hanami/cli/generators/monolith/slice/keep.erb +0 -0
- data/lib/hanami/cli/generators/monolith/slice/repository.erb +10 -0
- data/lib/hanami/cli/generators/monolith/slice/routes.erb +2 -0
- data/lib/hanami/cli/generators/monolith/slice/view.erb +9 -0
- data/lib/hanami/cli/generators/monolith/slice.rb +56 -0
- data/lib/hanami/cli/generators/monolith/slice_context.rb +33 -0
- data/lib/hanami/cli/repl/core.rb +55 -0
- data/lib/hanami/cli/repl/irb.rb +41 -0
- data/lib/hanami/cli/repl/pry.rb +29 -0
- data/lib/hanami/cli/system_call.rb +51 -0
- data/lib/hanami/cli/url.rb +34 -0
- data/lib/hanami/cli/version.rb +4 -3
- data/lib/hanami/cli.rb +10 -121
- data/lib/hanami/console/context.rb +39 -0
- data/lib/hanami/console/plugins/slice_readers.rb +42 -0
- data/lib/hanami/rake_tasks.rb +52 -0
- metadata +138 -42
- data/.circleci/config.yml +0 -141
- data/.travis.yml +0 -26
- data/lib/hanami/cli/banner.rb +0 -127
- data/lib/hanami/cli/command_registry.rb +0 -213
- data/lib/hanami/cli/errors.rb +0 -44
- data/lib/hanami/cli/option.rb +0 -132
- data/lib/hanami/cli/parser.rb +0 -142
- data/lib/hanami/cli/program_name.rb +0 -19
- data/lib/hanami/cli/registry.rb +0 -328
- data/lib/hanami/cli/usage.rb +0 -89
- data/script/ci +0 -61
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "database_config"
|
|
4
|
+
|
|
5
|
+
module Hanami
|
|
6
|
+
module CLI
|
|
7
|
+
module Commands
|
|
8
|
+
module DB
|
|
9
|
+
module Utils
|
|
10
|
+
class Database
|
|
11
|
+
attr_reader :application, :config
|
|
12
|
+
|
|
13
|
+
SCHEME_MAP = {
|
|
14
|
+
"sqlite" => -> {
|
|
15
|
+
require_relative("sqlite")
|
|
16
|
+
Sqlite
|
|
17
|
+
},
|
|
18
|
+
"postgres" => -> {
|
|
19
|
+
require_relative("postgres")
|
|
20
|
+
Postgres
|
|
21
|
+
},
|
|
22
|
+
"mysql" => -> {
|
|
23
|
+
require_relative("mysql")
|
|
24
|
+
Mysql
|
|
25
|
+
}
|
|
26
|
+
}.freeze
|
|
27
|
+
|
|
28
|
+
def self.[](application)
|
|
29
|
+
config = DatabaseConfig.new(application.settings.database_url)
|
|
30
|
+
|
|
31
|
+
resolver = SCHEME_MAP.fetch(config.db_type) do
|
|
32
|
+
raise "#{config.db_type} is not a supported db scheme"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
klass = resolver.()
|
|
36
|
+
|
|
37
|
+
klass.new(application: application, config: config)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def initialize(application:, config:)
|
|
41
|
+
@application = application
|
|
42
|
+
@config = config
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def create_command
|
|
46
|
+
raise NotImplementedError
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def drop_command
|
|
50
|
+
raise NotImplementedError
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def dump_command
|
|
54
|
+
raise NotImplementedError
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def load_command
|
|
58
|
+
raise NotImplementedError
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def root_path
|
|
62
|
+
application.root
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def rom_config
|
|
66
|
+
@rom_config ||=
|
|
67
|
+
begin
|
|
68
|
+
application.init_bootable(:persistence)
|
|
69
|
+
application.container["persistence.config"]
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def name
|
|
74
|
+
config.db_name
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def applied_migrations
|
|
78
|
+
sequel_migrator.applied_migrations
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def gateway
|
|
82
|
+
rom_config.gateways[:default]
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def connection
|
|
86
|
+
gateway.connection
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def run_migrations(**options)
|
|
90
|
+
require "rom/sql"
|
|
91
|
+
ROM::SQL.with_gateway(gateway) do
|
|
92
|
+
migrator.run(options)
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def migrator
|
|
97
|
+
@migrator ||=
|
|
98
|
+
begin
|
|
99
|
+
require "rom/sql"
|
|
100
|
+
ROM::SQL::Migration::Migrator.new(connection, path: File.join(root_path, "db/migrate"))
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def applied_migrations
|
|
105
|
+
sequel_migrator.applied_migrations
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
private
|
|
109
|
+
|
|
110
|
+
def sequel_migrator
|
|
111
|
+
Sequel::TimestampMigrator.new(migrator.connection, migrations_path, {})
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def migrations_path
|
|
115
|
+
File.join(root_path, "db/migrate")
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "uri"
|
|
4
|
+
|
|
5
|
+
module Hanami
|
|
6
|
+
module CLI
|
|
7
|
+
module Commands
|
|
8
|
+
module DB
|
|
9
|
+
module Utils
|
|
10
|
+
class DatabaseConfig
|
|
11
|
+
attr_reader :uri
|
|
12
|
+
|
|
13
|
+
def initialize(database_url)
|
|
14
|
+
@uri = URI(database_url)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def hostname
|
|
18
|
+
uri.hostname
|
|
19
|
+
end
|
|
20
|
+
alias_method :host, :hostname
|
|
21
|
+
|
|
22
|
+
def user
|
|
23
|
+
uri.user
|
|
24
|
+
end
|
|
25
|
+
alias_method :username, :user
|
|
26
|
+
|
|
27
|
+
def password
|
|
28
|
+
uri.password
|
|
29
|
+
end
|
|
30
|
+
alias_method :pass, :password
|
|
31
|
+
|
|
32
|
+
def port
|
|
33
|
+
uri.port
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def db_name
|
|
37
|
+
@db_name ||= uri.path.gsub(/\A\//, "")
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def db_type
|
|
41
|
+
uri.scheme
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "database"
|
|
4
|
+
|
|
5
|
+
module Hanami
|
|
6
|
+
module CLI
|
|
7
|
+
module Commands
|
|
8
|
+
module DB
|
|
9
|
+
module Utils
|
|
10
|
+
class Mysql < Database
|
|
11
|
+
def create_command
|
|
12
|
+
raise "Not Implemented Yet"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def dump_command
|
|
16
|
+
raise "Not Implemented Yet"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def load_command
|
|
20
|
+
raise "Not Implemented Yet"
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "shellwords"
|
|
4
|
+
require_relative "database"
|
|
5
|
+
|
|
6
|
+
module Hanami
|
|
7
|
+
module CLI
|
|
8
|
+
module Commands
|
|
9
|
+
module DB
|
|
10
|
+
module Utils
|
|
11
|
+
class Postgres < Database
|
|
12
|
+
def create_command
|
|
13
|
+
system(cli_env_vars, "createdb #{escaped_name}")
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def drop_command
|
|
17
|
+
system(cli_env_vars, "dropdb #{escaped_name}")
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def dump_command
|
|
21
|
+
system(cli_env_vars, "pg_dump --schema-only --no-owner #{escaped_name} > #{dump_file}")
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def load_command
|
|
25
|
+
raise "Not Implemented Yet"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def escaped_name
|
|
29
|
+
Shellwords.escape(name)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def cli_env_vars
|
|
33
|
+
@cli_env_vars ||= {}.tap do |vars|
|
|
34
|
+
vars["PGHOST"] = config.host.to_s
|
|
35
|
+
vars["PGPORT"] = config.port.to_s if config.port
|
|
36
|
+
vars["PGUSER"] = config.user.to_s if config.user
|
|
37
|
+
vars["PGPASSWORD"] = config.pass.to_s if config.pass
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def dump_file
|
|
42
|
+
"#{root_path}/db/structure.sql"
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "database"
|
|
4
|
+
|
|
5
|
+
module Hanami
|
|
6
|
+
module CLI
|
|
7
|
+
module Commands
|
|
8
|
+
module DB
|
|
9
|
+
module Utils
|
|
10
|
+
class Sqlite < Database
|
|
11
|
+
def create_command
|
|
12
|
+
rom_config
|
|
13
|
+
true
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def drop_command
|
|
17
|
+
file_path.unlink
|
|
18
|
+
true
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def dump_command
|
|
22
|
+
raise "Not Implemented Yet"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def load_command
|
|
26
|
+
raise "Not Implemented Yet"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def file_path
|
|
30
|
+
@file_path ||= Pathname("#{root_path}#{config.uri.path}").realpath
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "hanami/cli/command"
|
|
4
|
+
require "hanami/cli/bundler"
|
|
5
|
+
require "hanami/cli/command_line"
|
|
6
|
+
require "hanami/cli/generators/gem/application"
|
|
7
|
+
require "dry/files"
|
|
8
|
+
|
|
9
|
+
module Hanami
|
|
10
|
+
module CLI
|
|
11
|
+
module Commands
|
|
12
|
+
module Gem
|
|
13
|
+
class New < Command
|
|
14
|
+
ARCHITECTURES = %w[monolith micro].freeze
|
|
15
|
+
private_constant :ARCHITECTURES
|
|
16
|
+
|
|
17
|
+
DEFAULT_ARCHITECTURE = ARCHITECTURES.first
|
|
18
|
+
private_constant :DEFAULT_ARCHITECTURE
|
|
19
|
+
|
|
20
|
+
DEFAULT_SLICE_NAME = "main"
|
|
21
|
+
private_constant :DEFAULT_SLICE_NAME
|
|
22
|
+
|
|
23
|
+
DEFAULT_SLICE_URL_PREFIX = "/"
|
|
24
|
+
private_constant :DEFAULT_SLICE_URL_PREFIX
|
|
25
|
+
|
|
26
|
+
argument :app, required: true, desc: "The application name"
|
|
27
|
+
|
|
28
|
+
option :architecture, alias: "arch", default: DEFAULT_ARCHITECTURE,
|
|
29
|
+
values: ARCHITECTURES, desc: "The architecture"
|
|
30
|
+
|
|
31
|
+
option :slice, default: DEFAULT_SLICE_NAME, desc: %(The initial slice name, only for "monolith" architecture)
|
|
32
|
+
option :slice_url_prefix, default: DEFAULT_SLICE_URL_PREFIX,
|
|
33
|
+
desc: %(The initial slice URL prefix, only for "monolith" architecture)
|
|
34
|
+
|
|
35
|
+
def initialize(fs: Dry::Files.new, bundler: CLI::Bundler.new(fs: fs),
|
|
36
|
+
command_line: CLI::CommandLine.new(bundler: bundler), **other)
|
|
37
|
+
@bundler = bundler
|
|
38
|
+
@command_line = command_line
|
|
39
|
+
super(fs: fs, **other)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def call(app:, architecture: DEFAULT_ARCHITECTURE, slice: DEFAULT_SLICE_NAME,
|
|
43
|
+
slice_url_prefix: DEFAULT_SLICE_URL_PREFIX, **)
|
|
44
|
+
app = inflector.underscore(app)
|
|
45
|
+
|
|
46
|
+
fs.mkdir(app)
|
|
47
|
+
fs.chdir(app) do
|
|
48
|
+
generator(architecture).call(app, slice, slice_url_prefix) do
|
|
49
|
+
bundler.install!
|
|
50
|
+
run_install_commmand!
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
private
|
|
56
|
+
|
|
57
|
+
attr_reader :bundler
|
|
58
|
+
attr_reader :command_line
|
|
59
|
+
|
|
60
|
+
def generator(architecture)
|
|
61
|
+
unless ARCHITECTURES.include?(architecture)
|
|
62
|
+
raise ArgumentError.new("unknown architecture `#{architecture}'")
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
Generators::Gem::Application[architecture, fs, inflector, command_line]
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def run_install_commmand!
|
|
69
|
+
command_line.call("hanami install").tap do |result|
|
|
70
|
+
raise "hanami install failed\n\n\n#{result.err.inspect}" unless result.successful?
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "hanami/cli/command"
|
|
4
|
+
|
|
5
|
+
module Hanami
|
|
6
|
+
module CLI
|
|
7
|
+
module Commands
|
|
8
|
+
module Gem
|
|
9
|
+
class Version < Command
|
|
10
|
+
def call(*)
|
|
11
|
+
require "hanami/version"
|
|
12
|
+
out.puts "v#{Hanami::VERSION}"
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Hanami
|
|
4
|
+
module CLI
|
|
5
|
+
module Commands
|
|
6
|
+
module Gem
|
|
7
|
+
require_relative "gem/version"
|
|
8
|
+
# FIXME: temporary disabled for Hanami v2.0.0.alpha2
|
|
9
|
+
# require_relative "gem/new"
|
|
10
|
+
|
|
11
|
+
def self.extended(base)
|
|
12
|
+
base.module_eval do
|
|
13
|
+
register "version", Version, aliases: ["v", "-v", "--version"]
|
|
14
|
+
# FIXME: temporary disabled for Hanami v2.0.0.alpha2
|
|
15
|
+
# register "new", New
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "hanami/console/context"
|
|
4
|
+
|
|
5
|
+
require_relative "../application"
|
|
6
|
+
|
|
7
|
+
module Hanami
|
|
8
|
+
module CLI
|
|
9
|
+
module Commands
|
|
10
|
+
module Monolith
|
|
11
|
+
# @api public
|
|
12
|
+
class Console < Application
|
|
13
|
+
REPLS = {
|
|
14
|
+
"pry" => -> *args {
|
|
15
|
+
begin
|
|
16
|
+
require "hanami/cli/repl/pry"
|
|
17
|
+
Repl::Pry.new(*args)
|
|
18
|
+
rescue LoadError; end
|
|
19
|
+
},
|
|
20
|
+
"irb" => -> *args {
|
|
21
|
+
require "hanami/cli/repl/irb"
|
|
22
|
+
Repl::Irb.new(*args)
|
|
23
|
+
},
|
|
24
|
+
}.freeze
|
|
25
|
+
|
|
26
|
+
desc "Application REPL"
|
|
27
|
+
|
|
28
|
+
option :repl, required: false, desc: "REPL gem that should be used"
|
|
29
|
+
|
|
30
|
+
# @api private
|
|
31
|
+
def call(repl: nil, **opts)
|
|
32
|
+
engine = resolve_engine(repl, opts)
|
|
33
|
+
engine.start
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
# @api private
|
|
39
|
+
def resolve_engine(repl, opts)
|
|
40
|
+
if repl
|
|
41
|
+
REPLS.fetch(repl).(application, opts)
|
|
42
|
+
else
|
|
43
|
+
REPLS.map { |(_, loader)| loader.(application, opts) }.compact.first
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../../application"
|
|
4
|
+
|
|
5
|
+
module Hanami
|
|
6
|
+
module CLI
|
|
7
|
+
module Commands
|
|
8
|
+
module Monolith
|
|
9
|
+
module DB
|
|
10
|
+
class Create < Application
|
|
11
|
+
desc "Create database"
|
|
12
|
+
|
|
13
|
+
def call(**)
|
|
14
|
+
if database.create_command
|
|
15
|
+
out.puts "=> database #{database.name} created"
|
|
16
|
+
else
|
|
17
|
+
out.puts "=> failed to create database #{database.name}"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../../application"
|
|
4
|
+
require_relative "structure/dump"
|
|
5
|
+
|
|
6
|
+
module Hanami
|
|
7
|
+
module CLI
|
|
8
|
+
module Commands
|
|
9
|
+
module Monolith
|
|
10
|
+
module DB
|
|
11
|
+
class CreateMigration < Application
|
|
12
|
+
desc "Create new migration file"
|
|
13
|
+
|
|
14
|
+
argument :name, desc: "Migration file name"
|
|
15
|
+
|
|
16
|
+
def call(name:, **)
|
|
17
|
+
migrator = database.migrator
|
|
18
|
+
version = migrator.generate_version
|
|
19
|
+
|
|
20
|
+
measure "migration #{version}_#{name} created" do
|
|
21
|
+
migrator.create_file(name, version)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../../application"
|
|
4
|
+
|
|
5
|
+
module Hanami
|
|
6
|
+
module CLI
|
|
7
|
+
module Commands
|
|
8
|
+
module Monolith
|
|
9
|
+
module DB
|
|
10
|
+
class Drop < Application
|
|
11
|
+
desc "Delete database"
|
|
12
|
+
|
|
13
|
+
def call(**)
|
|
14
|
+
if database.drop_command
|
|
15
|
+
out.puts "=> database #{database.name} dropped"
|
|
16
|
+
else
|
|
17
|
+
out.puts "=> failed to drop #{database.name}"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../../application"
|
|
4
|
+
require_relative "structure/dump"
|
|
5
|
+
|
|
6
|
+
module Hanami
|
|
7
|
+
module CLI
|
|
8
|
+
module Commands
|
|
9
|
+
module Monolith
|
|
10
|
+
module DB
|
|
11
|
+
class Migrate < Application
|
|
12
|
+
desc "Migrates database"
|
|
13
|
+
|
|
14
|
+
option :target, desc: "Target migration number", aliases: ["-t"]
|
|
15
|
+
|
|
16
|
+
def call(target: nil, **)
|
|
17
|
+
return true if Dir[File.join(application.root, "db/migrate/*.rb")].empty?
|
|
18
|
+
|
|
19
|
+
measure "database #{database.name} migrated" do
|
|
20
|
+
if target
|
|
21
|
+
run_migrations(target: Integer(target))
|
|
22
|
+
else
|
|
23
|
+
run_migrations
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
true
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
def run_migrations(**options)
|
|
33
|
+
database.run_migrations(**options)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../../application"
|
|
4
|
+
require_relative "create"
|
|
5
|
+
require_relative "drop"
|
|
6
|
+
require_relative "migrate"
|
|
7
|
+
|
|
8
|
+
module Hanami
|
|
9
|
+
module CLI
|
|
10
|
+
module Commands
|
|
11
|
+
module Monolith
|
|
12
|
+
module DB
|
|
13
|
+
class Reset < Application
|
|
14
|
+
desc "Drop, create, and migrate database"
|
|
15
|
+
|
|
16
|
+
def call(**)
|
|
17
|
+
run_command Drop
|
|
18
|
+
run_command Create
|
|
19
|
+
run_command Migrate
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../../application"
|
|
4
|
+
require_relative "structure/dump"
|
|
5
|
+
|
|
6
|
+
module Hanami
|
|
7
|
+
module CLI
|
|
8
|
+
module Commands
|
|
9
|
+
module Monolith
|
|
10
|
+
module DB
|
|
11
|
+
class Rollback < Application
|
|
12
|
+
desc "Rollback database to a previous migration"
|
|
13
|
+
|
|
14
|
+
option :target, desc: "Target migration number", aliases: ["-t"]
|
|
15
|
+
option :dump, desc: "Dump structure after rolling back"
|
|
16
|
+
|
|
17
|
+
def call(target: nil, dump: true, **)
|
|
18
|
+
migration_code, migration_name = find_migration(target)
|
|
19
|
+
|
|
20
|
+
if migration_name.nil?
|
|
21
|
+
out.puts "==> migration file for target #{target} was not found"
|
|
22
|
+
return
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
measure "database #{database.name} rolled back to #{migration_name}" do
|
|
26
|
+
database.run_migrations(target: Integer(migration_code))
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
run_command Structure::Dump if dump
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
def find_migration(code)
|
|
35
|
+
migration = database.applied_migrations.yield_self { |migrations|
|
|
36
|
+
if code
|
|
37
|
+
migrations.detect { |m| m.split("_").first == code }
|
|
38
|
+
else
|
|
39
|
+
migrations.last
|
|
40
|
+
end
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return unless migration
|
|
44
|
+
|
|
45
|
+
migration_code = code || migration.split("_").first
|
|
46
|
+
migration_name = File.basename(migration, ".*")
|
|
47
|
+
|
|
48
|
+
[migration_code, migration_name]
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../../application"
|
|
4
|
+
require_relative "structure/dump"
|
|
5
|
+
|
|
6
|
+
module Hanami
|
|
7
|
+
module CLI
|
|
8
|
+
module Commands
|
|
9
|
+
module Monolith
|
|
10
|
+
module DB
|
|
11
|
+
class SampleData < Application
|
|
12
|
+
FILE_PATH = "db/sample_data.rb"
|
|
13
|
+
|
|
14
|
+
desc "Load sample data"
|
|
15
|
+
|
|
16
|
+
def call(**)
|
|
17
|
+
if has_file?
|
|
18
|
+
measure "sample data loaded from #{FILE_PATH}" do
|
|
19
|
+
load full_file_path
|
|
20
|
+
end
|
|
21
|
+
else
|
|
22
|
+
out.puts "=> #{FILE_PATH} not found"
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def full_file_path
|
|
29
|
+
File.join(application.root, FILE_PATH)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def has_file?
|
|
33
|
+
File.exist?(full_file_path)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|