launchy 2.5.0 → 3.0.1

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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +1 -0
  3. data/HISTORY.md +38 -20
  4. data/{LICENSE → LICENSE.txt} +1 -1
  5. data/Manifest.txt +4 -21
  6. data/README.md +10 -47
  7. data/exe/launchy +5 -0
  8. data/launchy.gemspec +32 -0
  9. data/lib/launchy/application.rb +38 -20
  10. data/lib/launchy/applications/browser.rb +68 -63
  11. data/lib/launchy/argv.rb +11 -6
  12. data/lib/launchy/cli.rb +29 -34
  13. data/lib/launchy/descendant_tracker.rb +14 -12
  14. data/lib/launchy/detect/host_os.rb +21 -18
  15. data/lib/launchy/detect/host_os_family.rb +94 -53
  16. data/lib/launchy/detect/nix_desktop_environment.rb +74 -69
  17. data/lib/launchy/detect.rb +7 -5
  18. data/lib/launchy/error.rb +2 -0
  19. data/lib/launchy/os_family.rb +2 -0
  20. data/lib/launchy/runner.rb +54 -0
  21. data/lib/launchy/version.rb +7 -5
  22. data/lib/launchy.rb +76 -68
  23. metadata +22 -93
  24. data/Rakefile +0 -27
  25. data/bin/launchy +0 -4
  26. data/lib/launchy/deprecated.rb +0 -52
  27. data/lib/launchy/detect/ruby_engine.rb +0 -78
  28. data/lib/launchy/detect/runner.rb +0 -152
  29. data/spec/application_spec.rb +0 -43
  30. data/spec/applications/browser_spec.rb +0 -78
  31. data/spec/cli_spec.rb +0 -75
  32. data/spec/detect/host_os_family_spec.rb +0 -42
  33. data/spec/detect/host_os_spec.rb +0 -19
  34. data/spec/detect/nix_desktop_environment_spec.rb +0 -27
  35. data/spec/detect/ruby_engine_spec.rb +0 -37
  36. data/spec/detect/runner_spec.rb +0 -103
  37. data/spec/launchy_spec.rb +0 -119
  38. data/spec/mock_application.rb +0 -9
  39. data/spec/spec_helper.rb +0 -11
  40. data/spec/tattle-host-os.yaml +0 -427
  41. data/spec/version_spec.rb +0 -11
  42. data/tasks/default.rake +0 -242
  43. data/tasks/this.rb +0 -208
data/lib/launchy/cli.rb CHANGED
@@ -1,9 +1,13 @@
1
- require 'optparse'
1
+ # frozen_string_literal: true
2
+
3
+ require "optparse"
2
4
 
3
5
  module Launchy
6
+ # Internal: Command line interface for Launchy
7
+ #
4
8
  class Cli
5
-
6
9
  attr_reader :options
10
+
7
11
  def initialize
8
12
  @options = {}
9
13
  end
@@ -15,75 +19,66 @@ module Launchy
15
19
  op.separator ""
16
20
  op.separator "Launch Options:"
17
21
 
18
- op.on( "-a", "--application APPLICATION",
19
- "Explicitly specify the application class to use in the launch") do |app|
22
+ op.on("-a", "--application APPLICATION",
23
+ "Explicitly specify the application class to use in the launch") do |app|
20
24
  @options[:application] = app
21
25
  end
22
26
 
23
- op.on( "-d", "--debug",
24
- "Force debug. Output lots of information.") do |d|
27
+ op.on("-d", "--debug",
28
+ "Force debug. Output lots of information.") do |_d|
25
29
  @options[:debug] = true
26
30
  end
27
31
 
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|
32
+ op.on("-n", "--dry-run", "Don't launchy, print the command to be executed on stdout") do |_x|
34
33
  @options[:dry_run] = true
35
34
  end
36
35
 
37
- op.on( "-o", "--host-os HOST_OS",
38
- "Force launchy to behave as if it was on a particular host os.") do |os|
36
+ op.on("-o", "--host-os HOST_OS",
37
+ "Force launchy to behave as if it was on a particular host os.") do |os|
39
38
  @options[:host_os] = os
40
39
  end
41
40
 
42
-
43
41
  op.separator ""
44
42
  op.separator "Standard Options:"
45
43
 
46
- op.on( "-h", "--help", "Print this message.") do |h|
44
+ op.on("-h", "--help", "Print this message.") do |_h|
47
45
  $stdout.puts op.to_s
48
46
  exit 0
49
47
  end
50
48
 
