saturday-night-beaver
Saturday🪩Night🦫Beaver
Project codename: Saturday🪩Night🦫Beaver. Implementation/package/module name: Crake.
A Crystal port of Ruby's Rake build tool, now with a little extra disco-beaver energy.
VS Code Tasks
This workspace now includes two editor tasks:
👀🧪 Saturday🪩Night🦫Beaver spec watcher— the default build task; rerunscrystal spec --error-tracewhenever files undersrc/,spec/, orshard.ymlchange.🧪 Saturday🪩Night🦫Beaver specs— the default test task; runs the spec suite once with error traces enabled.
Installation
Add to your shard.yml:
dependencies:
crake:
github: KarlAmort/crake
Then run shards install.
Usage
Create a Crakefile.cr:
require "crake"
desc "Build the project"
task "build" do |_|
sh "crystal build src/main.cr"
end
desc "Run tests"
task "test", deps: ["build"] do |_|
sh "crystal spec"
end
desc "Clean build artifacts"
task "clean" do |_|
sh "rm -rf bin/"
end
task "default", deps: ["test"]
Crake.run
Run it:
crystal run Crakefile.cr # Run default task
crystal run Crakefile.cr -- build # Run specific task
crystal run Crakefile.cr -- -T # List tasks
crystal run Crakefile.cr -- deploy[host] # Task with arguments
Or compile for speed:
crystal build Crakefile.cr -o crake --release
./crake build
Features
Task Dependencies
task "deploy", deps: ["build", "test"] do |_|
sh "rsync -avz build/ server:/app/"
end
Namespaces
namespace "db" do |_|
desc "Run migrations"
task "migrate" do |_|
sh "bin/rails db:migrate"
end
desc "Seed database"
task "seed", deps: ["db:migrate"] do |_|
sh "bin/rails db:seed"
end
end
File Tasks (timestamp-based)
file "output.o", deps: ["input.c"] do |_|
sh "cc -c input.c -o output.o"
end
File Creation Tasks (existence-based)
file_create "build/" do |_|
Dir.mkdir_p("build/")
end
Directory Tasks
directory "build/obj/debug" # Creates all intermediate dirs
Multitasks (parallel prerequisites)
multitask "assets", deps: ["css", "js", "images"] do |_|
puts "All assets compiled"
end
Task Arguments
task "deploy", arg_names: ["host", "user"] do |args|
host = args["host"] || "localhost"
user = args["user"] || "deploy"
sh "ssh #{user}@#{host} 'deploy.sh'"
end
# Invoke: ./crake deploy[myserver,admin]
Rules (pattern-based task synthesis)
rule ".o", [".c"] do |t|
sh "cc -c #{t.prerequisites.first} -o #{t.name}"
end
Shell Helpers
sh "make all" # Run command, raise on failure
output = sh_output("git rev-parse HEAD") # Capture output
FileList (glob-based file collections)
sources = Crake::FileList["src/**/*.cr"]
sources.exclude(/spec/)
CLI Options
-T, --tasks Display tasks with descriptions
-AT, --all Display all tasks
-P, --prereqs Display task prerequisites
-t, --trace Turn on invoke/execute tracing
-n, --dry-run Do a dry run without executing actions
-s, --silent Suppress status output
-m, --multitask Run all prerequisites in parallel
-B, --build-all Build all prerequisites
-j, --jobs N Number of parallel workers
-f, --rakefile FILE Use FILE as the Crakefile
-V, --version Display the version
-h, --help Display this help
Ported from Ruby's Rake
Core classes faithfully ported:
Task— basic tasks with dependencies and actionsFileTask— timestamp-based file rebuild logicFileCreationTask— existence-based one-time tasksMultiTask— parallel prerequisite execution via Crystal fibersTaskManager— task registry, lookup, and rule synthesisApplication— CLI parsing and task orchestrationScope/LinkedList— immutable namespace scopingInvocationChain— circular dependency detectionTaskArguments— named argument passing with parent chainsFileList— glob-based file collections with exclusionsNameSpace— scoped task lookup- Full DSL (
task,file,namespace,desc,rule,sh, etc.)
License
MIT
Repository
saturday-night-beaver
Owner
Statistic
- 0
- 0
- 0
- 0
- 0
- about 9 hours ago
- April 2, 2026
License
MIT License
Links
Synced at
Thu, 02 Apr 2026 13:04:56 GMT
Languages