Class: Ast::Merge::Recipe::Runner

Inherits:
Object
  • Object
show all
Defined in:
lib/ast/merge/recipe/runner.rb

Overview

Executes a merge recipe against target files.

The runner:

  1. Loads the template file
  2. Expands target file globs
  3. For each target, finds the injection point and performs the merge
  4. Collects results for reporting

Examples:

Running a recipe

recipe = Recipe::Config.load(".merge-recipes/gem_family_section.yml")
runner = Recipe::Runner.new(recipe, dry_run: true)
results = runner.run
puts runner.summary

With custom parser

runner = Recipe::Runner.new(recipe, parser: :markly, base_dir: "/path/to/project")
results = runner.run

See Also:

Defined Under Namespace

Classes: Result

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(recipe, dry_run: false, base_dir: nil, parser: :markly, verbose: false, target_files: nil, **options) ⇒ Runner

Initialize a recipe runner.

Parameters:

  • recipe (Config)

    The recipe to execute

  • dry_run (Boolean) (defaults to: false)

    If true, don’t write files

  • base_dir (String, nil) (defaults to: nil)

    Base directory for path resolution

  • parser (Symbol) (defaults to: :markly)

    Which parser to use

  • verbose (Boolean) (defaults to: false)

    Enable verbose output

  • target_files (Array<String>, nil) (defaults to: nil)

    Override recipe targets with these files



57
58
59
60
61
62
63
64
65
# File 'lib/ast/merge/recipe/runner.rb', line 57

def initialize(recipe, dry_run: false, base_dir: nil, parser: :markly, verbose: false, target_files: nil, **options)
  @recipe = recipe
  @dry_run = dry_run
  @base_dir = base_dir || Dir.pwd
  @parser = parser
  @verbose = verbose
  @target_files = target_files
  @results = []
end

Instance Attribute Details

#base_dirString (readonly)

Returns Base directory for path resolution.

Returns:

  • (String)

    Base directory for path resolution



38
39
40
# File 'lib/ast/merge/recipe/runner.rb', line 38

def base_dir
  @base_dir
end

#dry_runBoolean (readonly)

Returns Whether this is a dry run.

Returns:

  • (Boolean)

    Whether this is a dry run



35
36
37
# File 'lib/ast/merge/recipe/runner.rb', line 35

def dry_run
  @dry_run
end

#parserSymbol (readonly)

Returns Parser to use (:markly, :commonmarker, :prism, :psych, etc.).

Returns:

  • (Symbol)

    Parser to use (:markly, :commonmarker, :prism, :psych, etc.)



41
42
43
# File 'lib/ast/merge/recipe/runner.rb', line 41

def parser
  @parser
end

#recipeConfig (readonly)

Returns The recipe being executed.

Returns:

  • (Config)

    The recipe being executed



32
33
34
# File 'lib/ast/merge/recipe/runner.rb', line 32

def recipe
  @recipe
end

#resultsArray<Result> (readonly)

Returns Results from the last run.

Returns:

  • (Array<Result>)

    Results from the last run



47
48
49
# File 'lib/ast/merge/recipe/runner.rb', line 47

def results
  @results
end

#target_filesArray<String>? (readonly)

Returns Target files override (from command line).

Returns:

  • (Array<String>, nil)

    Target files override (from command line)



44
45
46
# File 'lib/ast/merge/recipe/runner.rb', line 44

def target_files
  @target_files
end

Instance Method Details

#results_by_statusHash<Symbol, Array<Result>>

Get results grouped by status.

Returns:

  • (Hash<Symbol, Array<Result>>)


96
97
98
# File 'lib/ast/merge/recipe/runner.rb', line 96

def results_by_status
  @results.group_by(&:status)
end

#results_tableArray<Hash>

Format results as an array of hashes for TableTennis.

Returns:

  • (Array<Hash>)


118
119
120
121
122
123
124
125
126
127
# File 'lib/ast/merge/recipe/runner.rb', line 118

def results_table
  @results.map do |r|
    {
      file: r.relative_path,
      status: r.status.to_s,
      changed: r.changed ? "yes" : "no",
      message: r.message,
    }
  end
end

#runArray<Result>

Run the recipe against all target files.

Returns:

  • (Array<Result>)

    Results for each processed file



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/ast/merge/recipe/runner.rb', line 70

def run
  @results = []

  template_content = load_template

  # Use command-line targets if provided, otherwise expand from recipe
  files_to_process = if @target_files && !@target_files.empty?
    # Expand paths relative to base_dir
    @target_files.map { |f| File.expand_path(f, @base_dir) }
  else
    # Let the recipe expand targets from its own location
    recipe.expand_targets
  end

  files_to_process.each do |target_path|
    result = process_file(target_path, template_content)
    @results << result
    yield result if block_given?
  end

  @results
end

#summaryHash

Get a summary hash of the run.

Returns:

  • (Hash)


103
104
105
106
107
108
109
110
111
112
113
# File 'lib/ast/merge/recipe/runner.rb', line 103

def summary
  by_status = results_by_status
  {
    total: @results.size,
    updated: (by_status[:updated] || []).size,
    would_update: (by_status[:would_update] || []).size,
    unchanged: (by_status[:unchanged] || []).size,
    skipped: (by_status[:skipped] || []).size,
    errors: (by_status[:error] || []).size,
  }
end

#summary_tableArray<Hash>

Format summary as an array of hashes for TableTennis.

Returns:

  • (Array<Hash>)


132
133
134
135
136
137
138
139
140
141
# File 'lib/ast/merge/recipe/runner.rb', line 132

def summary_table
  s = summary
  [
    {metric: "Total files", value: s[:total]},
    {metric: "Updated", value: dry_run ? s[:would_update] : s[:updated]},
    {metric: "Unchanged", value: s[:unchanged]},
    {metric: "Skipped (no anchor)", value: s[:skipped]},
    {metric: "Errors", value: s[:errors]},
  ]
end