Manage your Ruby projects with a straightforward syntax.
Run is compatible with Ruby >=2.4.
gem install run_tasksrun your_taskIf you want to display the available tasks:
run helpThe help provides Run's version, so
run versionwill display the same screen.
Note that the command
rundisplays the help screen by default when no task is specified.
# Displays hello.
task :hello do
puts "hello!"
endThe comment is used by the Run to display the help. It must be placed directly above the task and can be multiline.
Note that help verbatims support Markdown syntax.
task also support aliases, so you can call a task with different names:
task [:console, :c] do
run "bundle exec rails c"
endRunning run c or run console will then start the Rails console.
# Accessing a non-existent file.
task :boom do
run "stat foo"
run "echo 'hello!'"
endIt outputs:
$ run boom
> stat foo
stat: cannot stat 'foo': No such file or directoryAs you can see,
runcaptures errors and stops when something bad happens.
You can run tasks arbitrarily from any other task by passing a symbol:
task :eslint do
run "npx eslint"
end
task :flow do
run "npx flow"
end
task :lint_js do
run :eslint
run :flow
endBy running run lint_js you will call eslint and flow tasks.
You can pass arguments to tasks from the CLI:
task :hello do |name, age|
puts "Hello #{name}, you are #{age}."
end$ run hello 'John Doe' 30
Hello John Doe, you are 30.But also from the Runfile itself:
task :test do
run :hello, "John Doe", 30
endTasks also support named arguments, but those ones are (currently) only available from inside the Runfile:
task :hello do |name:, age:|
puts "Hello #{name}, you are #{age}."
end
task :test do
run :hello, name: "John Doe", age: 30
endIt is often needed to colorize/stylize the messages sent to the user with puts. For this matter, Run is natively shipped with basic styles.
For example:
puts "Please wait...".yellow.boldThe available styles are :
- bold
- dim
- italic
- underline
- inverse
- strikethrough
And the available colors are :
- black
- red
- green
- yellow
- blue
- magenta
- cyan
- white
- bright_black
- bright_red
- bright_green
- bright_yellow
- bright_blue
- bright_magenta
- bright_cyan
- bright_white
Run comes with a few helpers to help writing tasks quicker.
When called, it asks a question to the user which has the choice to enter y, yes, n or no (the default answer). When no is selected, the task will exit with a 9 code.
task :dangerous_task do
are_you_sure "This task will delete your hard drive. Are you sure about that?"
#
# Some dangerous actions.
#
endYou can pause a task if needed, waiting for the user to press any key.
task :some_task do
# some action
pause
# some action
endDisplays a question and returns the answer.
task :survey do
comment = question "Did your meal was good?"
endYou can also pass a regex to validation the entered value:
task :age do
age = question "What is your age?", /^\d+$/
endIt displays an advanced menu where you can choose an element that will be returned by the function.
# Array syntax
task :deploy_aws do
region = menu "Where?", ["us‑east‑2", "us-west-1", "eu-west-1"]
end# Hash syntax
task :deploy_aws do
region = menu "Where?", {
"US East (Ohio)" => "us‑east‑2",
"US West (N. California)" => "us-west-1",
"Europe (Ireland)" => "eu-west-1",
}
endIf you need to wait for the user to interrupt a task of, for example, several running servers, you can use the wait_for_interruption helper.
# Run server in development mode.
task :dev do
Thread.new do
# Run first server.
end
Thread.new do
# Run second server.
end
# Wait for CTRL+C.
wait_for_interruption do
# Some actions to handle before terminating the task, like killing the servers.
end
endAlternatively, if you have a command that stays open until you hit CTRL+C (like a Docker container) and you need to catch the binding, you probably want to use catch_interruption instead so it lets the command handle the interruption gracefully and executes some actions afterwards.
# Run server in development mode.
task :dev do
catch_interruption("docker run -d -p 8080:80 my_docker_image") do
# Run some clean up actions here after the command has been interrupted.
end
endThis one takes a glob string and process it to return a list of files.
task :scan do |glob|
expand(glob).each do |file_path|
# Do something.
end
endRun also comes with some generic tasks for recurring tasks.
# Run the tests.
task [:specs, :s, :tests, :t] do |path = "spec/src"|
run :rspec, path
endRun has specific exit codes so you can handle it better in some environments, like in CI or in deployments:
- 1: Run has exited abnormally.
- 2: The required task does not exist.
- 3: Unhandled Interrupt error coming from a failed shell command.
- 4: An error has been raised in the Runfile.
- 5: The Runfile contains a syntax error.
- 6: Some parameters are invalid.
- 7: Runfile not found.
- 8: Unable to load a remote file.
- 9: The user has answered "No" to an "Are you sure?" question.
- 10: The required task already exists.