51
- op.on( "-v", "--version", "Output the version of Launchy") do |v|
49
+ op.on("-v", "--version", "Output the version of Launchy") do |_v|
52
50
  $stdout.puts "Launchy version #{Launchy::VERSION}"
53
51
  exit 0
54
52
  end
55
-
56
53
  end
57
54
  end
58
55
 
59
- def parse( argv, env )
60
- parser.parse!( argv )
61
- return true
62
- rescue ::OptionParser::ParseError => pe
63
- error_output( pe )
56
+ def parse(argv, _env)
57
+ parser.parse!(argv)
58
+ true
59
+ rescue ::OptionParser::ParseError => e
60
+ error_output(e)
64
61
  end
65
62
 
66
- def good_run( argv, env )
67
- if parse( argv, env ) then
68
- Launchy.open( argv.shift, options ) { |e| error_output( e ) }
69
- return true
70
- else
71
- return false
72
- end
63
+ def good_run(argv, env)
64
+ return false unless parse(argv, env)
65
+
66
+ Launchy.open(argv.shift, options) { |e| error_output(e) }
67
+ true
73
68
  end
74
69
 
75
- def error_output( error )
70
+ def error_output(error)
76
71
  $stderr.puts "ERROR: #{error}"
77
72
  Launchy.log "ERROR: #{error}"
78
73
  error.backtrace.each do |bt|
79
74
  Launchy.log bt
80
75
  end
81
76
  $stderr.puts "Try `#{parser.program_name} --help' for more information."
82
- return false
77
+ false
83
78
  end
84
79
 
85
- def run( argv = ARGV, env = ENV )
86
- exit 1 unless good_run( argv, env )
80
+ def run(argv = ARGV, env = ENV)
81
+ exit 1 unless good_run(argv, env)
87
82
  end
88
83
  end
89
84
  end
@@ -1,4 +1,6 @@
1
- require 'set'
1
+ # frozen_string_literal: true
2
+
3
+ require "set"
2
4
 
3
5
  module Launchy
4
6
  #
@@ -9,7 +11,7 @@ module Launchy
9
11
  # end
10
12
  #
11
13
  # or
12
- #
14
+ #
13
15
  # class Foo
14
16
  # class << self
15
17
  # include DescendantTracker
@@ -20,29 +22,29 @@ module Launchy
20
22
  # them in a Set that is available via the 'children' method.
21
23
  #
22
24
  module DescendantTracker
23
- def inherited( klass )
24
- return unless klass.instance_of?( Class )
25
- self.children << klass
25
+ def inherited(klass)
26
+ super
27
+ return unless klass.instance_of?(Class)
28
+
29
+ children << klass
26
30
  end
27
31
 
28
32
  #
29
33
  # The list of children that are registered
30
34
  #
31
35
  def children
32
- unless defined? @children
33
- @children = Array.new
34
- end
35
- return @children
36
+ @children = [] unless defined? @children
37
+ @children
36
38
  end
37
39
 
38
40
  #
39
41
  # Find one of the child classes by calling the given method
40
- # and passing all the rest of the parameters to that method in
42
+ # and passing all the rest of the parameters to that method in
41
43
  # each child
42
- def find_child( method, *args )
44
+ def find_child(method, *args)
43
45
  children.find do |child|
44
46
  Launchy.log "Checking if class #{child} is the one for #{method}(#{args.join(', ')})}"
45
- child.send( method, *args )
47
+ child.send(method, *args)
46
48
  end
47
49
  end
48
50
  end
@@ -1,32 +1,35 @@
1
- require 'rbconfig'
1
+ # frozen_string_literal: true
2
2
 
3
- module Launchy::Detect
4
- class HostOs
3
+ require "rbconfig"
5
4
 
6
- attr_reader :host_os
7
- alias to_s host_os
8
- alias to_str host_os
5
+ module Launchy
6
+ module Detect
7
+ # Internal: Determine the host operating system that Launchy is running on
8
+ #
9
+ class HostOs
10
+ attr_reader :host_os
11
+ alias to_s host_os
12
+ alias to_str host_os
9
13
 
10
- def initialize( host_os = nil )
11
- @host_os = host_os
14
+ def initialize(host_os = nil)
15
+ @host_os = host_os
12
16
 
13
- if not @host_os then
14
- if @host_os = override_host_os then
17
+ return if @host_os
18
+
19
+ if (@host_os = override_host_os)
15
20
  Launchy.log "Using LAUNCHY_HOST_OS override value of '#{Launchy.host_os}'"
16
21
  else
17
22
  @host_os = default_host_os
18
23
  end
19
24
  end
20
- end
21
25
 
