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

Add marten seed command #266

Merged
merged 2 commits into from
Sep 11, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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 docs/docs/development/management-commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ Available commands:
› play Start a Crystal playground server initialized for the current project.
› resetmigrations Reset an existing set of migrations into a single one.
› routes Display all the routes of the application.
› seed Populate the database by running the seed file.
› serve / s Start a development server that is automatically recompiled when source files change.
› version Show the Marten version.

Expand Down
10 changes: 10 additions & 0 deletions docs/docs/development/reference/management-commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,16 @@ marten resetmigrations foo # Resets the migrations of the "foo" application

Displays all the routes of the application.

## `seed`

**Usage:** `marten seed [options]`

Populate the database by running the seed file.

### Options

* `-f PATH, --file=PATH` - Specify a custom path to the seed file

## `serve`

**Usage:** `marten serve [options]`
Expand Down
1 change: 1 addition & 0 deletions spec/marten/cli/manage/command/new_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,7 @@ module Marten::CLI::Manage::Command::NewSpec
"src/templates/base.html",
".editorconfig",
".gitignore",
"seed.cr",
"manage.cr",
"shard.yml",
]
Expand Down
94 changes: 94 additions & 0 deletions spec/marten/cli/manage/command/seed_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
require "./spec_helper"

describe Marten::CLI::Manage::Command::Seed do
after_each do
File.delete("./seed.cr") if File.exists?("./seed.cr")
end

describe "#run" do
it "runs the default seed file when no custom path is provided" do
stdout = IO::Memory.new
stderr = IO::Memory.new

# Create a mock seed file to simulate seeding
message = "Seeding..."
File.write("./seed.cr", "puts \"#{message}\"")

command = Marten::CLI::Manage::Command::Seed.new(
options: [] of String,
stdout: stdout,
stderr: stderr
)

command.handle
output = stdout.rewind.gets_to_end

output.includes?("Running seed file at ./seed.cr").should be_true
output.includes?(message).should be_true
stderr.rewind.gets_to_end.empty?.should be_true
end

it "runs the seed file from a custom path when provided" do
stdout = IO::Memory.new
stderr = IO::Memory.new

custom_seed_path = "./custom_seed.cr"
message = "Custom seeding..."
File.write(custom_seed_path, "puts \"#{message}\"")

command = Marten::CLI::Manage::Command::Seed.new(
options: ["--file", custom_seed_path],
stdout: stdout,
stderr: stderr
)

command.handle

output = stdout.rewind.gets_to_end

File.delete(custom_seed_path) if File.exists?(custom_seed_path)

output.includes?("Running seed file at #{custom_seed_path}").should be_true
output.includes?(message).should be_true
stderr.rewind.gets_to_end.empty?.should be_true
end

it "generates a default seed file if none exists" do
stdout = IO::Memory.new
stderr = IO::Memory.new

command = Marten::CLI::Manage::Command::Seed.new(
options: [] of String,
stdout: stdout,
stderr: stderr
)

command.handle

stdout.rewind.gets_to_end.includes?("Seed file not found at ./seed.cr").should be_true
stdout.rewind.gets_to_end.includes?("Default seed file generated at ./seed.cr").should be_true

# Check that the file was generated
File.exists?("./seed.cr").should be_true
end

it "handles errors if the seed file fails to run" do
stdout = IO::Memory.new
stderr = IO::Memory.new

# Create a seed file with invalid content
File.write("./seed.cr", "invalid_crystal_code")

command = Marten::CLI::Manage::Command::Seed.new(
options: [] of String,
stdout: stdout,
stderr: stderr
)

command.handle

output = stderr.rewind.gets_to_end
output.includes?("Error:").should be_true
end
end
end
1 change: 1 addition & 0 deletions src/marten/cli/manage/command/new/templates.cr
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ module Marten
# Other files
files << {".editorconfig", editorconfig}
files << {".gitignore", gitignore}
files << {"seed.cr", ECR.render("#{__DIR__}/templates/app/src/app/seed.cr.ecr")}
treagod marked this conversation as resolved.
Show resolved Hide resolved
files << {"manage.cr", ECR.render("#{__DIR__}/templates/project/manage.cr.ecr")}
files << {"shard.yml", ECR.render("#{__DIR__}/templates/project/shard.yml.ecr")}
if context.edge
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
require "./src/project"
treagod marked this conversation as resolved.
Show resolved Hide resolved

# Setup the project.
Marten.setup

# Add your seeding logic here.
54 changes: 54 additions & 0 deletions src/marten/cli/manage/command/seed.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
module Marten
module CLI
class Manage
module Command
class Seed < Base
@seed_path : String = "./seed.cr"

help "Populate the database by running the seed file."

def setup
on_option_with_arg(
:f,
:file,
arg: "path",
description: "Specify a custom path to the seed file"
) do |v|
@seed_path = v
end
end

def run
run_seed_file
end

private SEED_SOURCE_CONTENT = ECR.render("#{__DIR__}/new/templates/app/src/app/seed.cr.ecr")

private getter seed_path

private def run_seed_file
if File.exists?(seed_path)
print "Running seed file at #{seed_path}"
begin
Process.run("crystal #{seed_path}", shell: true, output: stdout, error: stderr)
rescue ex : Exception
print "Error running seed file: #{ex.message}"
treagod marked this conversation as resolved.
Show resolved Hide resolved
end
else
print "Seed file not found at #{seed_path}. Generating default seed.cr..."
write_seed_file
treagod marked this conversation as resolved.
Show resolved Hide resolved
end
end

private def write_seed_file
unless File.exists?(seed_path)
FileUtils.mkdir_p(Path[seed_path].dirname)
File.write(seed_path, SEED_SOURCE_CONTENT)
print "Default seed file generated at #{seed_path}."
end
end
end
end
end
end
end
Loading