Class: Ast::Merge::Recipe::ScriptLoader

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

Overview

Loads Ruby scripts referenced by a recipe from a companion folder.

Convention: A recipe at .merge-recipes/my_recipe.yml can reference
scripts in .merge-recipes/my_recipe/ folder.

Scripts must define a callable object (lambda, proc, or object with #call method).

Examples:

Script reference in recipe YAML

merge:
  signature_generator: scripts/signature_generator.rb
  node_typing:
    heading: scripts/heading_typing.rb
  add_missing: scripts/add_missing_filter.rb

Script file content (signature_generator.rb)

# Must return a callable
lambda do |node|
  text = node.respond_to?(:to_plaintext) ? node.to_plaintext.to_s : node.to_s
  if text.include?("gem family")
    [:gem_family, :section]
  else
    nil
  end
end

See Also:

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(recipe_path: nil, base_dir: nil) ⇒ ScriptLoader

Initialize a script loader.

Parameters:

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

    Path to recipe file (determines script folder)

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

    Override base directory for scripts



45
46
47
48
# File 'lib/ast/merge/recipe/script_loader.rb', line 45

def initialize(recipe_path: nil, base_dir: nil)
  @base_dir = determine_base_dir(recipe_path, base_dir)
  @script_cache = {}
end

Instance Attribute Details

#base_dirString? (readonly)

Returns Base directory for script resolution.

Returns:

  • (String, nil)

    Base directory for script resolution



36
37
38
# File 'lib/ast/merge/recipe/script_loader.rb', line 36

def base_dir
  @base_dir
end

#script_cacheHash (readonly)

Returns Cache of loaded scripts.

Returns:

  • (Hash)

    Cache of loaded scripts



39
40
41
# File 'lib/ast/merge/recipe/script_loader.rb', line 39

def script_cache
  @script_cache
end

Instance Method Details

#available_scriptsArray<String>

List available scripts.

Returns:

  • (Array<String>)

    Script filenames



88
89
90
91
92
93
94
# File 'lib/ast/merge/recipe/script_loader.rb', line 88

def available_scripts
  return [] unless scripts_available?

  Dir.glob(File.join(base_dir, "**/*.rb")).map do |path|
    path.sub("#{base_dir}/", "")
  end
end

#load_callable(reference) ⇒ Proc?

Load a callable from a script reference.

Parameters:

  • reference (String, Proc, nil)

    Script path, inline expression, or existing callable

Returns:

  • (Proc, nil)

    The callable, or nil if reference is nil

Raises:

  • (ArgumentError)

    If script not found or doesn’t return a callable



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

def load_callable(reference)
  return if reference.nil?
  return reference if reference.respond_to?(:call)

  # Check if it's an inline lambda expression
  if inline_expression?(reference)
    return evaluate_inline_expression(reference)
  end

  # It's a file path reference
  load_script_file(reference)
end

#load_callable_hash(config) ⇒ Hash?

Load a hash of callables (e.g., node_typing config).

Parameters:

  • config (Hash, nil)

    Hash with script references as values

Returns:

  • (Hash, nil)

    Hash with callables as values



72
73
74
75
76
# File 'lib/ast/merge/recipe/script_loader.rb', line 72

def load_callable_hash(config)
  return if config.nil? || config.empty?

  config.transform_values { |ref| load_callable(ref) }
end

#scripts_available?Boolean

Check if scripts directory exists.

Returns:

  • (Boolean)


81
82
83
# File 'lib/ast/merge/recipe/script_loader.rb', line 81

def scripts_available?
  !!(base_dir && Dir.exist?(base_dir))
end