/
boson.rb
96 lines (82 loc) · 3.33 KB
/
boson.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
%w{hirb alias}.each {|e| require e }
%w{runner runners/console_runner repo manager loader inspector library}.each {|e| require "boson/#{e}" }
%w{argument method comment}.each {|e| require "boson/inspectors/#{e}_inspector" }
# order of library subclasses matters
%w{module file gem require local_file}.each {|e| require "boson/libraries/#{e}_library" }
(%w{namespace view command util commands option_parser options} +
%w{index repo_index scientist option_command pipe pipes version}).each {|e| require "boson/#{e}" }
# This module stores the libraries, commands, repos and main object used throughout Boson.
#
# Useful documentation links:
# * Boson::BinRunner - Runs the boson executable
# * Boson::ConsoleRunner - Runs Boson from the ruby console
# * Boson::Repo.config - Explains main config file
# * Boson::Library - All about libraries
# * Boson::FileLibrary - Explains creating libraries as files
# * Boson::Loader - Explains library module callbacks
# * Boson::OptionParser - All about options
module Boson
# Module which is extended by Boson.main_object to give it command functionality.
module Universe; include Commands::Namespace; end
NAMESPACE = '.' # Delimits namespace from command
extend self
# The object which holds and executes all command functionality
attr_accessor :main_object
attr_accessor :commands, :libraries
alias_method :higgs, :main_object
# Array of loaded Boson::Library objects.
def libraries
@libraries ||= Array.new
end
# Array of loaded Boson::Command objects.
def commands
@commands ||= Array.new
end
# The main required repository which defaults to ~/.boson.
def repo
@repo ||= Repo.new("#{Util.find_home}/.boson")
end
# An optional local repository which defaults to ./lib/boson or ./.boson.
def local_repo
@local_repo ||= begin
ignored_dirs = (repo.config[:ignore_directories] || []).map {|e| File.expand_path(e) }
dir = ["lib/boson", ".boson"].find {|e| File.directory?(e) &&
File.expand_path(e) != repo.dir && !ignored_dirs.include?(File.expand_path('.')) }
Repo.new(dir) if dir
end
end
# The array of loaded repositories containing the main repo and possible local and global repos
def repos
@repos ||= [repo, local_repo, global_repo].compact
end
# Optional global repository at /etc/boson
def global_repo
File.exists?('/etc/boson') ? Repo.new('/etc/boson') : nil
end
def main_object=(value) #:nodoc:
@main_object = value.extend(Universe)
end
def library(query, attribute='name') #:nodoc:
libraries.find {|e| e.send(attribute) == query }
end
# Start Boson by loading repositories and their configured libraries.
# See ConsoleRunner.start for its options.
def start(options={})
ConsoleRunner.start(options)
end
# Invoke an action on the main object.
def invoke(*args, &block)
main_object.send(*args, &block)
end
# Invoke command string even with namespaces
def full_invoke(cmd, args) #:nodoc:
command, subcommand = cmd.include?(NAMESPACE) ? cmd.split(NAMESPACE, 2) : [cmd, nil]
dispatcher = subcommand ? Boson.invoke(command) : Boson.main_object
dispatcher.send(subcommand || command, *args)
end
# Boolean indicating if the main object can invoke the given method/command.
def can_invoke?(meth, priv=true)
Boson.main_object.respond_to? meth, priv
end
end
Boson.main_object = self