Module: Bahia

Defined in:
lib/bahia.rb

Defined Under Namespace

Classes: DetectionError

Constant Summary collapse

VERSION =
'0.7.2'

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.commandObject

Returns the value of attribute command.



13
14
15
# File 'lib/bahia.rb', line 13

def command
  @command
end

.command_methodObject

Returns the value of attribute command_method.



13
14
15
# File 'lib/bahia.rb', line 13

def command_method
  @command_method
end

.project_directoryObject

Returns the value of attribute project_directory.



13
14
15
# File 'lib/bahia.rb', line 13

def project_directory
  @project_directory
end

Instance Attribute Details

#processObject (readonly)

Returns the value of attribute process.



14
15
16
# File 'lib/bahia.rb', line 14

def process
  @process
end

#stderrObject (readonly)

Returns the value of attribute stderr.



14
15
16
# File 'lib/bahia.rb', line 14

def stderr
  @stderr
end

#stdoutObject (readonly)

Returns the value of attribute stdout.



14
15
16
# File 'lib/bahia.rb', line 14

def stdout
  @stdout
end

Class Method Details

.exec_command(*args) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/bahia.rb', line 39

def self.exec_command(*args)
  unless RUBY_DESCRIPTION[/rubinius|jruby|ruby 1\.8\.7/]
    return Open3.capture3(*args)
  end

  args.shift.each {|k,v| ENV[k] = v }

  if RUBY_DESCRIPTION[/jruby/]
    i, o, e = IO.popen3(*args)
    stdout, stderr = read_and_close(i, o, e)
    # status not supported until Open3 actually works
    [stdout, stderr, nil]
  else
    require 'open4'
    pid, stdin, stdout, stderr = Open4.open4(*args)
    _, status = Process.wait2(pid)
    out, err = read_and_close(stdin, stdout, stderr)
    [out, err, status]
  end
end

.included(mod) ⇒ Object



16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/bahia.rb', line 16

def self.included(mod)
  self.project_directory ||= set_project_directory(caller)
  self.command ||= Dir[self.project_directory + '/bin/*'][0] or
    raise DetectionError.new(:command)
  self.command_method ||= File.basename(command)

  # We want only want one optional arg, thank 1.8.7 for the splat
  define_method(command_method) do |*cmd|
    @stdout, @stderr, @process = Bahia.run_command(cmd.shift || '')
  end
rescue DetectionError => err
  msg = "bahia: #{err}"
  abort "\n" + "*" * msg.size + "\n#{msg}\n" + "*" * msg.size + "\n\n"
end

.run_command(cmd) ⇒ Object



31
32
33
34
35
36
37
# File 'lib/bahia.rb', line 31

def self.run_command(cmd)
  args = Shellwords.split(cmd)
  args.unshift Bahia.command
  args.unshift('RUBYLIB' =>
   "#{Bahia.project_directory}/lib:#{ENV['RUBYLIB']}".sub(/:\s*$/, ''))
  exec_command *args
end

.set_project_directory(arr) ⇒ Object

Raises:



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/bahia.rb', line 60

def self.set_project_directory(arr)
  # get rid of rspec backtrace
  arr = arr.drop_while {|e| e[/rspec/] } if arr[0][/rspec/]
  arr[0][/^([^:]+):\d+/] or raise DetectionError.new(:project_directory)
  file = $1
  raise DetectionError.new(:project_directory) unless File.exists?(file)

  dir = File.dirname(file)
  # Look for bin or test directory called spec or test
  until dir[%r{/(bin|spec|test)$}]
    raise DetectionError.new(:project_directory) if dir == '/'
    dir = File.dirname(dir)
  end
  File.dirname dir
end