Class: Ready::Executable

Inherits:
Object
  • Object
show all
Defined in:
lib/ready/executable.rb

Overview

Resolves an executable name (gem-provided or on-disk) to a concrete path and renders its source with a process title prelude.

Defined Under Namespace

Classes: MultipleFilesError

Constant Summary collapse

GEM_BIN_OVERRIDES =

Executables whose gem name differs from the command, so path isn't a wall of one-off special cases.

{
  "bundle" => %w[bundler bundle],
  "ri" => %w[rdoc ri],
  "yri" => %w[yard yri],
  "rstore" => %w[reversal-store rstore],
  "rougify" => %w[rouge rougify],
}.freeze
SHEBANG_LINE =
/^.*#!.*\n/
REQUIRE_RELATIVE =
/(require_relative(?:\(| )\s*[\x27"]([^\s\x27"]+)[\x27"]\)?)/

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name) ⇒ Executable

Returns a new instance of Executable.



23
24
25
26
# File 'lib/ready/executable.rb', line 23

def initialize(name)
  @name = name
  @is_gem = !File.exist?(name)
end

Instance Attribute Details

#is_gemObject (readonly)

Returns the value of attribute is_gem.



8
9
10
# File 'lib/ready/executable.rb', line 8

def is_gem
  @is_gem
end

#nameObject (readonly)

Returns the value of attribute name.



8
9
10
# File 'lib/ready/executable.rb', line 8

def name
  @name
end

Instance Method Details

#convert_path_to_bin(path) ⇒ Object

"bin/" when the executable sits directly in a bin directory, else the bare basename. Anchored on the parent directory's name so a path like /home/robin/foo doesn't match "bin" as a substring.



31
32
33
34
# File 'lib/ready/executable.rb', line 31

def convert_path_to_bin(path)
  pathname = Pathname(path)
  pathname.dirname.basename.to_s == "bin" ? "bin/#{pathname.basename}" : pathname.basename
end

#pathObject



48
49
50
# File 'lib/ready/executable.rb', line 48

def path
  @path ||= @is_gem ? gem_executable_path : on_disk_path
end

#renderObject



36
37
38
39
40
41
42
43
44
45
46
# File 'lib/ready/executable.rb', line 36

def render
  stream = StringIO.new
  stream.puts
  stream.puts(
    <<~RUBY,
      Process.setproctitle #{name.inspect}
    RUBY
  )
  stream.puts(source)
  stream.string
end

#sourceObject



52
53
54
55
56
# File 'lib/ready/executable.rb', line 52

def source
  raise "No executable found for '#{@name}'" if path.nil?

  @source ||= rewrite_require_relative(File.read(path).gsub(SHEBANG_LINE, "").strip)
end