Class: Browserctl::FlowRegistry
- Inherits:
-
Object
- Object
- Browserctl::FlowRegistry
- Defined in:
- lib/browserctl/flow_registry.rb
Overview
Discovers and loads flow files from project, user, and bundled stdlib locations. Project flows shadow user flows, which shadow stdlib flows.
Files are plain Ruby; loading them is expected to invoke ‘Browserctl.flow(name) { … }`, which registers the flow in the global registry. Filename should match the registered name (validated lazily —mismatches are allowed but discouraged).
Constant Summary collapse
- SAFE_NAME =
/\A[a-zA-Z0-9_-]+\z/
Class Method Summary collapse
-
.bundled_dir ⇒ Object
Search order: highest-precedence last so later registrations overwrite earlier ones in the global registry.
- .list ⇒ Object
-
.load_all ⇒ Object
Loads every flow file from every search path.
- .project_dir ⇒ Object
-
.resolve(name) ⇒ Object
Resolves a name to a registered flow, loading from disk on demand.
- .search_paths ⇒ Object
- .user_dir ⇒ Object
- .validate_name!(name) ⇒ Object
Class Method Details
.bundled_dir ⇒ Object
Search order: highest-precedence last so later registrations overwrite earlier ones in the global registry.
18 |
# File 'lib/browserctl/flow_registry.rb', line 18 def self.bundled_dir = File.("flows/stdlib", __dir__) |
.list ⇒ Object
56 57 58 |
# File 'lib/browserctl/flow_registry.rb', line 56 def self.list load_all.map { |n, f| { name: n, desc: f.description, version: f.version_string } } end |
.load_all ⇒ Object
Loads every flow file from every search path. Lower-precedence dirs run first; project files load last and win on name collisions.
28 29 30 31 32 33 34 35 |
# File 'lib/browserctl/flow_registry.rb', line 28 def self.load_all search_paths.each do |dir| next unless Dir.exist?(dir) Dir.glob(File.join(dir, "*.rb")).each { |f| load f } end Browserctl.flow_registry_snapshot end |
.project_dir ⇒ Object
20 |
# File 'lib/browserctl/flow_registry.rb', line 20 def self.project_dir = "./.browserctl/flows" |
.resolve(name) ⇒ Object
Resolves a name to a registered flow, loading from disk on demand. Searches in precedence order: project → user → stdlib. The first matching file is loaded and the flow returned via the global registry.
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/browserctl/flow_registry.rb', line 40 def self.resolve(name) validate_name!(name) existing = Browserctl.lookup_flow(name) return existing if existing search_paths.reverse_each do |dir| candidate = File.join(dir, "#{name}.rb") next unless File.exist?(candidate) load candidate flow = Browserctl.lookup_flow(name) return flow if flow end nil end |
.search_paths ⇒ Object
22 23 24 |
# File 'lib/browserctl/flow_registry.rb', line 22 def self.search_paths [bundled_dir, user_dir, project_dir] end |
.user_dir ⇒ Object
19 |
# File 'lib/browserctl/flow_registry.rb', line 19 def self.user_dir = File.("~/.browserctl/flows") |
.validate_name!(name) ⇒ Object
60 61 62 63 64 |
# File 'lib/browserctl/flow_registry.rb', line 60 def self.validate_name!(name) return if SAFE_NAME.match?(name.to_s) raise ArgumentError, "invalid flow name: #{name.inspect} — use letters, digits, _ and - only" end |