22
- def default_host_os
23
- ::RbConfig::CONFIG['host_os']
24
- end
26
+ def default_host_os
27
+ ::RbConfig::CONFIG["host_os"].downcase
28
+ end
25
29
 
26
- def override_host_os
27
- Launchy.host_os
30
+ def override_host_os
31
+ Launchy.host_os
32
+ end
28
33
  end
29
-
30
34
  end
31
-
32
35
  end
@@ -1,71 +1,112 @@
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}"
1
+ # frozen_string_literal: true
2
+
3
+ module Launchy
4
+ module Detect
5
+ # Detect the current host os family
6
+ #
7
+ # If the current host familiy cannot be detected then return
8
+ # HostOsFamily::Unknown
9
+ class HostOsFamily
10
+ class NotFoundError < Launchy::Error; end
11
+ extend ::Launchy::DescendantTracker
12
+
13
+ class << self
14
+ def detect(host_os = HostOs.new)
15
+ found = find_child(:matches?, host_os)
16
+ return found.new(host_os) if found
17
+
18
+ raise NotFoundError, "Unknown OS family for host os '#{host_os}'. #{Launchy.bug_report_message}"
19
+ end
20
+
21
+ def matches?(host_os)
22
+ matching_regex.match(host_os.to_s)
23
+ end
24
+
25
+ def windows?
26
+ self == Windows
27
+ end
28
+
29
+ def darwin?
30
+ self == Darwin
31
+ end
32
+
33
+ def nix?
34
+ self == Nix
35
+ end
36
+
37
+ def cygwin?
38
+ self == Cygwin
39
+ end
16
40
  end
17
41
 
18
- def matches?( host_os )
19
- matching_regex.match( host_os.to_s )
42
+ attr_reader :host_os
43
+
44
+ def initialize(host_os = HostOs.new)
45
+ @host_os = host_os
20
46
  end
21
47
 
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
48
+ def windows?
49
+ self.class.windows?
50
+ end
27
51
 
52
+ def darwin?
53
+ self.class.darwin?
54
+ end
28
55
 
29
- attr_reader :host_os
30
- def initialize( host_os = HostOs.new )
31
- @host_os = host_os
32
- end
56
+ def nix?
57
+ self.class.nix?
58
+ end
33
59
 
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
60
+ def cygwin?
61
+ self.class.cygwin?
62
+ end
38
63
 
39
- #---------------------------
40
- # All known host os families
41
- #---------------------------
42
- #
43
- class Windows < HostOsFamily
44
- def self.matching_regex
45
- /(mingw|mswin|windows)/i
64
+ #---------------------------
65
+ # All known host os families
66
+ #---------------------------
67
+ #
68
+ class Windows < HostOsFamily
69
+ def self.matching_regex
70
+ /(mingw|mswin|msys|windows)/i
71
+ end
72
+
73
+ def app_list(app)
74
+ app.windows_app_list
75
+ end
46
76
  end
47
- def app_list( app ) app.windows_app_list; end
48
- end
49
77
 
50
- class Darwin < HostOsFamily
51
- def self.matching_regex
52
- /(darwin|mac os)/i
78
+ # Mac OS X family
79
+ class Darwin < HostOsFamily
80
+ def self.matching_regex
81
+ /(darwin|mac os)/i
82
+ end
83
+
84
+ def app_list(app)
85
+ app.darwin_app_list
86
+ end
53
87
  end
54
- def app_list( app ) app.darwin_app_list; end
55
- end
56
88
 
57
- class Nix < HostOsFamily
58
- def self.matching_regex
59
- /(linux|bsd|aix|solaris)/i
89
+ # All the *nix family of operating systems, and BSDs
90
+ class Nix < HostOsFamily
91
+ def self.matching_regex
92
+ /(linux|bsd|aix|solaris|sunos|dragonfly)/i
93
+ end
94
+
95
+ def app_list(app)
96
+ app.nix_app_list
97
+ end
60
98
  end
61
- def app_list( app ) app.nix_app_list; end
62
- end
63
99
 
64
- class Cygwin < HostOsFamily
65
- def self.matching_regex
66
- /cygwin/i
100
+ # Cygwin - if anyone is still using that
101
+ class Cygwin < HostOsFamily
102
+ def self.matching_regex
103
+ /cygwin/i
104
+ end
105
+
106
+ def app_list(app)
107
+ app.cygwin_app_list
108
+ end
67
109
  end
68
- def app_list( app ) app.cygwin_app_list; end
69
110
  end
70
111
  end
71
112
  end
