Module: Basepath
Constant Summary collapse
- DOT_BASE =
'.base'
Instance Method Summary collapse
- #const_expand!(s, fallback = true) ⇒ Object
- #find_base(start_path) ⇒ Object
- #find_base! ⇒ Object
- #mine(file = false) ⇒ Object
- #path_from_caller_line(caller_line) ⇒ Object
- #resolve! ⇒ Object
Instance Method Details
#const_expand!(s, fallback = true) ⇒ Object
52 53 54 55 56 |
# File 'lib/basepath.rb', line 52 def (s, fallback = true) k = s.sub!(RX_CONSTS, '') && Object.const_get($1) return s if not k unless fallback (k || ::BASE_PATH).join(s) end |
#find_base(start_path) ⇒ Object
19 20 21 22 23 24 |
# File 'lib/basepath.rb', line 19 def find_base(start_path) cur_path = start_path got_base = lambda { cur_path.join(DOT_BASE).exist? } cur_path = cur_path.parent until cur_path == cur_path.parent or got_base[] cur_path if got_base[] end |
#find_base! ⇒ Object
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 |
# File 'lib/basepath.rb', line 26 def find_base! paths_tried = [] caller_line_before_require = caller.inject(false) do |was_in_require, line| is_in_require = line.force_encoding(__ENCODING__) =~ /`(rescue in )?require'$/ break line if was_in_require && !is_in_require is_in_require end if caller_line_before_require path_from_requirer = Pathname.new(path_from_caller_line(caller_line_before_require)).realpath.dirname base_from_requirer = find_base(path_from_requirer) return base_from_requirer if base_from_requirer paths_tried << path_from_requirer end path_from_pwd = Pathname.new(Dir.pwd).realpath pwd_path_parent_of_requirer_path = caller_line_before_require && "#{path_from_requirer}/".index("#{path_from_pwd}/") == 0 if not pwd_path_parent_of_requirer_path base_from_pwd = find_base(path_from_pwd) return base_from_pwd if base_from_pwd paths_tried << path_from_pwd end err = "Can't find #{DOT_BASE} for BASE_PATH. (started at #{paths_tried.first}" err << ", then tried #{paths_tried[1]}" if paths_tried[1] err << ")" raise err end |
#mine(file = false) ⇒ Object
9 10 11 12 13 |
# File 'lib/basepath.rb', line 9 def mine(file = false) path_to_caller = path_from_caller_line(caller.last) path = Pathname.new(path_to_caller).realpath file ? path : path.dirname end |
#path_from_caller_line(caller_line) ⇒ Object
15 16 17 |
# File 'lib/basepath.rb', line 15 def path_from_caller_line(caller_line) caller_line.sub(/:\d+(?::in `.*?')?$/, '').sub(/^\(\w+\)$/, '') end |
#resolve! ⇒ Object
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 |
# File 'lib/basepath.rb', line 58 def resolve! return if Object.const_defined?("BASE_PATH") Object.const_set :BASE_PATH, find_base! # read dot_base base_conf = IO.read(::BASE_PATH.join(DOT_BASE)).strip.gsub(/[ \t]/, '').gsub(/\n+/, "\n")\ .scan(/^\[(\w+)\]((?:\n[^\[].*)*)/)\ .inject(Hash.new('')) { |h, (k, s)| h[k.to_sym] = s.strip; h } base_conf.values.each { |s| s.gsub!(/\s*#.*\n/, "\n") } # set path consts k_order = [] # ruby 1.8 doesn't retain hash key order consts = base_conf[:consts].scan(/([A-Z][A-Z0-9_]*)=(.+)/).inject({}) { |h, (k, v)| k_order << k; h[k] = v; h } const_set :RX_CONSTS, /^(BASE_PATH|#{consts.keys.map(&Regexp.method(:escape)).join('|')})(?:\/|$)/ k_order.each { |k| Object.const_set(k, (consts[k])) } # set load_paths load_paths = base_conf[:load_paths].split("\n").map { |s| Dir[(s).to_s] }.flatten.select { |s| File.directory? s } $LOAD_PATH.unshift(*load_paths) # requires loaded = caller(0).map { |s| s.force_encoding(__ENCODING__)[/\A(.+?)(?:\.rb)?:\d+(?::in `.*?')?\z/, 1] }.compact.uniq globs, names = base_conf[:requires].split("\n").partition { |s| s =~ /\*/ } names.map! { |s| s, false }.concat \ globs.map { |s| Dir[(s).to_s + ".rb"] }\ .flatten.select { |s| File.file? s }.map { |s| s.sub(/\.rb$/, '') } names.each { |lib| require lib } # includes base_conf[:includes].split("\n").each { |k| Object.send :include, Object.const_get(k.strip) } end |