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.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +42 -0
  3. data/.gitignore +4 -2
  4. data/.rspec +1 -0
  5. data/.rubocop.yml +25 -1
  6. data/CHANGELOG.md +30 -1
  7. data/CODE_OF_CONDUCT.md +84 -0
  8. data/Gemfile +13 -6
  9. data/LICENSE.txt +21 -0
  10. data/README.md +12 -605
  11. data/Rakefile +9 -12
  12. data/bin/console +1 -0
  13. data/exe/hanami +10 -0
  14. data/hanami-cli.gemspec +25 -18
  15. data/lib/hanami/cli/bundler.rb +73 -0
  16. data/lib/hanami/cli/command.rb +16 -355
  17. data/lib/hanami/cli/command_line.rb +17 -0
  18. data/lib/hanami/cli/commands/application.rb +63 -0
  19. data/lib/hanami/cli/commands/db/utils/database.rb +122 -0
  20. data/lib/hanami/cli/commands/db/utils/database_config.rb +48 -0
  21. data/lib/hanami/cli/commands/db/utils/mysql.rb +27 -0
  22. data/lib/hanami/cli/commands/db/utils/postgres.rb +49 -0
  23. data/lib/hanami/cli/commands/db/utils/sqlite.rb +37 -0
  24. data/lib/hanami/cli/commands/gem/new.rb +77 -0
  25. data/lib/hanami/cli/commands/gem/version.rb +18 -0
  26. data/lib/hanami/cli/commands/gem.rb +21 -0
  27. data/lib/hanami/cli/commands/monolith/console.rb +50 -0
  28. data/lib/hanami/cli/commands/monolith/db/create.rb +25 -0
  29. data/lib/hanami/cli/commands/monolith/db/create_migration.rb +29 -0
  30. data/lib/hanami/cli/commands/monolith/db/drop.rb +25 -0
  31. data/lib/hanami/cli/commands/monolith/db/migrate.rb +40 -0
  32. data/lib/hanami/cli/commands/monolith/db/reset.rb +26 -0
  33. data/lib/hanami/cli/commands/monolith/db/rollback.rb +55 -0
  34. data/lib/hanami/cli/commands/monolith/db/sample_data.rb +40 -0
  35. data/lib/hanami/cli/commands/monolith/db/seed.rb +40 -0
  36. data/lib/hanami/cli/commands/monolith/db/setup.rb +24 -0
  37. data/lib/hanami/cli/commands/monolith/db/structure/dump.rb +25 -0
  38. data/lib/hanami/cli/commands/monolith/db/version.rb +26 -0
  39. data/lib/hanami/cli/commands/monolith/generate/action.rb +62 -0
  40. data/lib/hanami/cli/commands/monolith/generate/slice.rb +62 -0
  41. data/lib/hanami/cli/commands/monolith/generate.rb +14 -0
  42. data/lib/hanami/cli/commands/monolith/install.rb +16 -0
  43. data/lib/hanami/cli/commands/monolith/version.rb +18 -0
  44. data/lib/hanami/cli/commands/monolith.rb +55 -0
  45. data/lib/hanami/cli/commands.rb +26 -0
  46. data/lib/hanami/cli/error.rb +8 -0
  47. data/lib/hanami/cli/generators/context.rb +38 -0
  48. data/lib/hanami/cli/generators/gem/application/monolith/action.erb +21 -0
  49. data/lib/hanami/cli/generators/gem/application/monolith/application.erb +8 -0
  50. data/lib/hanami/cli/generators/gem/application/monolith/config_ru.erb +5 -0
  51. data/lib/hanami/cli/generators/gem/application/monolith/entities.erb +9 -0
  52. data/lib/hanami/cli/generators/gem/application/monolith/env.erb +0 -0
  53. data/lib/hanami/cli/generators/gem/application/monolith/functions.erb +13 -0
  54. data/lib/hanami/cli/generators/gem/application/monolith/gemfile.erb +19 -0
  55. data/lib/hanami/cli/generators/gem/application/monolith/keep.erb +0 -0
  56. data/lib/hanami/cli/generators/gem/application/monolith/operation.erb +18 -0
  57. data/lib/hanami/cli/generators/gem/application/monolith/rakefile.erb +3 -0
  58. data/lib/hanami/cli/generators/gem/application/monolith/readme.erb +1 -0
  59. data/lib/hanami/cli/generators/gem/application/monolith/repository.erb +13 -0
  60. data/lib/hanami/cli/generators/gem/application/monolith/routes.erb +4 -0
  61. data/lib/hanami/cli/generators/gem/application/monolith/settings.erb +6 -0
  62. data/lib/hanami/cli/generators/gem/application/monolith/types.erb +10 -0
  63. data/lib/hanami/cli/generators/gem/application/monolith/validation_contract.erb +14 -0
  64. data/lib/hanami/cli/generators/gem/application/monolith/view_context.erb +15 -0
  65. data/lib/hanami/cli/generators/gem/application/monolith.rb +83 -0
  66. data/lib/hanami/cli/generators/gem/application.rb +21 -0
  67. data/lib/hanami/cli/generators/monolith/action/action.erb +13 -0
  68. data/lib/hanami/cli/generators/monolith/action/template.erb +0 -0
  69. data/lib/hanami/cli/generators/monolith/action/template.html.erb +2 -0
  70. data/lib/hanami/cli/generators/monolith/action/view.erb +13 -0
  71. data/lib/hanami/cli/generators/monolith/action.rb +123 -0
  72. data/lib/hanami/cli/generators/monolith/action_context.rb +76 -0
  73. data/lib/hanami/cli/generators/monolith/slice/action.erb +9 -0
  74. data/lib/hanami/cli/generators/monolith/slice/entities.erb +9 -0
  75. data/lib/hanami/cli/generators/monolith/slice/keep.erb +0 -0
  76. data/lib/hanami/cli/generators/monolith/slice/repository.erb +10 -0
  77. data/lib/hanami/cli/generators/monolith/slice/routes.erb +2 -0
  78. data/lib/hanami/cli/generators/monolith/slice/view.erb +9 -0
  79. data/lib/hanami/cli/generators/monolith/slice.rb +56 -0
  80. data/lib/hanami/cli/generators/monolith/slice_context.rb +33 -0
  81. data/lib/hanami/cli/repl/core.rb +55 -0
  82. data/lib/hanami/cli/repl/irb.rb +41 -0
  83. data/lib/hanami/cli/repl/pry.rb +29 -0
  84. data/lib/hanami/cli/system_call.rb +51 -0
  85. data/lib/hanami/cli/url.rb +34 -0
  86. data/lib/hanami/cli/version.rb +4 -3
  87. data/lib/hanami/cli.rb +10 -121
  88. data/lib/hanami/console/context.rb +39 -0
  89. data/lib/hanami/console/plugins/slice_readers.rb +42 -0
  90. data/lib/hanami/rake_tasks.rb +52 -0
  91. metadata +138 -42
  92. data/.circleci/config.yml +0 -141
  93. data/.travis.yml +0 -26
  94. data/lib/hanami/cli/banner.rb +0 -127
  95. data/lib/hanami/cli/command_registry.rb +0 -213
  96. data/lib/hanami/cli/errors.rb +0 -44
  97. data/lib/hanami/cli/option.rb +0 -132
  98. data/lib/hanami/cli/parser.rb +0 -142
  99. data/lib/hanami/cli/program_name.rb +0 -19
  100. data/lib/hanami/cli/registry.rb +0 -328
  101. data/lib/hanami/cli/usage.rb +0 -89
  102. 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