Skip to content

Asgard

Upgrading from an earlier version?

Version 0.6.0 has breaking changes to scheduled tasks, watchers and sh. Read Breaking Changes before you upgrade.

Asgard
"Loki collects the tricks.
Thor of Asgard runs them."
Key Features
  • Tasks in plain Ruby: a task is a method in a .loki file; every Thor DSL word (desc, method_option, long_desc, map, subcommand) works as written
  • Dependencies: depends_on runs prerequisites first, in sequence or in parallel stages, each at most once per run
  • Shell commands: execute shell scripts through user-defined shell environments, as foreground or background processes
  • Variables and helpers: @@name values shared by every task, helper methods usable in help text and task bodies alike
  • Subcommands: group tasks as asgard db migrate or asgard server start
  • Environment: dotenv loads a .env file; env(:port, "3000") reads a variable with a default
  • Auto-discovery: run asgard from any subdirectory; it finds the project's .loki by walking up
  • Multi-file projects: split tasks across *.loki files and pull them in with import
  • Scheduled tasks: schedule :backup, at: "02:00" and asgard schedule install hand a task to launchd or systemd
  • Watched files: watch :test, paths: "lib" and asgard watcher start run a task whenever files change
  • Background jobs: sh "mkdocs serve", background: true starts a job that outlives asgard; asgard jobs lists, stops and restarts it
  • Built-in flags: --version, --debug, --verbose and --doctor, which diagnoses a project's task files

Asgard is a command-line task runner for any project. You describe the tasks a project needs (build it, test it, deploy it, serve its docs) as short Ruby methods in a file named .loki, and asgard <task> runs them. Asgard orders prerequisites for you, runs independent ones in parallel, and can keep running tasks when you are not at the keyboard: on a timer, when files change, or as a background process you manage later.

The name is a small joke: Thor is the command-line toolkit asgard is built on, Asgard is where the tasks live, and Loki, the .loki file, holds all the tricks.


Quick Start

# Install the command
gem install asgard

# Mark your project root
cd ~/work/myproject
touch .loki

# Add a first task
cat >> .loki << 'EOF'
class Tasks
  desc "Say hello"
  def hello = puts "Hello from Asgard!"
end
EOF

# Run it
asgard hello
Hello from Asgard!

asgard help lists every task the project defines, and asgard help hello shows the help for one of them.


How It Works

When you type asgard build, asgard looks for a file named .loki in the current directory, then in its parent, and so on up to the root of the filesystem. The first one it finds marks the project root, so the command works from any subdirectory of the project.

That .loki file is plain Ruby. Asgard has already defined a class named Tasks; your file reopens it and adds methods. Each public method with a desc is a task you can run from the command line:

class Tasks
  desc "Compile the project"
  def build = sh "rake build"

  depends_on :build
  desc "Run the tests"
  def test = sh "rake test"
end

Only .loki loads on its own. When a project outgrows one file, .loki says what else to load with import "*.loki", and every imported file reopens the same Tasks class.

Asgard is built on Thor, so the words you may know from other Ruby command-line tools work unchanged inside a .loki: desc, method_option, class_option, long_desc, argument, default_task, map and subcommand. Asgard adds its own on top: depends_on, sh and shebang (with background: for jobs), shell, default_shell, helper, header, footer, dotenv, schedule and watch.


Where to Go Next

The manual is layered. Each page starts with the simplest thing that works and goes deeper from there, so you can stop reading whenever you have what you need.

Start with Getting Started, then pick from the sections below.

Writing Tasks

Page What it covers
Defining Tasks desc, parameters, options, long_desc, hidden tasks, default_task, aliases, exit status
Shell Commands sh and shebang, the shells registry, pinning a bash, long-running commands
Dependencies Sequential and parallel stages, run-once rules, failures, dep_result, computed dependency lists
Options & Flags Per-task and class-wide options, the built-in flags, debug? and verbose?
Variables @@ class variables, constants, interpolation, computed values
Helper Methods private, no_commands, the helper DSL, sharing helpers across files
Subcommands Grouping tasks under a name such as asgard db migrate

Organizing a Project

Page What it covers
Task Files The .loki marker, import, import_up, loki_up, multi-file layouts, overridden tasks
Environment Variables dotenv, env(), and every variable asgard sets or reads
Help & Diagnostics asgard help, asgard tree, header/footer, the --doctor report, error messages and exit codes

Built-in Commands

Page What it covers
Scheduled Tasks schedule :task, at: ... and asgard schedule install, list, start, stop and more, under launchd or systemd
Watched Files watch :task, paths: ..., asgard watcher start, stop, list and more, and changes inside a task
Background Jobs sh ..., background: true and asgard jobs list, stop, log, restart and clean

Reference

Page What it covers
DSL Reference Every word you can write in a .loki, with its signature
Command Reference Every asgard command, subcommand and flag
Files & Directories Where asgard keeps logs, state and job definitions on disk
Examples The working .loki files shipped in the repository

Tips collects short pieces of practical advice from daily use. Breaking Changes explains the 0.6.0 changes that affect existing schedules, watchers and sh calls, and the Changelog has the release history.


Requirements

  • Ruby 4.0 or later.
  • macOS or Linux for scheduled tasks and the file watcher (launchd on macOS, systemd user timers on Linux).
  • A POSIX system for background jobs (sh ..., background: true and asgard jobs), which need fork, setsid and /bin/sh. Everything else works wherever Ruby does.
  • A C++17 compiler at install time: gem install asgard compiles one native extension. Xcode's command-line tools or a distribution's build-essential package is enough.

Asgard is on RubyGems; the source and issue tracker are on GitHub.