Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Break Versioning](https://www.taoensso.com/break-ve

- Add `hanami new --skip-git` to generate an app without initializing a git repository or generating a `.gitignore`. (@aaronmallen #441)
- Proper support for MariaDB (@katafrakt in #458)
- Generate the app or slice base struct class (`db/struct.rb`) in `hanami generate struct` when it does not exist yet, as `hanami generate part` does for the base part. (@anyingiit in #465)

### Changed

Expand Down
30 changes: 30 additions & 0 deletions lib/hanami/cli/generators/app/struct.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ def initialize(fs:, inflector:, stdout: $stdout)
# @since 2.2.0
# @api private
def call(key:, namespace:, base_path:, force: false)
create_app_base_struct_if_missing
create_slice_base_struct_if_missing(namespace:, base_path:) unless namespace == Hanami.app.namespace

RubyClassFile.new(
fs: fs,
inflector: inflector,
Expand All @@ -32,6 +35,33 @@ def call(key:, namespace:, base_path:, force: false)
private

attr_reader :fs, :inflector, :stdout

def create_app_base_struct_if_missing
return if fs.exist?(fs.join(APP_DIR, "db", "struct.rb"))

RubyClassFile.new(
fs: fs,
inflector: inflector,
namespace: Hanami.app.namespace,
key: "db.struct",
base_path: APP_DIR,
parent_class_name: "Hanami::DB::Struct",
requires: ["hanami/db/struct"]
).create
end

def create_slice_base_struct_if_missing(namespace:, base_path:)
return if fs.exist?(fs.join(base_path, "db", "struct.rb"))

RubyClassFile.new(
fs: fs,
inflector: inflector,
namespace: namespace,
key: "db.struct",
base_path: base_path,
parent_class_name: "#{Hanami.app.namespace}::DB::Struct"
).create
end
end
end
end
Expand Down
78 changes: 78 additions & 0 deletions spec/unit/hanami/cli/commands/app/generate/struct_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,43 @@ class Hardcover < Test::DB::Struct
expect(output).to include("Created app/structs/book/published/hardcover.rb")
end

context "without base struct" do
it "generates the app base struct" do
subject.call(name: "book")

base_struct = <<~EXPECTED
# frozen_string_literal: true

require "hanami/db/struct"

module Test
module DB
class Struct < Hanami::DB::Struct
end
end
end
EXPECTED

expect(fs.read("app/db/struct.rb")).to eq(base_struct)
expect(output).to include("Created app/db/struct.rb")
end
end

context "with base struct" do
before do
fs.write("app/db/struct.rb", "existing base struct")
stdout.truncate 0
end

it "does not overwrite the app base struct" do
subject.call(name: "book")

expect(fs.read("app/db/struct.rb")).to eq("existing base struct")
expect(output).not_to include("Created app/db/struct.rb")
expect(fs.exist?("app/structs/book.rb")).to be(true)
end
end

context "with existing file" do
let(:file_path) { "app/structs/book/published/hardcover.rb" }

Expand Down Expand Up @@ -127,6 +164,47 @@ class DraftBook < Main::DB::Struct
expect(output).to include("Created slices/main/structs/book/draft_book.rb")
end

context "without base structs" do
it "generates the app and slice base structs" do
fs.mkdir("slices/main")
subject.call(name: "book", slice: "main")

slice_base_struct = <<~EXPECTED
# frozen_string_literal: true

module Main
module DB
class Struct < Test::DB::Struct
end
end
end
EXPECTED

expect(fs.read("slices/main/db/struct.rb")).to eq(slice_base_struct)
expect(output).to include("Created slices/main/db/struct.rb")
expect(fs.exist?("app/db/struct.rb")).to be(true)
expect(output).to include("Created app/db/struct.rb")
end
end

context "with base structs" do
before do
fs.write("app/db/struct.rb", "existing app base struct")
fs.write("slices/main/db/struct.rb", "existing slice base struct")
stdout.truncate 0
end

it "does not overwrite the base structs" do
subject.call(name: "book", slice: "main")

expect(fs.read("app/db/struct.rb")).to eq("existing app base struct")
expect(fs.read("slices/main/db/struct.rb")).to eq("existing slice base struct")
expect(output).not_to include("Created app/db/struct.rb")
expect(output).not_to include("Created slices/main/db/struct.rb")
expect(fs.exist?("slices/main/structs/book.rb")).to be(true)
end
end

context "with existing file" do
let(:file_path) { "slices/main/structs/book/draft_book.rb" }

Expand Down