Class: Asgard::Base
Direct Known Subclasses
Class Method Summary collapse
-
._build_dep_graph(stages) ⇒ Object
Translate stages into a DependencyGraph-compatible hash.
- ._deps ⇒ Object
- ._ran_mutex ⇒ Object
- ._ran_tasks ⇒ Object
-
._reset_ran! ⇒ Object
Reset execution tracking for a fresh asgard invocation.
- ._vars ⇒ Object
-
.depends_on(*recipes) ⇒ Object
Declare dependencies for the next recipe.
- .dotenv(path = ".env") ⇒ Object
- .import(mod) ⇒ Object
- .inherited(subclass) ⇒ Object
- .method_added(method_name) ⇒ Object
- .subclasses ⇒ Object
-
.validate_deps! ⇒ Object
Validate the full dep graph for cycles using Dagwood::DependencyGraph.
- .var(name, value = nil, &block) ⇒ Object
Methods included from Shell
Class Method Details
._build_dep_graph(stages) ⇒ Object
Translate stages into a DependencyGraph-compatible hash.
stages: [[:one], [:two, :three], [:four]]
→ { one: [], two: [:one], three: [:one], four: [:two, :three] }
51 52 53 54 55 56 57 58 |
# File 'lib/asgard/base.rb', line 51 def _build_dep_graph(stages) graph = {} stages.each_with_index do |stage, i| prev_stage = i > 0 ? stages[i - 1] : [] stage.each { |task| graph[task] = prev_stage.dup } end graph end |
._deps ⇒ Object
26 27 28 |
# File 'lib/asgard/base.rb', line 26 def _deps @_deps ||= {} end |
._ran_mutex ⇒ Object
38 39 40 |
# File 'lib/asgard/base.rb', line 38 def _ran_mutex @_ran_mutex ||= Mutex.new end |
._ran_tasks ⇒ Object
34 35 36 |
# File 'lib/asgard/base.rb', line 34 def _ran_tasks @_ran_tasks ||= Set.new end |
._reset_ran! ⇒ Object
Reset execution tracking for a fresh asgard invocation.
43 44 45 |
# File 'lib/asgard/base.rb', line 43 def _reset_ran! _ran_mutex.synchronize { @_ran_tasks = Set.new } end |
._vars ⇒ Object
30 31 32 |
# File 'lib/asgard/base.rb', line 30 def _vars @_vars ||= {} end |
.depends_on(*recipes) ⇒ Object
Declare dependencies for the next recipe. Bare symbols run sequentially; arrays within the splat run in parallel.
depends_on :build # sequential
depends_on :build, :lint # both sequential
depends_on [:build, :lint] # build and lint in parallel
depends_on :setup, [:build, :lint], :test # setup, then build+lint, then test
67 68 69 |
# File 'lib/asgard/base.rb', line 67 def depends_on(*recipes) @_pending_deps = recipes end |
.dotenv(path = ".env") ⇒ Object
86 87 88 89 |
# File 'lib/asgard/base.rb', line 86 def dotenv(path = ".env") require "dotenv" Dotenv.load(path) if File.exist?(path) end |
.import(mod) ⇒ Object
82 83 84 |
# File 'lib/asgard/base.rb', line 82 def import(mod) include mod end |
.inherited(subclass) ⇒ Object
16 17 18 19 20 21 22 23 24 |
# File 'lib/asgard/base.rb', line 16 def inherited(subclass) super Asgard::Base.subclasses << subclass subclass.instance_variable_set(:@_deps, {}) subclass.instance_variable_set(:@_vars, {}) subclass.instance_variable_set(:@_pending_deps, []) subclass.instance_variable_set(:@_ran_tasks, Set.new) subclass.instance_variable_set(:@_ran_mutex, Mutex.new) end |
.method_added(method_name) ⇒ Object
105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/asgard/base.rb', line 105 def method_added(method_name) pending = Array(@_pending_deps).dup @_pending_deps = [] return super if pending.empty? return super if method_name.to_s.start_with?("_") # Each element is a Symbol (sequential) or Array (parallel group). _deps[method_name.to_sym] = pending.map { |d| Array(d).map(&:to_sym) } super end |
.subclasses ⇒ Object
12 13 14 |
# File 'lib/asgard/base.rb', line 12 def subclasses @subclasses ||= [] end |
.validate_deps! ⇒ Object
Validate the full dep graph for cycles using Dagwood::DependencyGraph.
92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/asgard/base.rb', line 92 def validate_deps! return if _deps.empty? all_tasks = all_commands.keys.map(&:to_sym) full_graph = all_tasks.each_with_object({}) do |task, hash| hash[task] = _deps.fetch(task, []).flatten end Dagwood::DependencyGraph.new(full_graph).order rescue TSort::Cyclic => e raise Asgard::CircularDependencyError, e. end |
.var(name, value = nil, &block) ⇒ Object
71 72 73 74 75 76 77 78 79 80 |
# File 'lib/asgard/base.rb', line 71 def var(name, value = nil, &block) value = block if block_given? _vars[name.to_sym] = value no_commands do define_method(name) do v = self.class._vars[name.to_sym] v.respond_to?(:call) ? v.call : v end end end |