wijet-launchy 2.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/HISTORY +111 -0
- data/LICENSE +16 -0
- data/NOTES +1 -0
- data/README +100 -0
- data/Rakefile +70 -0
- data/bin/launchy +4 -0
- data/lib/launchy.rb +115 -0
- data/lib/launchy/application.rb +62 -0
- data/lib/launchy/applications/browser.rb +79 -0
- data/lib/launchy/cli.rb +83 -0
- data/lib/launchy/deprecated.rb +52 -0
- data/lib/launchy/descendant_tracker.rb +49 -0
- data/lib/launchy/detect.rb +10 -0
- data/lib/launchy/detect/host_os.rb +31 -0
- data/lib/launchy/detect/host_os_family.rb +71 -0
- data/lib/launchy/detect/nix_desktop_environment.rb +60 -0
- data/lib/launchy/detect/ruby_engine.rb +78 -0
- data/lib/launchy/detect/runner.rb +111 -0
- data/lib/launchy/error.rb +4 -0
- data/lib/launchy/os_family.rb +8 -0
- data/lib/launchy/version.rb +18 -0
- data/spec/application_spec.rb +43 -0
- data/spec/applications/browser_spec.rb +54 -0
- data/spec/cli_spec.rb +75 -0
- data/spec/detect/host_os_family_spec.rb +40 -0
- data/spec/detect/host_os_spec.rb +19 -0
- data/spec/detect/nix_desktop_environment_spec.rb +33 -0
- data/spec/detect/ruby_engine_spec.rb +37 -0
- data/spec/detect/runner_spec.rb +98 -0
- data/spec/launchy_spec.rb +58 -0
- data/spec/mock_application.rb +9 -0
- data/spec/spec_helper.rb +5 -0
- data/spec/tattle-host-os.yaml +427 -0
- data/spec/version_spec.rb +11 -0
- data/tasks/bundler.rake +13 -0
- data/tasks/contribute.rake +36 -0
- metadata +200 -0
@@ -0,0 +1,79 @@
|
|
1
|
+
class Launchy::Application
|
2
|
+
#
|
3
|
+
# The class handling the browser application and all of its schemes
|
4
|
+
#
|
5
|
+
class Browser < Launchy::Application
|
6
|
+
def self.schemes
|
7
|
+
%w[ http https ftp file ]
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.handles?( uri )
|
11
|
+
return true if schemes.include?( uri.scheme )
|
12
|
+
return true if File.exist?( uri.path )
|
13
|
+
end
|
14
|
+
|
15
|
+
def windows_app_list
|
16
|
+
[ 'start /b' ]
|
17
|
+
end
|
18
|
+
|
19
|
+
def cygwin_app_list
|
20
|
+
[ 'cmd /C start /b' ]
|
21
|
+
end
|
22
|
+
|
23
|
+
def darwin_app_list
|
24
|
+
[ find_executable( "open" ) ]
|
25
|
+
end
|
26
|
+
|
27
|
+
def nix_app_list
|
28
|
+
app_list = %w[ xdg-open ]
|
29
|
+
if nix_de = Launchy::Detect::NixDesktopEnvironment.detect then
|
30
|
+
app_list << nix_de.browser
|
31
|
+
app_list << nix_de.fallback_browsers
|
32
|
+
end
|
33
|
+
app_list.flatten!
|
34
|
+
app_list.delete_if { |b| b.nil? || (b.strip.size == 0) }
|
35
|
+
app_list.collect { |bin| find_executable( bin ) }.find_all { |x| not x.nil? }
|
36
|
+
end
|
37
|
+
|
38
|
+
# use a call back mechanism to get the right app_list that is decided by the
|
39
|
+
# host_os_family class.
|
40
|
+
def app_list
|
41
|
+
host_os_family.app_list( self )
|
42
|
+
end
|
43
|
+
|
44
|
+
def browser_env
|
45
|
+
return [] unless ENV['BROWSER']
|
46
|
+
browser_env = ENV['BROWSER'].split( File::PATH_SEPARATOR )
|
47
|
+
browser_env.flatten!
|
48
|
+
browser_env.delete_if { |b| b.nil? || (b.strip.size == 0) }
|
49
|
+
return browser_env
|
50
|
+
end
|
51
|
+
|
52
|
+
# Get the full commandline of what we are going to add the uri to
|
53
|
+
def browser_cmdline
|
54
|
+
possibilities = (browser_env + app_list).flatten
|
55
|
+
possibilities.each do |p|
|
56
|
+
Launchy.log "#{self.class.name} : possibility : #{p}"
|
57
|
+
end
|
58
|
+
browser = possibilities.shift
|
59
|
+
Launchy.log "#{self.class.name} : Using browser value '#{browser}'"
|
60
|
+
return browser
|
61
|
+
end
|
62
|
+
|
63
|
+
def cmd_and_args( uri, options = {} )
|
64
|
+
cmd = browser_cmdline
|
65
|
+
args = [ uri.to_s ]
|
66
|
+
if cmd =~ /%s/ then
|
67
|
+
cmd.gsub!( /%s/, args.shift )
|
68
|
+
end
|
69
|
+
return [cmd, args]
|
70
|
+
end
|
71
|
+
|
72
|
+
# final assembly of the command and do %s substitution
|
73
|
+
# http://www.catb.org/~esr/BROWSER/index.html
|
74
|
+
def open( uri, options = {} )
|
75
|
+
cmd, args = cmd_and_args( uri, options )
|
76
|
+
run( cmd, args )
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
data/lib/launchy/cli.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
module Launchy
|
4
|
+
class Cli
|
5
|
+
|
6
|
+
attr_reader :options
|
7
|
+
def initialize
|
8
|
+
@options = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def parser
|
12
|
+
@parser ||= OptionParser.new do |op|
|
13
|
+
op.banner = "Usage: launchy [options] thing-to-launch"
|
14
|
+
|
15
|
+
op.separator ""
|
16
|
+
op.separator "Launch Options:"
|
17
|
+
|
18
|
+
op.on( "-a", "--application APPLICATION",
|
19
|
+
"Explicitly specify the application class to use in the launch") do |app|
|
20
|
+
@options[:application] = app
|
21
|
+
end
|
22
|
+
|
23
|
+
op.on( "-d", "--debug",
|
24
|
+
"Force debug. Output lots of information.") do |d|
|
25
|
+
@options[:debug] = 'true'
|
26
|
+
end
|
27
|
+
|
28
|
+
op.on( "-e", "--engine RUBY_ENGINE",
|
29
|
+
"Force launchy to behave as if it was on a particular ruby engine.") do |e|
|
30
|
+
@options[:ruby_engine] = e
|
31
|
+
end
|
32
|
+
|
33
|
+
op.on( "-n", "--dry-run", "Don't launchy, print the command to be executed on stdout" ) do |x|
|
34
|
+
@options[:dry_run] = true
|
35
|
+
end
|
36
|
+
|
37
|
+
op.on( "-o", "--host-os HOST_OS",
|
38
|
+
"Force launchy to behave as if it was on a particular host os.") do |os|
|
39
|
+
@options[:host_os] = os
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
op.separator ""
|
44
|
+
op.separator "Standard Options:"
|
45
|
+
|
46
|
+
op.on( "-h", "--help", "Print this message.") do |h|
|
47
|
+
$stdout.puts op.to_s
|
48
|
+
exit 0
|
49
|
+
end
|
50
|
+
|
51
|
+
op.on( "-v", "--version", "Output the version of Launchy") do |v|
|
52
|
+
$stdout.puts "Launchy version #{Launchy::VERSION}"
|
53
|
+
exit 0
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def parse( argv, env )
|
60
|
+
begin
|
61
|
+
parser.parse!( argv )
|
62
|
+
return true
|
63
|
+
rescue ::OptionParser::ParseError => pe
|
64
|
+
$stderr.puts "#{parser.program_name}: #{pe}"
|
65
|
+
$stderr.puts "Try `#{parser.program_name} --help for more information."
|
66
|
+
return false
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def good_run( argv, env )
|
71
|
+
if parse( argv, env ) then
|
72
|
+
Launchy.open( argv.shift, options )
|
73
|
+
return true
|
74
|
+
else
|
75
|
+
return false
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def run( argv = ARGV, env = ENV )
|
80
|
+
exit 1 unless good_run( argv, env )
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Launchy
|
2
|
+
#
|
3
|
+
# This class is deprecated and will be removed
|
4
|
+
#
|
5
|
+
class Browser
|
6
|
+
def self.run( *args )
|
7
|
+
Browser.new.visit( args[0] )
|
8
|
+
end
|
9
|
+
|
10
|
+
def visit( url )
|
11
|
+
_warn "You made a call to a deprecated Launchy API. This call should be changed to 'Launchy.open( uri )'"
|
12
|
+
report_caller_context( caller )
|
13
|
+
|
14
|
+
::Launchy.open( url )
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def find_caller_context( stack )
|
20
|
+
caller_file = stack.find do |line|
|
21
|
+
not line.index( __FILE__ )
|
22
|
+
end
|
23
|
+
if caller_file then
|
24
|
+
caller_fname, caller_line, _ = caller_file.split(":")
|
25
|
+
if File.readable?( caller_fname ) then
|
26
|
+
caller_lines = IO.readlines( caller_fname )
|
27
|
+
context = [ caller_file ]
|
28
|
+
context << caller_lines[(caller_line.to_i)-3, 5]
|
29
|
+
return context.flatten
|
30
|
+
end
|
31
|
+
end
|
32
|
+
return []
|
33
|
+
end
|
34
|
+
|
35
|
+
def report_caller_context( stack )
|
36
|
+
context = find_caller_context( stack )
|
37
|
+
if context.size > 0 then
|
38
|
+
_warn "I think I was able to find the location that needs to be fixed. Please go look at:"
|
39
|
+
_warn
|
40
|
+
context.each do |line|
|
41
|
+
_warn line.rstrip
|
42
|
+
end
|
43
|
+
_warn
|
44
|
+
_warn "If this is not the case, please file a bug. #{Launchy.bug_report_message}"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def _warn( msg = "" )
|
49
|
+
warn "WARNING: #{msg}"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
3
|
+
module Launchy
|
4
|
+
#
|
5
|
+
# Use by either
|
6
|
+
#
|
7
|
+
# class Foo
|
8
|
+
# extend DescendantTracker
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
# or
|
12
|
+
#
|
13
|
+
# class Foo
|
14
|
+
# class << self
|
15
|
+
# include DescendantTracker
|
16
|
+
# end
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# It will track all the classes that inherit from the extended class and keep
|
20
|
+
# them in a Set that is available via the 'children' method.
|
21
|
+
#
|
22
|
+
module DescendantTracker
|
23
|
+
def inherited( klass )
|
24
|
+
return unless klass.instance_of?( Class )
|
25
|
+
self.children << klass
|
26
|
+
end
|
27
|
+
|
28
|
+
#
|
29
|
+
# The list of children that are registered
|
30
|
+
#
|
31
|
+
def children
|
32
|
+
unless defined? @children
|
33
|
+
@children = Set.new
|
34
|
+
end
|
35
|
+
return @children
|
36
|
+
end
|
37
|
+
|
38
|
+
#
|
39
|
+
# Find one of the child classes by calling the given method
|
40
|
+
# and passing all the rest of the parameters to that method in
|
41
|
+
# each child
|
42
|
+
def find_child( method, *args )
|
43
|
+
klass = children.find do |child|
|
44
|
+
Launchy.log "Checking if class #{child} is the one for #{method}(#{args.join(', ')})}"
|
45
|
+
child.send( method, *args )
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'rbconfig'
|
2
|
+
|
3
|
+
module Launchy::Detect
|
4
|
+
class HostOs
|
5
|
+
|
6
|
+
attr_reader :host_os
|
7
|
+
alias to_s host_os
|
8
|
+
|
9
|
+
def initialize( host_os = nil )
|
10
|
+
@host_os = host_os
|
11
|
+
|
12
|
+
if not @host_os then
|
13
|
+
if @host_os = override_host_os then
|
14
|
+
Launchy.log "Using LAUNCHY_HOST_OS override value of '#{Launchy.host_os}'"
|
15
|
+
else
|
16
|
+
@host_os = default_host_os
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def default_host_os
|
22
|
+
::RbConfig::CONFIG['host_os']
|
23
|
+
end
|
24
|
+
|
25
|
+
def override_host_os
|
26
|
+
Launchy.host_os
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Launchy::Detect
|
2
|
+
# Detect the current host os family
|
3
|
+
#
|
4
|
+
# If the current host familiy cannot be detected then return
|
5
|
+
# HostOsFamily::Unknown
|
6
|
+
class HostOsFamily
|
7
|
+
class NotFoundError < Launchy::Error; end
|
8
|
+
extend ::Launchy::DescendantTracker
|
9
|
+
|
10
|
+
class << self
|
11
|
+
|
12
|
+
def detect( host_os = HostOs.new )
|
13
|
+
found = find_child( :matches?, host_os )
|
14
|
+
return found.new( host_os ) if found
|
15
|
+
raise NotFoundError, "Unknown OS family for host os '#{host_os}'. #{Launchy.bug_report_message}"
|
16
|
+
end
|
17
|
+
|
18
|
+
def matches?( host_os )
|
19
|
+
matching_regex.match( host_os.to_s )
|
20
|
+
end
|
21
|
+
|
22
|
+
def windows?() self == Windows; end
|
23
|
+
def darwin?() self == Darwin; end
|
24
|
+
def nix?() self == Nix; end
|
25
|
+
def cygwin?() self == Cygwin; end
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
attr_reader :host_os
|
30
|
+
def initialize( host_os = HostOs.new )
|
31
|
+
@host_os = host_os
|
32
|
+
end
|
33
|
+
|
34
|
+
def windows?() self.class.windows?; end
|
35
|
+
def darwin?() self.class.darwin?; end
|
36
|
+
def nix?() self.class.nix?; end
|
37
|
+
def cygwin?() self.class.cygwin?; end
|
38
|
+
|
39
|
+
#---------------------------
|
40
|
+
# All known host os families
|
41
|
+
#---------------------------
|
42
|
+
#
|
43
|
+
class Windows < HostOsFamily
|
44
|
+
def self.matching_regex
|
45
|
+
/(mingw|mswin|windows)/i
|
46
|
+
end
|
47
|
+
def app_list( app ) app.windows_app_list; end
|
48
|
+
end
|
49
|
+
|
50
|
+
class Darwin < HostOsFamily
|
51
|
+
def self.matching_regex
|
52
|
+
/(darwin|mac os)/i
|
53
|
+
end
|
54
|
+
def app_list( app ) app.darwin_app_list; end
|
55
|
+
end
|
56
|
+
|
57
|
+
class Nix < HostOsFamily
|
58
|
+
def self.matching_regex
|
59
|
+
/(linux|bsd|aix|solaris)/i
|
60
|
+
end
|
61
|
+
def app_list( app ) app.nix_app_list; end
|
62
|
+
end
|
63
|
+
|
64
|
+
class Cygwin < HostOsFamily
|
65
|
+
def self.matching_regex
|
66
|
+
/cygwin/i
|
67
|
+
end
|
68
|
+
def app_list( app ) app.cygwin_app_list; end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Launchy::Detect
|
2
|
+
#
|
3
|
+
# Detect the current desktop environment for *nix machines
|
4
|
+
# Currently this is Linux centric. The detection is based upon the detection
|
5
|
+
# used by xdg-open from http://portland.freedesktop.org/wiki/XdgUtils
|
6
|
+
class NixDesktopEnvironment
|
7
|
+
class NotFoundError < Launchy::Error; end
|
8
|
+
|
9
|
+
extend ::Launchy::DescendantTracker
|
10
|
+
|
11
|
+
# Detect the current *nix desktop environment
|
12
|
+
#
|
13
|
+
# If the current dekstop environment be detected, the return
|
14
|
+
# NixDekstopEnvironment::Unknown
|
15
|
+
def self.detect
|
16
|
+
found = find_child( :is_current_desktop_environment? )
|
17
|
+
Launchy.log("Current Desktop environment not flound. #{Launchy.bug_report_message}") unless found
|
18
|
+
return found
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.fallback_browsers
|
22
|
+
%w[ firefox seamonkey opera mozilla netscape galeon ]
|
23
|
+
end
|
24
|
+
|
25
|
+
#---------------------------------------
|
26
|
+
# The list of known desktop environments
|
27
|
+
#---------------------------------------
|
28
|
+
|
29
|
+
class Kde < NixDesktopEnvironment
|
30
|
+
def self.is_current_desktop_environment?
|
31
|
+
ENV['KDE_FULL_SESSION']
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.browser
|
35
|
+
'kfmclient'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class Gnome < NixDesktopEnvironment
|
40
|
+
def self.is_current_desktop_environment?
|
41
|
+
ENV['GNOME_DESKTOP_SESSION_ID']
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.browser
|
45
|
+
'gnome-open'
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
class Xfce < NixDesktopEnvironment
|
50
|
+
def self.is_current_desktop_environment?
|
51
|
+
%x[ xprop -root _DT_SAVE_MODE | grep ' = \"xfce\"$' ].strip.size > 0
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.browser
|
55
|
+
'exo-open'
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module Launchy::Detect
|
2
|
+
class RubyEngine
|
3
|
+
class NotFoundError < Launchy::Error; end
|
4
|
+
|
5
|
+
extend ::Launchy::DescendantTracker
|
6
|
+
|
7
|
+
# Detect the current ruby engine.
|
8
|
+
#
|
9
|
+
# If the current ruby engine cannot be detected, the return
|
10
|
+
# RubyEngine::Unknown
|
11
|
+
def self.detect( ruby_engine = RubyEngine.new )
|
12
|
+
found = find_child( :is_current_engine?, ruby_engine.to_s )
|
13
|
+
return found if found
|
14
|
+
raise NotFoundError, "#{ruby_engine_error_message( ruby_engine )} #{Launchy.bug_report_message}"
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.ruby_engine_error_message( ruby_engine )
|
18
|
+
msg = "Unkonwn RUBY_ENGINE "
|
19
|
+
if ruby_engine then
|
20
|
+
msg += " '#{ruby_engine}'."
|
21
|
+
elsif defined?( RUBY_ENGINE ) then
|
22
|
+
msg += " '#{RUBY_ENGINE}'."
|
23
|
+
else
|
24
|
+
msg = "RUBY_ENGINE not defined for #{RUBY_DESCRIPTION}."
|
25
|
+
end
|
26
|
+
return msg
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.is_current_engine?( ruby_engine )
|
30
|
+
return ruby_engine == self.engine_name
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.mri?() self == Mri; end
|
34
|
+
def self.jruby?() self == Jruby; end
|
35
|
+
def self.rbx?() self == Rbx; end
|
36
|
+
def self.macruby?() self == MacRuby; end
|
37
|
+
|
38
|
+
attr_reader :ruby_engine
|
39
|
+
alias to_s ruby_engine
|
40
|
+
def initialize( ruby_engine = Launchy.ruby_engine )
|
41
|
+
if ruby_engine then
|
42
|
+
@ruby_engine = ruby_engine
|
43
|
+
else
|
44
|
+
@ruby_engine = defined?( RUBY_ENGINE ) ? RUBY_ENGINE : "ruby"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
#-------------------------------
|
50
|
+
# The list of known ruby engines
|
51
|
+
#-------------------------------
|
52
|
+
|
53
|
+
#
|
54
|
+
# This is the ruby engine if the RUBY_ENGINE constant is not defined
|
55
|
+
class Mri < RubyEngine
|
56
|
+
def self.engine_name() "ruby"; end
|
57
|
+
def self.is_current_engine?( ruby_engine )
|
58
|
+
if ruby_engine then
|
59
|
+
super( ruby_engine )
|
60
|
+
else
|
61
|
+
return true if not Launchy.ruby_engine and not defined?( RUBY_ENGINE )
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class Jruby < RubyEngine
|
67
|
+
def self.engine_name() "jruby"; end
|
68
|
+
end
|
69
|
+
|
70
|
+
class Rbx < RubyEngine
|
71
|
+
def self.engine_name() "rbx"; end
|
72
|
+
end
|
73
|
+
|
74
|
+
class MacRuby < RubyEngine
|
75
|
+
def self.engine_name() "macruby"; end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|