Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor RubyFileWriter #222

Merged
merged 12 commits into from
Sep 10, 2024
15 changes: 13 additions & 2 deletions lib/hanami/cli/commands/app/generate/command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,19 @@ def generator_class
# @since 2.2.0
# @api private
def call(name:, slice: nil, **)
normalized_slice = inflector.underscore(slice) if slice
generator.call(app.namespace, name, normalized_slice)
if slice
generator.call(
key: name,
namespace: slice,
base_path: fs.join("slices", inflector.underscore(slice))
)
else
generator.call(
key: name,
namespace: app.namespace,
base_path: "app"
)
end
end
end
end
Expand Down
6 changes: 0 additions & 6 deletions lib/hanami/cli/commands/app/generate/relation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,6 @@ class Relation < Command
def generator_class
Generators::App::Relation
end

# @since 2.2.0
# @api private
def call(name:, slice: nil, **opts)
super(name: name, slice: slice, **opts)
end
end
end
end
Expand Down
10 changes: 3 additions & 7 deletions lib/hanami/cli/commands/app/generate/repo.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,9 @@ def generator_class

# @since 2.2.0
# @api private
def call(name:, slice: nil, **opts)
normalized_name = if name.end_with?("_repo")
name
else
"#{inflector.singularize(name)}_repo"
end
super(name: normalized_name, slice: slice, **opts)
def call(name:, **opts)
name = "#{inflector.singularize(name)}_repo" unless name.end_with?("_repo")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just checking: by reassigning name here, that new value will still be passed up to the superclass method via the no-args version of super below?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup! Which I wasn't expecting. I wrote it explicitly as super(name: name, **opts), but my Rubocop autocorrect got rid of it since it's equivalent to super.

super
end
end
end
Expand Down
16 changes: 6 additions & 10 deletions lib/hanami/cli/generators/app/migration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,13 @@ def initialize(fs:, inflector:, out: $stdout)

# @since 2.2.0
# @api private
def call(_app_namespace, name, slice, **_opts)
normalized_name = inflector.underscore(name)
ensure_valid_name(normalized_name)
def call(namespace:, key:, base_path:, **_opts)
_namespace = namespace
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the reason for this extra assignment? It doesn't look like we use _namespace anywhere?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, it was to appease Rubocop, but clearly the better move is to just remove the namespace: arg altogether, which is what I just committed.

name = inflector.underscore(key)
ensure_valid_name(name)

base = if slice
fs.join("slices", slice, "config", "db", "migrate")
else
fs.join("config", "db", "migrate")
end

path = fs.join(base, file_name(normalized_name))
base_path = "" if base_path == "app" # Migrations are in root dir, not app/
path = fs.join(base_path, "config", "db", "migrate", file_name(name))

fs.write(path, FILE_CONTENTS)
end
Expand Down
9 changes: 5 additions & 4 deletions lib/hanami/cli/generators/app/operation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,17 @@ def initialize(fs:, inflector:, out: $stdout)

# @since 2.2.0
# @api private
def call(app_namespace, key, slice)
def call(key:, namespace:, base_path:)
RubyFileWriter.new(
fs: fs,
inflector: inflector,
app_namespace: app_namespace,
).call(
namespace: namespace,
base_path: base_path,
key: key,
slice: slice,
relative_parent_class: "Operation",
body: ["def call", "end"],
).call
)

unless key.match?(KEY_SEPARATOR)
out.puts(
Expand Down
9 changes: 5 additions & 4 deletions lib/hanami/cli/generators/app/relation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,20 @@ def initialize(fs:, inflector:, out: $stdout)

# @since 2.2.0
# @api private
def call(app_namespace, key, slice)
def call(key:, namespace:, base_path:)
schema_name = key.split(KEY_SEPARATOR).last

RubyFileWriter.new(
fs: fs,
inflector: inflector,
app_namespace: app_namespace,
).call(
namespace: namespace,
key: key,
slice: slice,
base_path: base_path,
extra_namespace: "Relations",
relative_parent_class: "DB::Relation",
body: ["schema :#{schema_name}, infer: true"],
).call
)
end

private
Expand Down
9 changes: 5 additions & 4 deletions lib/hanami/cli/generators/app/repo.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,18 @@ def initialize(fs:, inflector:, out: $stdout)

