Class: ExecutablePathname

Inherits:
Pathname
  • Object
show all
Defined in:
lib/executable_pathname.rb,
lib/executable_pathname/version.rb

Constant Summary collapse

VERSION =
"1.0.0"

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path) ⇒ ExecutablePathname

Returns a new instance of ExecutablePathname.



37
38
39
40
41
# File 'lib/executable_pathname.rb', line 37

def initialize(path)
  super(path)
  @first_line = nil
  @shbang_paths = nil
end

Class Method Details

.path_listObject



29
30
31
# File 'lib/executable_pathname.rb', line 29

def self.path_list
  @@path_list ||= ENV['PATH'].split(':')
end

.remote_path_listObject



33
34
35
# File 'lib/executable_pathname.rb', line 33

def self.remote_path_list
  (ENV['REMOTE_PATH'] || '/bin:/usr/bin:/usr/local/bin').split(':')
end

.valid_executable?(name) ⇒ Boolean

Define the envar REMOTE_PATH as the colon-separated list of well-known directory paths that will be referenced on remote hosts. The default is ‘/bin:/usr/bin:/usr/local/bin’

Returns:

  • (Boolean)


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

def self.valid_executable?(name)
  case name
  when %r{^/}, %r{.+/.+}
    pn = new(name)
    return true if pn.valid_executable?
  else
    path_list.each do |dirname|
      pn = new(File.join(dirname, name))
      return true if pn.valid_executable?
    end
  end
  false
end

Instance Method Details

#env_shbang?Boolean

Returns:

  • (Boolean)


65
66
67
# File 'lib/executable_pathname.rb', line 65

def env_shbang?
  shbang_paths && shbang_paths.size > 1 && shbang_paths[0].end_with?('env')
end

#executable_file?Boolean

Returns:

  • (Boolean)


85
86
87
# File 'lib/executable_pathname.rb', line 85

def executable_file?
  exist? && file? && executable?
end

#first_lineObject



43
44
45
46
47
48
49
50
# File 'lib/executable_pathname.rb', line 43

def first_line
  @first_line ||= open { |io|
    line = io.gets
    line.chomp if line
  }
rescue Errno::ENOENT, Errno::EACCES, IOError
  nil
end

#invalid_shbang?Boolean

Returns:

  • (Boolean)


73
74
75
# File 'lib/executable_pathname.rb', line 73

def invalid_shbang?
  shbang? && (env_shbang? ? !valid_env_shbang? : !valid_shbang_command?)
end

#remove_execute_permissionsObject



98
99
100
# File 'lib/executable_pathname.rb', line 98

def remove_execute_permissions
  chmod(stat.mode & ~0111)
end

#shbang?Boolean

Returns:

  • (Boolean)


52
53
54
# File 'lib/executable_pathname.rb', line 52

def shbang?
  first_line && first_line[0..1] == '#!'
end

#shbang_pathsObject



56
57
58
59
60
61
62
63
# File 'lib/executable_pathname.rb', line 56

def shbang_paths
  @shbang_paths ||= first_line &&
    case first_line
    when /^#!\s*(\S+)\s+(\S+.)/ then [$1, $2.chomp]
    when /^#!\s*(\S+)/          then [$1.chomp]
    else []
    end
end

#valid_env_shbang?Boolean

Returns:

  • (Boolean)


77
78
79
# File 'lib/executable_pathname.rb', line 77

def valid_env_shbang?
  env_shbang? && valid_shbang_command? && shbang_paths.last.split('/').size == 1
end

#valid_executable?Boolean

Returns:

  • (Boolean)


89
90
91
# File 'lib/executable_pathname.rb', line 89

def valid_executable?
  exist? && executable_file? && (!shbang? || valid_shbang?)
end

#valid_shbang?Boolean

Returns:

  • (Boolean)


69
70
71
# File 'lib/executable_pathname.rb', line 69

def valid_shbang?
  shbang? && (env_shbang? ? valid_env_shbang? : valid_shbang_command?)
end

#valid_shbang_command?Boolean

Returns:

  • (Boolean)


81
82
83
# File 'lib/executable_pathname.rb', line 81

def valid_shbang_command?
  shbang_paths.size > 0 && ExecutablePathname.valid_executable?(shbang_paths[0])
end

#well_known_path?Boolean

Returns:

  • (Boolean)


93
94
95
96
# File 'lib/executable_pathname.rb', line 93

def well_known_path?
  return false unless exist?
  ExecutablePathname.remote_path_list.any? {|rp| (shbang? ? shbang_paths.first : to_path).start_with?(rp)}
end