From 828cbe8aabe995acf4f799fd12e2ade38e105e6f Mon Sep 17 00:00:00 2001 From: Samuel Williams Date: Tue, 20 Aug 2024 23:45:59 +1200 Subject: [PATCH] Reorganise loaders and `Registry`. --- lib/bake/registry.rb | 119 +--------------- lib/bake/registry/aggregate.rb | 128 ++++++++++++++++++ .../{loader => registry}/directory_loader.rb | 2 +- lib/bake/{loader => registry}/file_loader.rb | 2 +- .../{loader => registry}/inline_loader.rb | 2 +- 5 files changed, 135 insertions(+), 118 deletions(-) create mode 100644 lib/bake/registry/aggregate.rb rename lib/bake/{loader => registry}/directory_loader.rb (99%) rename lib/bake/{loader => registry}/file_loader.rb (96%) rename lib/bake/{loader => registry}/inline_loader.rb (98%) diff --git a/lib/bake/registry.rb b/lib/bake/registry.rb index c4c6a0f..45560cf 100644 --- a/lib/bake/registry.rb +++ b/lib/bake/registry.rb @@ -3,124 +3,13 @@ # Released under the MIT License. # Copyright, 2020-2024, by Samuel Williams. -require 'console' - -require_relative 'loader/directory_loader' -require_relative 'loader/file_loader' -require_relative 'loader/inline_loader' +require_relative 'registry/aggregate' module Bake # Structured access to the working directory and loaded gems for loading bakefiles. - class Registry - include Enumerable - - # Create a loader using the specified working directory. - # @parameter working_directory [String] - def self.default(working_directory, bakefile_path = nil) - registry = self.new - - if bakefile_path - registry.append_bakefile(bakefile_path) - end - - registry.append_defaults(working_directory) - - return registry - end - - # Initialize an empty array of registry. - def initialize - # Used to de-duplicated directories: - @roots = {} - - # The ordered list of loaders: - @ordered = Array.new - - @wrappers = Loader::InlineLoader.new - end - - def wrap(...) - @wrappers.wrap(...) - end - - # Whether any registry are defined. - # @returns [Boolean] - def empty? - @ordered.empty? - end - - # Enumerate the registry in order. - def each(&block) - @ordered.each(&block) - yield @wrappers - end - - def scopes_for(path) - @ordered.each do |loader| - if scope = loader.scope_for(path) - yield scope - end - end - - @wrappers.scopes_for(path) do |scope| - yield scope - end - end - - def append_bakefile(path) - @ordered << Loader::FileLoader.new({ - [] => path - }) - end - - # Append a specific project path to the search path for recipes. - # The computed path will have `bake` appended to it. - # @parameter current [String] The path to add. - def append_path(current = Dir.pwd, **options) - bake_path = File.join(current, "bake") - - if File.directory?(bake_path) - return insert(bake_path, **options) - end - - return false - end - - # Add registry according to the current working directory and loaded gems. - # @parameter working_directory [String] - def append_defaults(working_directory) - # Load recipes from working directory: - self.append_path(working_directory) - - # Load recipes from loaded gems: - self.append_from_gems - end - - # Enumerate all loaded gems and add them. - def append_from_gems - ::Gem.loaded_specs.each do |name, spec| - Console.debug(self) {"Checking gem #{name}: #{spec.full_gem_path}..."} - - if path = spec.full_gem_path and File.directory?(path) - append_path(path, name: spec.full_name) - end - end - end - - protected - - def insert(directory, **options) - unless @roots.key?(directory) - Console.debug(self) {"Adding #{directory.inspect}"} - - loader = Loader::DirectoryLoader.new(directory, **options) - @roots[directory] = loader - @ordered << loader - - return true - end - - return false + module Registry + def self.default(...) + Aggregate.default(...) end end end diff --git a/lib/bake/registry/aggregate.rb b/lib/bake/registry/aggregate.rb new file mode 100644 index 0000000..b5ffd73 --- /dev/null +++ b/lib/bake/registry/aggregate.rb @@ -0,0 +1,128 @@ +# frozen_string_literal: true + +# Released under the MIT License. +# Copyright, 2020-2024, by Samuel Williams. + +require 'console' + +require_relative 'directory_loader' +require_relative 'file_loader' +require_relative 'inline_loader' + +module Bake + # Structured access to the working directory and loaded gems for loading bakefiles. + module Registry + class Aggregate + include Enumerable + + # Create a loader using the specified working directory. + # @parameter working_directory [String] + def self.default(working_directory, bakefile_path = nil) + registry = self.new + + if bakefile_path + registry.append_bakefile(bakefile_path) + end + + registry.append_defaults(working_directory) + + return registry + end + + # Initialize an empty array of registry. + def initialize + # Used to de-duplicated directories: + @roots = {} + + # The ordered list of loaders: + @ordered = Array.new + + @wrappers = InlineLoader.new + end + + def wrap(...) + @wrappers.wrap(...) + end + + # Whether any registry are defined. + # @returns [Boolean] + def empty? + @ordered.empty? + end + + # Enumerate the registry in order. + def each(&block) + @ordered.each(&block) + yield @wrappers + end + + def scopes_for(path) + @ordered.each do |loader| + if scope = loader.scope_for(path) + yield scope + end + end + + @wrappers.scopes_for(path) do |scope| + yield scope + end + end + + def append_bakefile(path) + @ordered << FileLoader.new({ + [] => path + }) + end + + # Append a specific project path to the search path for recipes. + # The computed path will have `bake` appended to it. + # @parameter current [String] The path to add. + def append_path(current = Dir.pwd, **options) + bake_path = File.join(current, "bake") + + if File.directory?(bake_path) + return insert(bake_path, **options) + end + + return false + end + + # Add registry according to the current working directory and loaded gems. + # @parameter working_directory [String] + def append_defaults(working_directory) + # Load recipes from working directory: + self.append_path(working_directory) + + # Load recipes from loaded gems: + self.append_from_gems + end + + # Enumerate all loaded gems and add them. + def append_from_gems + ::Gem.loaded_specs.each do |name, spec| + Console.debug(self) {"Checking gem #{name}: #{spec.full_gem_path}..."} + + if path = spec.full_gem_path and File.directory?(path) + append_path(path, name: spec.full_name) + end + end + end + + protected + + def insert(directory, **options) + unless @roots.key?(directory) + Console.debug(self) {"Adding #{directory.inspect}"} + + loader = DirectoryLoader.new(directory, **options) + @roots[directory] = loader + @ordered << loader + + return true + end + + return false + end + end + end +end diff --git a/lib/bake/loader/directory_loader.rb b/lib/bake/registry/directory_loader.rb similarity index 99% rename from lib/bake/loader/directory_loader.rb rename to lib/bake/registry/directory_loader.rb index 063355c..392603c 100644 --- a/lib/bake/loader/directory_loader.rb +++ b/lib/bake/registry/directory_loader.rb @@ -6,7 +6,7 @@ require_relative '../scope' module Bake - module Loader + module Registry # Represents a directory which contains bakefiles. class DirectoryLoader # Initialize the loader with the specified root path. diff --git a/lib/bake/loader/file_loader.rb b/lib/bake/registry/file_loader.rb similarity index 96% rename from lib/bake/loader/file_loader.rb rename to lib/bake/registry/file_loader.rb index 74eb3d9..cb74f7b 100644 --- a/lib/bake/loader/file_loader.rb +++ b/lib/bake/registry/file_loader.rb @@ -6,7 +6,7 @@ require_relative '../scope' module Bake - module Loader + module Registry class FileLoader def initialize(paths) @paths = paths diff --git a/lib/bake/loader/inline_loader.rb b/lib/bake/registry/inline_loader.rb similarity index 98% rename from lib/bake/loader/inline_loader.rb rename to lib/bake/registry/inline_loader.rb index eb221e8..2a75052 100644 --- a/lib/bake/loader/inline_loader.rb +++ b/lib/bake/registry/inline_loader.rb @@ -1,5 +1,5 @@ module Bake - module Loader + module Registry class InlineLoader def initialize @wrappers = Hash.new do |hash, key|