Skip to content

Commit

Permalink
Replacing Teeplate with LuckyTemplate (#1028)
Browse files Browse the repository at this point in the history
* Move the template files for LuckyTemplate format

* No need to override LuckyTask now

* Refactor Lucky extension tasks so they use LuckyTemplate instead of Teeplate. Fixes #1026

* I need LuckyTemplate required until I can set the dep to Lucky 1.2
  • Loading branch information
jwoertink authored Apr 21, 2024
1 parent db6ef66 commit 556ed3d
Show file tree
Hide file tree
Showing 34 changed files with 223 additions and 186 deletions.
5 changes: 1 addition & 4 deletions shard.override.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
dependencies:
lucky_task:
github: luckyframework/lucky_task
version: ~> 0.3.0
# dependencies:
development_dependencies:
lucky:
github: luckyframework/lucky
Expand Down
3 changes: 3 additions & 0 deletions shard.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ dependencies:
cadmium_transliterator:
github: cadmiumcr/transliterator
branch: master
lucky_template:
github: luckyframework/lucky_template
version: ~> 0.1.0

development_dependencies:
ameba:
Expand Down
61 changes: 29 additions & 32 deletions spec/avram/migrator/gen/migration_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -5,48 +5,45 @@ include CleanupHelper
describe "Generating migrations" do
it "can generate a migration with custom name" do
with_cleanup do
Gen::Migration.silence_output do
ARGV.push("Should Ignore This Name")
task = Gen::Migration.new
task.output = IO::Memory.new
task.print_help_or_call(args: ["Custom"])

Gen::Migration.new.call("Custom")

should_generate_migration named: "custom.cr"
end
should_generate_migration named: "custom.cr"
end
end

it "can generate a migration with custom name and contents" do
with_cleanup do
Gen::Migration.silence_output do
migrate_contents = <<-CONTENTS
create :users do
add name : String
end
CONTENTS
rollback_contents = <<-CONTENTS
drop :users
CONTENTS

Avram::Migrator::MigrationGenerator.new(
"CreateUsers",
migrate_contents: migrate_contents,
rollback_contents: rollback_contents
).generate(_version: "123")

File.read("./db/migrations/123_create_users.cr").should contain <<-MIGRATION
class CreateUsers::V123 < Avram::Migrator::Migration::V1
def migrate
create :users do
add name : String
end
migrate_contents = <<-CONTENTS
create :users do
add name : String
end
CONTENTS
rollback_contents = <<-CONTENTS
drop :users
CONTENTS

Avram::Migrator::MigrationGenerator.new(
"CreateUsers",
io: IO::Memory.new,
migrate_contents: migrate_contents,
rollback_contents: rollback_contents
).generate(_version: "123")

File.read("./db/migrations/123_create_users.cr").should contain <<-MIGRATION
class CreateUsers::V123 < Avram::Migrator::Migration::V1
def migrate
create :users do
add name : String
end
end
def rollback
drop :users
end
def rollback
drop :users
end
MIGRATION
end
MIGRATION
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion spec/avram/tasks/db_schema_dump_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ include CleanupHelper
describe Db::Schema::Dump do
it "generates a new sql dump file" do
with_cleanup do
Db::Schema::Dump.new.print_help_or_call(args: ["structure.sql"])
Db::Schema::Dump.new(quiet: true).print_help_or_call(args: ["structure.sql"])

filename = "structure.sql"
File.exists?(filename).should eq true
Expand Down
6 changes: 3 additions & 3 deletions spec/avram/tasks/db_schema_restore_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,19 @@ SQL_DUMP_FILE = "spec/support/files/sample_backup.sql"
describe Db::Schema::Restore do
it "raises an error when no import file is supplied" do
expect_raises(Exception, "A path to the import SQL file must be provided") do
Db::Schema::Restore.new.run_task
Db::Schema::Restore.new(quiet: true).run_task
end
end

it "raises an error when unable to find the import file" do
expect_raises(Exception, "Unable to locate the restore file: missing_file.sql") do
Db::Schema::Restore.new("missing_file.sql").run_task
Db::Schema::Restore.new("missing_file.sql", quiet: true).run_task
end
end

it "restores from the sample_backup file" do
swap_database_with_cleanup(SampleBackupDatabase) do
Db::Schema::Restore.new(SQL_DUMP_FILE).run_task
Db::Schema::Restore.new(SQL_DUMP_FILE, quiet: true).run_task

SampleBackupDatabase.run do |db|
value = db.scalar("SELECT COUNT(*) FROM sample_records").as(Int64)
Expand Down
118 changes: 47 additions & 71 deletions spec/lucky/tasks/gen/model_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -6,53 +6,41 @@ include GeneratorHelper
describe Gen::Model do
it "generates a model" do
with_cleanup do
Gen::Migration.silence_output do
io = IO::Memory.new
model_name = "Customer"
ARGV.push(model_name)

Gen::Model.new.call(io)

should_create_files_with_contents io,
"./src/models/customer.cr": "table"
should_create_files_with_contents io,
"./src/operations/save_customer.cr": "# permit_columns column_1, column_2"
should_create_files_with_contents io,
"./src/models/customer.cr": "class Customer < BaseModel",
"./src/operations/save_customer.cr": "class SaveCustomer < Customer::SaveOperation",
"./src/operations/delete_customer.cr": "class DeleteCustomer < Customer::DeleteOperation",
"./src/queries/customer_query.cr": "class CustomerQuery < Customer::BaseQuery"
should_generate_migration named: "create_customers.cr"
end
io = generate Gen::Model, "Customer"

should_create_files_with_contents io,
"./src/models/customer.cr": "table"
should_create_files_with_contents io,
"./src/operations/save_customer.cr": "# permit_columns column_1, column_2"
should_create_files_with_contents io,
"./src/models/customer.cr": "class Customer < BaseModel",
"./src/operations/save_customer.cr": "class SaveCustomer < Customer::SaveOperation",
"./src/operations/delete_customer.cr": "class DeleteCustomer < Customer::DeleteOperation",
"./src/queries/customer_query.cr": "class CustomerQuery < Customer::BaseQuery"
should_generate_migration named: "create_customers.cr"
end
end

it "generates a model with columns" do
with_cleanup do
Gen::Migration.silence_output do
io = IO::Memory.new
model_name = "ContactInfo"
ARGV.push(model_name, "name:String", "notes:String?", "contacted_at:Time")

Gen::Model.new.call(io)

should_create_files_with_contents io,
"./src/models/contact_info.cr": "table"
should_create_files_with_contents io,
"./src/models/contact_info.cr": "column name : String",
"./src/operations/save_contact_info.cr": "# permit_columns name, notes, contacted_at"
should_create_files_with_contents io,
"./src/models/contact_info.cr": "column notes : String?"
should_create_files_with_contents io,
"./src/models/contact_info.cr": "class ContactInfo < BaseModel",
"./src/operations/save_contact_info.cr": "class SaveContactInfo < ContactInfo::SaveOperation",
"./src/operations/delete_contact_info.cr": "class DeleteContactInfo < ContactInfo::DeleteOperation",
"./src/queries/contact_info_query.cr": "class ContactInfoQuery < ContactInfo::BaseQuery"
should_generate_migration named: "create_contact_infos.cr",
with: "add notes : String?"
should_generate_migration named: "create_contact_infos.cr",
with: "add contacted_at : Time"
end
io = generate Gen::Model, "ContactInfo", "name:String", "notes:String?", "contacted_at:Time"

should_create_files_with_contents io,
"./src/models/contact_info.cr": "table"
should_create_files_with_contents io,
"./src/models/contact_info.cr": "column name : String",
"./src/operations/save_contact_info.cr": "# permit_columns name, notes, contacted_at"
should_create_files_with_contents io,
"./src/models/contact_info.cr": "column notes : String?"
should_create_files_with_contents io,
"./src/models/contact_info.cr": "class ContactInfo < BaseModel",
"./src/operations/save_contact_info.cr": "class SaveContactInfo < ContactInfo::SaveOperation",
"./src/operations/delete_contact_info.cr": "class DeleteContactInfo < ContactInfo::DeleteOperation",
"./src/queries/contact_info_query.cr": "class ContactInfoQuery < ContactInfo::BaseQuery"
should_generate_migration named: "create_contact_infos.cr",
with: "add notes : String?"
should_generate_migration named: "create_contact_infos.cr",
with: "add contacted_at : Time"
end
end

Expand All @@ -63,10 +51,8 @@ describe Gen::Model do
bad_text_column = "text_column:text"
good_string_column = "good_column:String"
good_optional_string_column = "good_optional_column:String?"
io = IO::Memory.new
ARGV.push("ModelName", bad_int_column, bad_text_column, good_string_column, good_optional_string_column)

Gen::Model.new.call(io)
io = generate Gen::Model, "ModelName", bad_int_column, bad_text_column, good_string_column, good_optional_string_column

io.to_s.should contain("Unable to generate model ModelName")
io.to_s.should contain("the following columns are using types not supported by the generator")
Expand All @@ -78,55 +64,45 @@ describe Gen::Model do
end

it "displays an error when given a more complex type" do
io = IO::Memory.new
ARGV.push("Alphabet", "a:BigDecimal")

Gen::Model.new.call(io)

io = generate Gen::Model, "Alphabet", "a:BigDecimal"
io.to_s.should contain("For more complex types that can be added to your migrations manually")
end
end

it "displays an error if given no arguments" do
io = IO::Memory.new

Gen::Model.new.call(io)

io = generate Gen::Model
io.to_s.should contain("Model name is required.")
end

it "displays an error if argument is not camelcase" do
with_cleanup do
io = IO::Memory.new
ARGV.push("invalid_name")

Gen::Model.new.call(io)

io = generate Gen::Model, "invalid_name"
io.to_s.should contain("Model name should be camel case")
end
end

it "displays an error if the name contains weird characters" do
with_cleanup do
io = IO::Memory.new
ARGV.push(":-)sillyame")
Gen::Model.new.call(io)
io = generate Gen::Model, ":-)sillyame"
io.to_s.should contain("Model name should only contain letters")
end
end

it "displays an error if the model has already been generated" do
with_cleanup do
ARGV.push("User")

Gen::Migration.silence_output do
io = IO::Memory.new
Gen::Model.new.call(io)
end

io = IO::Memory.new
Gen::Model.new.call(io)
generate Gen::Model, "User"
io = generate Gen::Model, "User"
io.to_s.should contain("'User' model already exists at ./src/models/user.cr")
end
end
end

private def generate(generator : Class, *options) : IO
task = generator.new
task.output = IO::Memory.new
# HACK: Some tasks are still using a legacy task format with ARGV
options.each { |opt| ARGV.push(opt) }
task.print_help_or_call(args: ARGV)
ARGV.clear
task.output
end
23 changes: 10 additions & 13 deletions spec/lucky/tasks/gen/resource_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,8 @@ describe Gen::Resource::Browser do
bad_text_column = "text_column:text"
good_string_column = "good_column:String"
good_optional_string_column = "good_optional_column:String?"
io = IO::Memory.new
ARGV.push("ModelName", bad_int_column, bad_text_column, good_string_column, good_optional_string_column)

Gen::Model.new.call(io)
io = generate(Gen::Model, "ModelName", bad_int_column, bad_text_column, good_string_column, good_optional_string_column)

io.to_s.should contain("Unable to generate model ModelName")
io.to_s.should contain("the following columns are using types not supported by the generator")
Expand All @@ -74,11 +72,7 @@ describe Gen::Resource::Browser do
end

it "displays an error when given a more complex type" do
io = IO::Memory.new
ARGV.push("Alphabet", "a:BigDecimal")

Gen::Model.new.call(io)

io = generate(Gen::Model, "Alphabet", "a:BigDecimal")
io.to_s.should contain("For more complex types that can be added to your migrations manually")
end
end
Expand Down Expand Up @@ -126,9 +120,12 @@ describe Gen::Resource::Browser do
end
end

private def generate(generator : Class, *options)
options.each { |option| ARGV.push(option) }
IO::Memory.new.tap do |io|
generator.new.call(io)
end
private def generate(generator : Class, *options) : IO
task = generator.new
task.output = IO::Memory.new
# HACK: Some tasks are still using a legacy task format with ARGV
options.each { |opt| ARGV.push(opt) }
task.print_help_or_call(args: ARGV)
ARGV.clear
task.output
end
3 changes: 2 additions & 1 deletion src/avram/migrator/runner.cr
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,9 @@ class Avram::Migrator::Runner

def self.restore_db(restore_file : String, quiet : Bool = false)
if File.exists?(restore_file)
output = quiet ? IO::Memory.new : STDOUT
File.open(restore_file) do |f|
run("psql", ["-q", *cmd_args_array, "-v", "ON_ERROR_STOP=1"], input: f)
run("psql", ["-q", *cmd_args_array, "-v", "ON_ERROR_STOP=1"], input: f, output: output)
end
unless quiet
puts "Done restoring #{db_name.colorize(:green)}"
Expand Down
11 changes: 4 additions & 7 deletions src/avram/tasks/gen/migration.cr
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ class Gen::Migration < LuckyTask::Task
TEXT

positional_arg :migration_name, "The migration class name", format: /^[A-Z]/

Habitat.create do
setting io : IO = STDOUT
end
Expand All @@ -25,14 +27,9 @@ class Gen::Migration < LuckyTask::Task
end
end

def call(name : String? = nil)
def call
Avram::Migrator.run do
name = name || ARGV.first?
if name
Avram::Migrator::MigrationGenerator.new(name: name).generate
else
raise "Migration name is required. Example: lucky gen.migration CreateUsers".colorize(:red).to_s
end
Avram::Migrator::MigrationGenerator.new(name: migration_name, io: output).generate
end
end
end
Loading

0 comments on commit 556ed3d

Please sign in to comment.