@@ -1,93 +1,98 @@
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/
6
- class NixDesktopEnvironment
7
- class NotFoundError < Launchy::Error; end
1
+ # frozen_string_literal: true
8
2
 
9
- extend ::Launchy::DescendantTracker
10
-
11
- # Detect the current *nix desktop environment
3
+ module Launchy
4
+ module Detect
12
5
  #
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 found. #{Launchy.bug_report_message}") unless found
18
- return found
19
- end
6
+ # Detect the current desktop environment for *nix machines
7
+ # Currently this is Linux centric. The detection is based upon the detection
8
+ # used by xdg-open from http://portland.freedesktop.org/
9
+ class NixDesktopEnvironment
10
+ class NotFoundError < Launchy::Error; end
11
+
12
+ extend ::Launchy::DescendantTracker
13
+
14
+ # Detect the current *nix desktop environment
15
+ #
16
+ # If the current dekstop environment be detected, the return
17
+ # NixDekstopEnvironment::Unknown
18
+ def self.detect
19
+ found = find_child(:is_current_desktop_environment?)
20
+ Launchy.log("Current Desktop environment not found. #{Launchy.bug_report_message}") unless found
21
+ found
22
+ end
20
23
 
21
- def self.fallback_browsers
22
- %w[ firefox iceweasel seamonkey opera mozilla netscape galeon links lynx ].map { |x| ::Launchy::Argv.new( x ) }
23
- end
24
+ def self.fallback_browsers
25
+ %w[firefox iceweasel seamonkey opera mozilla netscape galeon links lynx].map { |x| ::Launchy::Argv.new(x) }
26
+ end
24
27
 
25
- def self.browsers
26
- [ browser, fallback_browsers ].flatten
27
- end
28
+ def self.browsers
29
+ [browser, fallback_browsers].flatten
30
+ end
28
31
 
29
- #---------------------------------------
30
- # The list of known desktop environments
31
- #---------------------------------------
32
+ #---------------------------------------
33
+ # The list of known desktop environments
34
+ #---------------------------------------
32
35
 
33
- class Kde < NixDesktopEnvironment
34
- def self.is_current_desktop_environment?
35
- ENV['KDE_FULL_SESSION'] &&
36
- Launchy::Application.find_executable( 'kde-open' )
37
- end
36
+ # KDE desktop environment
37
+ class Kde < NixDesktopEnvironment
38
+ def self.is_current_desktop_environment?
39
+ ENV.fetch("KDE_FULL_SESSION", nil) &&
40
+ Launchy::Application.find_executable("kde-open")
41
+ end
38
42
 
39
- def self.browser
40
- ::Launchy::Argv.new( 'kde-open' )
43
+ def self.browser
44
+ ::Launchy::Argv.new("kde-open")
45
+ end
41
46
  end
42
- end
43
47
 
44
- class Gnome < NixDesktopEnvironment
45
- def self.is_current_desktop_environment?
46
- ENV['GNOME_DESKTOP_SESSION_ID'] &&
47
- Launchy::Application.find_executable( 'gnome-open' )
48
- end
48
+ # Gnome desktop environment
49
+ class Gnome < NixDesktopEnvironment
50
+ def self.is_current_desktop_environment?
51
+ ENV.fetch("GNOME_DESKTOP_SESSION_ID", nil) &&
52
+ Launchy::Application.find_executable("gnome-open")
53
+ end
49
54
 
50
- def self.browser
51
- ::Launchy::Argv.new( 'gnome-open' )
55
+ def self.browser
56
+ ::Launchy::Argv.new("gnome-open")
57
+ end
52
58
  end
53
- end
54
59
 
55
- class Xfce < NixDesktopEnvironment
56
- def self.is_current_desktop_environment?
57
- if Launchy::Application.find_executable( 'xprop' ) then
58
- %x[ xprop -root _DT_SAVE_MODE].include?("xfce")
59
- else
60
- false
60
+ # Xfce desktop environment
61
+ class Xfce < NixDesktopEnvironment
62
+ def self.is_current_desktop_environment?
63
+ if Launchy::Application.find_executable("xprop")
64
+ `xprop -root _DT_SAVE_MODE`.include?("xfce")
65
+ else
66
+ false
67
+ end
61
68
  end
62
- end
63
69
 
64
- def self.browser
65
- ::Launchy::Argv.new( %w[ exo-open --launch WebBrowser ] )
70
+ def self.browser
71
+ ::Launchy::Argv.new(%w[exo-open --launch WebBrowser])
72
+ end
66
73
  end
67
- end
68
74
 