# @since 2.2.0
# @api private
def call(app_namespace, key, slice)
def call(key:, namespace:, base_path:)
RubyFileWriter.new(
fs: fs,
inflector: inflector,
app_namespace: app_namespace,
).call(
key: key,
slice: slice,
namespace: namespace,
base_path: base_path,
extra_namespace: "Repos",
relative_parent_class: "DB::Repo",
body: [],
).call
)
end

private
Expand Down
76 changes: 39 additions & 37 deletions lib/hanami/cli/generators/app/ruby_file_writer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,31 +14,55 @@ module App
class RubyFileWriter
# @since 2.2.0
# @api private
def initialize(fs:, inflector:)
@fs = fs
@inflector = inflector
end

# @since 2.2.0
# @api private
def call(key:, namespace:, base_path:, relative_parent_class:, extra_namespace: nil, body: [])
ClassFile.new(
fs: fs,
inflector: inflector,
key: key,
namespace: namespace,
base_path: base_path,
relative_parent_class: relative_parent_class,
extra_namespace: extra_namespace,
body: body,
).write
end

private

# @since 2.2.0
# @api private
attr_reader :fs, :inflector
end

class ClassFile
def initialize(
fs:,
inflector:,
app_namespace:,
key:,
slice:,
namespace:,
base_path:,
relative_parent_class:,
extra_namespace: nil,
body: []
)
@fs = fs
@inflector = inflector
@app_namespace = app_namespace
@key = key
@slice = slice
@namespace = namespace
@base_path = base_path
@extra_namespace = extra_namespace&.downcase
@relative_parent_class = relative_parent_class
@body = body
raise_missing_slice_error_if_missing(slice) if slice
end

# @since 2.2.0
# @api private
def call
fs.mkdir(directory)
def write
fs.write(path, file_contents)
end

Expand All @@ -49,9 +73,9 @@ def call
attr_reader(
:fs,
:inflector,
:app_namespace,
:key,
:slice,
:namespace,
:base_path,
:extra_namespace,
:relative_parent_class,
:body,
Expand All @@ -62,7 +86,6 @@ def call
def file_contents
class_definition(
class_name: class_name,
container_namespace: container_namespace,
local_namespaces: local_namespaces,
)
end
Expand All @@ -73,12 +96,6 @@ def class_name
key.split(KEY_SEPARATOR)[-1]
end

# @since 2.2.0
# @api private
def container_namespace
slice || app_namespace
end

# @since 2.2.0
# @api private
def local_namespaces
Expand All @@ -88,16 +105,10 @@ def local_namespaces
# @since 2.2.0
# @api private
def directory
base = if slice
fs.join("slices", slice)
else
fs.join("app")
end

@directory ||= if local_namespaces.any?
fs.join(base, local_namespaces)
fs.join(base_path, local_namespaces)
else
fs.join(base)
base_path
end
end

Expand All @@ -109,8 +120,8 @@ def path

# @since 2.2.0
# @api private
def class_definition(class_name:, container_namespace:, local_namespaces:)
container_module = normalize(container_namespace)
def class_definition(class_name:, local_namespaces:)
container_module = normalize(namespace)

modules = local_namespaces
.map { normalize(_1) }
Expand All @@ -133,15 +144,6 @@ def class_definition(class_name:, container_namespace:, local_namespaces:)
def normalize(name)
inflector.camelize(name).gsub(/[^\p{Alnum}]/, "")
end

# @since 2.2.0
# @api private
def raise_missing_slice_error_if_missing(slice)
if slice
slice_directory = fs.join("slices", slice)
raise MissingSliceError.new(slice) unless fs.directory?(slice_directory)
end
end
end
end
end
Expand Down
9 changes: 5 additions & 4 deletions lib/hanami/cli/generators/app/struct.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,17 @@ def initialize(fs:, inflector:, out: $stdout)

# @since 2.2.0
# @api private
def call(app_namespace, key, slice)
def call(key:, namespace:, base_path:)
RubyFileWriter.new(
fs: fs,
inflector: inflector,
app_namespace: app_namespace,
).call(
key: key,
slice: slice,
namespace: namespace,
base_path: base_path,
extra_namespace: "Structs",
relative_parent_class: "DB::Struct",
).call
)
end

private
Expand Down