Changelog¶
All notable changes to Asgard are documented here.
The format follows Keep a Changelog. Asgard adheres to Semantic Versioning.
Unreleased¶
Added¶
--doctorbuilt-in CLI flag — diagnoses.lokiresolution, import chains, and task definitions for the current directory. Handled directly inAsgard.run!(same pattern as--version), so it works even when a broken file, a circular/undefined dependency, or a silently redefined task would otherwise abort the whole process. Backed by the newAsgard::Doctorclass. Includes a "Tasks by file" listing — every command grouped by the file it's defined in, asfile:line, with any silently-overridden task annotated inline (OVERRIDDEN by .../active — redefines ...). See API Reference.helperDSL method — defines a method available in both class context (e.g. insideheader) and instance context (inside task methods) with a single declaration. Eliminates the manualdef self.name+no_commands { private def name = self.class.name }boilerplate. Supports positional arguments, keyword arguments, and block arguments. See Helper Methods.- Flay and Reek quality gates —
flay_checkchecks for structural duplication (mass ≥ 150);reekchecks code smells. Reviewed findings are grandfathered precisely, per method and detector, viareek --todo-generatedexclude:entries in.reek.yml— a genuinely new smell still fails the gate even at an already-reviewed method. test_verbose,consoletasks — verbose test output and an IRB console with the gem loaded.git.loki— per-repopush/pull/fetchtasks.typos_check/typos_fixtasks — spell-checking via the externaltyposCLI (brew install typos-cli). ReportsSKIP(not a failure) iftyposisn't installed, with a one-line install hint.fasterer_checktask — performance-idiom suggestions from thefasterergem, reported asWARN(non-blocking).SKIP/WARNquality-gate statuses — alongsidePASS/FAIL; onlyFAILblocksquality.- Every quality gate now writes full detail to a
<gate>_output.txtfile (gitignored) and prints just a one-line summary to stdout. asgard treenow shows the project header/footer, matchingasgard help.bundler_audit_checktask —bundle-audit check --updateagainstGemfile.lock;FAILon any known vulnerability.quality_rails.loki— imported only whenRailsis defined; shipsbrakeman_checkas a Rails security-scan example. No wiring needed —qualitydiscovers it automatically (seedepends_onbelow).depends_onaccepts a Proc/lambda, not just a fixed list — resolved once, invalidate_deps!, after every.lokifile has loaded, instead of immediately. Solves "load order matters" for a dependency list that can't be known upfront, e.g. every task ending in_checkacross several files. See Dynamic Dependencies.depends_onalso accepts a block —depends_on { ... }ordepends_on do ... end, interchangeable with the Proc/lambda form above. Task arguments and a block can't be combined; doing so raisesAsgard::Error.- The Proc/lambda/block result is now shape-validated once resolved — it must be an
ArrayofSymbol/String(sequential) orArrayofSymbol/String(parallel group) stages, nested no deeper. A bad shape raises a clearAsgard::Errornaming the task and the offending value instead of a rawNoMethodError. Seeexamples/depends_on_block/{good,bad}/.
Changed¶
qualitytask — discovers every*_checktask at run time (via adepends_onProc) rather than a fixed list, and runs them all in parallel with a colorized PASS/FAIL/WARN/SKIP summary and tally.test,rubocop,reekrenamed totest_check,rubocop_check,reek_check— consistency with the other gates is what makesquality's automatic discovery possible.releasetask — prompts for confirmation unless-y/--yesis passed.Asgard::BaseandAsgard::Doctorsplit into mixins —lib/asgard/base/{registry,dependency_graph,task_dsl,dispatch}.rbandlib/asgard/doctor/{task_sections,report}.rb. No behavior change; drops both classes' ReekTooManyMethods/TooManyInstanceVariableswarnings to zero.
Fixed¶
bin/asgard— switched fromrequire "asgard"torequire_relative "../lib/asgard"so the executable always loads the library shipped alongside it, instead of whateverasgardgem happens to be installed separately.
Removed¶
reek_baseline/ensure_quality_dirtasks and.quality/— superseded by precise per-methodexclude:entries in.reek.yml(see the Reek gate entry above).varDSL method — replaced by native Ruby class variables. Use@@name ||= "value".freezein the class body. Class variables are visible in all task instance methods and in subcommand subclasses, making them the correct tool for shared configuration in a Thor-based task runner. See Variables.
0.2.0 — 2026-05-29¶
Changed¶
*.lokifiles are no longer auto-loaded by default. Pass--auto-loadtoasgardto load all*.lokifiles from the project root alphabetically before.loki. This is a breaking change for projects using the multi-file layout.- Added
--auto-loadas a built-in CLI flag inTasks, visible inasgard help
0.1.2 — 2026-05-29¶
Added¶
--versionbuilt-in CLI flag — printsAsgard::VERSIONand exits; implemented as a_-prefixed method inTasksper the gem-owned naming convention--debugand--verbosebuilt-inclass_optiondeclarations onTasks— set$DEBUG/$VERBOSEbefore any task runs via theinvoke_commandhook inAsgard::Basedebug?andverbose?private predicate helpers onTasks— thin wrappers around$DEBUGand$VERBOSEfor use inside task bodies_prefix convention for gem-owned methods inTasks— built-in methods use_prefix to distinguish them from user-defined tasksrun!guards against direct invocation of_-prefixed commands with a clean error message and exit 1examples/directory with working.lokifiles:kitchen_sink.loki— demonstrates the full Thor DSL (all option types,long_desc,class_option,default_task,map,depends_on,var,no_commands,private)server_subcommands.loki— subcommand group for server managementdb_subcommands.loki— subcommand group for database management withdepends_onchainingconcurrent.loki— demonstrates parallel task execution with interleaved thread output- README sections: Helper methods, Subcommands, Thor wrapper callout
Fixed¶
- Replaced
warn/exit 1withabortthroughoutrun!—Kernel#warnis silenced when$VERBOSE = nil, which is the default in Ruby 4.0;abortwrites to$stderrregardless
Changed¶
--debugand--verbosepromoted from mapped tasks toclass_option— they now work as modifiers alongside other commands (e.g.asgard build --debug) rather than as standalone commands- Removed all references to
justtask runner andrecipeterminology; Asgard uses "task" throughout depends_onparameter renamed from*recipesto*tasksfor consistency
0.1.1 — 2026-05-28¶
Added¶
- Parallel dependency execution — wrap deps in an array to run them concurrently:
depends_on [:build, :lint]ordepends_on :setup, [:build, :lint], :deploy Asgard.run!(argv)— single entry point encapsulating find, load, validate, and startAsgard.load_loki(dir)— auto-loads all*.lokifiles in a directory alphabeticallyTasksclass pre-defined by the gem (class Tasks < Asgard::Base) — task files reopen it without restating the superclasslib/asgard/tasks.rb— ships the pre-definedTasksclass
Changed¶
- Replaced
SimpleFlowdependency withDagwood— purpose-built DAG library with no extra dependencies and no Ruby 4 compatibility issues bin/asgardsimplified to two lines:require "asgard"+Asgard.run!(ARGV)- Task file convention:
.lokiis the project root marker and entry point;*.lokifiles each reopenclass Tasksand are auto-loaded before.loki Asgard.find_task_filesrenamed toAsgard.find_task_file(singular — only.lokiis the entry point)depends_onnow accepts mixed sequential/parallel stages; bare symbols run sequentially, arrays within the splat run in parallelrun!handles its own errors — missing.lokiand circular dependencies produce a clean one-line message and exit 1 rather than a backtrace- Thread-safe dep deduplication via class-level
_ran_tasksSet + Mutex replaces Thor's@_invocations - Removed
importmacro — task files use Ruby class reopening instead of modules
Removed¶
SimpleFlowdependency (replaced byDagwood)loggergem workaround (was only needed for SimpleFlow on Ruby 4)*.lokiglob fallback infind_task_file— only.lokiis the auto-discovered entry point
0.1.0 — 2026-05-28¶
Added¶
Asgard::Base— Thor subclass providing the task DSLdepends_on— declare task dependencies; dependencies run at most once per invocationvar— declare static or lazy-evaluated variables available to all tasksimport— flat-merge a task module into the current classdotenv— load a.envfile into the environmentsh— run a shell command or multiline heredoc script; exits with the command's status on failureshebang— write a script body to a tempfile and execute it with a given interpreter (:python3,:node,:ruby,:perl,:bash,:sh, or any custom interpreter)Asgard.find_task_files— search current directory and ancestors for task files- Task file resolution:
.lokitakes priority; falls back to all*.lokifiles sorted alphabetically asgardexecutable — finds task files, validates dependency graph, dispatches via Thor- Circular dependency detection via
SimpleFlow::DependencyGraphat startup - 100% test coverage enforced via SimpleCov (95% minimum threshold)
- Quality task in
.lokiruns flog after tests