69
- # Fall back environment as the last case
70
- class Xdg < NixDesktopEnvironment
71
- def self.is_current_desktop_environment?
72
- Launchy::Application.find_executable( browser )
73
- end
75
+ # Fall back environment as the last case
76
+ class Xdg < NixDesktopEnvironment
77
+ def self.is_current_desktop_environment?
78
+ Launchy::Application.find_executable(browser)
79
+ end
74
80
 
75
- def self.browser
76
- ::Launchy::Argv.new( 'xdg-open' )
81
+ def self.browser
82
+ ::Launchy::Argv.new("xdg-open")
83
+ end
77
84
  end
78
- end
79
85
 
80
- # The one that is found when all else fails. And this must be declared last
81
- class NotFound < NixDesktopEnvironment
82
- def self.is_current_desktop_environment?
83
- true
84
- end
86
+ # The one that is found when all else fails. And this must be declared last
87
+ class NotFound < NixDesktopEnvironment
88
+ def self.is_current_desktop_environment?
89
+ true
90
+ end
85
91
 
86
- def self.browser
87
- ::Launchy::Argv.new
92
+ def self.browser
93
+ ::Launchy::Argv.new
94
+ end
88
95
  end
89
96
  end
90
-
91
97
  end
92
98
  end
93
-
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Launchy
4
+ # Internal: Namespace for detecting the environment that Launchy is running in
5
+ #
2
6
  module Detect
3
7
  end
4
8
  end
5
9
 
6
- require 'launchy/detect/host_os'
7
- require 'launchy/detect/host_os_family'
8
- require 'launchy/detect/ruby_engine'
9
- require 'launchy/detect/nix_desktop_environment'
10
- require 'launchy/detect/runner'
10
+ require "launchy/detect/host_os"
11
+ require "launchy/detect/host_os_family"
12
+ require "launchy/detect/nix_desktop_environment"
data/lib/launchy/error.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Launchy
2
4
  class Error < ::StandardError; end
3
5
  class ApplicationNotFoundError < Error; end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Launchy
2
4
  #
3
5
  # Model all the Operating system families that can exist.
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "childprocess"
4
+ module Launchy
5
+ # Internal: Run a command in a child process
6
+ #
7
+ class Runner
8
+ def run(cmd, *args)
9
+ unless cmd
10
+ raise Launchy::CommandNotFoundError,
11
+ "No command found to run with args '#{args.join(' ')}'. If this is unexpected, #{Launchy.bug_report_message}"
12
+ end
13
+
14
+ if Launchy.dry_run?
15
+ $stdout.puts dry_run(cmd, *args)
16
+ else
17
+ wet_run(cmd, *args)
18
+ end
19
+ end
20
+
21
+ def wet_run(cmd, *args)
22
+ argv = [cmd, *args].flatten
23
+ Launchy.log "ChildProcess: argv => #{argv.inspect}"
24
+ process = ChildProcess.build(*argv)
25
+
26
+ process.io.inherit!
27
+ process.leader = true
28
+ process.detach = true
29
+ process.start
30
+ end
31
+
32
+ def dry_run(cmd, *args)
33
+ shell_commands(cmd, args).join(" ")
34
+ end
35
+
36
+ # cut it down to just the shell commands that will be passed to exec or
37
+ # posix_spawn. The cmd argument is split according to shell rules and the
38
+ # args are not escaped because the whole set is passed to system as *args
39
+ # and in that case system shell escaping rules are not done.
40
+ #
41
+ def shell_commands(cmd, args)
42
+ cmdline = [cmd.to_s.shellsplit]
43
+ cmdline << args.flatten.collect(&:to_s)
44
+ commandline_normalize(cmdline)
45
+ end
46
+
47
+ def commandline_normalize(cmdline)
48
+ c = cmdline.flatten!
49
+ c = c.find_all { |a| !a.nil? and a.size.positive? }
50
+ Launchy.log "commandline_normalized => #{c.join(' ')}"
51
+ c
52
+ end
53
+ end
54
+ end
@@ -1,11 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Launchy
2
- VERSION = "2.5.0"
4
+ VERSION = "3.0.1"
3
5
 
6
+ # Internal: Version number of Launchy
4
7
  module Version
5
-
6
- MAJOR = Integer(VERSION.split('.')[0])
7
- MINOR = Integer(VERSION.split('.')[1])
8
- PATCH = Integer(VERSION.split('.')[2])
8
+ MAJOR = Integer(VERSION.split(".")[0])
9
+ MINOR = Integer(VERSION.split(".")[1])
10
+ PATCH = Integer(VERSION.split(".")[2])
9
11
 
10
12
  def self.to_a
11
13
  [MAJOR, MINOR, PATCH]