launchy 2.2.0-java → 2.4.2-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CONTRIBUTING.md +11 -8
- data/HISTORY.md +154 -0
- data/Manifest.txt +3 -2
- data/{README.rdoc → README.md} +38 -24
- data/Rakefile +2 -2
- data/lib/launchy.rb +40 -14
- data/lib/launchy/applications/browser.rb +14 -13
- data/lib/launchy/argv.rb +36 -0
- data/lib/launchy/cli.rb +2 -4
- data/lib/launchy/descendant_tracker.rb +1 -1
- data/lib/launchy/detect/nix_desktop_environment.rb +24 -7
- data/lib/launchy/detect/runner.rb +15 -2
- data/lib/launchy/version.rb +1 -1
- data/spec/application_spec.rb +2 -2
- data/spec/applications/browser_spec.rb +3 -2
- data/spec/detect/nix_desktop_environment_spec.rb +6 -11
- data/spec/launchy_spec.rb +51 -4
- data/tasks/default.rake +76 -17
- data/tasks/this.rb +14 -7
- metadata +32 -44
- data/HISTORY.rdoc +0 -135
data/lib/launchy/argv.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
module Launchy
|
2
|
+
class Argv
|
3
|
+
attr_reader :argv
|
4
|
+
def initialize( *args )
|
5
|
+
@argv = args.flatten
|
6
|
+
end
|
7
|
+
|
8
|
+
def to_s
|
9
|
+
@argv.join(' ')
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_str
|
13
|
+
to_s
|
14
|
+
end
|
15
|
+
|
16
|
+
def [](idx)
|
17
|
+
@argv[idx]
|
18
|
+
end
|
19
|
+
|
20
|
+
def valid?
|
21
|
+
(not blank?) && executable?
|
22
|
+
end
|
23
|
+
|
24
|
+
def blank?
|
25
|
+
@argv.empty? || (@argv.first.strip.size == 0)
|
26
|
+
end
|
27
|
+
|
28
|
+
def executable?
|
29
|
+
::Launchy::Application.find_executable( @argv.first )
|
30
|
+
end
|
31
|
+
|
32
|
+
def ==( other )
|
33
|
+
@argv == other.argv
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/launchy/cli.rb
CHANGED
@@ -22,7 +22,7 @@ module Launchy
|
|
22
22
|
|
23
23
|
op.on( "-d", "--debug",
|
24
24
|
"Force debug. Output lots of information.") do |d|
|
25
|
-
@options[:debug] =
|
25
|
+
@options[:debug] = true
|
26
26
|
end
|
27
27
|
|
28
28
|
op.on( "-e", "--engine RUBY_ENGINE",
|
@@ -65,13 +65,11 @@ module Launchy
|
|
65
65
|
|
66
66
|
def good_run( argv, env )
|
67
67
|
if parse( argv, env ) then
|
68
|
-
Launchy.open( argv.shift, options )
|
68
|
+
Launchy.open( argv.shift, options ) { |e| error_output( e ) }
|
69
69
|
return true
|
70
70
|
else
|
71
71
|
return false
|
72
72
|
end
|
73
|
-
rescue StandardError => e
|
74
|
-
error_output( e )
|
75
73
|
end
|
76
74
|
|
77
75
|
def error_output( error )
|
@@ -19,7 +19,11 @@ module Launchy::Detect
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def self.fallback_browsers
|
22
|
-
%w[ firefox seamonkey opera mozilla netscape galeon ]
|
22
|
+
%w[ firefox seamonkey opera mozilla netscape galeon ].map { |x| ::Launchy::Argv.new( x ) }
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.browsers
|
26
|
+
[ browser, fallback_browsers ].flatten
|
23
27
|
end
|
24
28
|
|
25
29
|
#---------------------------------------
|
@@ -32,7 +36,7 @@ module Launchy::Detect
|
|
32
36
|
end
|
33
37
|
|
34
38
|
def self.browser
|
35
|
-
|
39
|
+
::Launchy::Argv.new( %w[ kfmclient openURL ] )
|
36
40
|
end
|
37
41
|
end
|
38
42
|
|
@@ -42,7 +46,7 @@ module Launchy::Detect
|
|
42
46
|
end
|
43
47
|
|
44
48
|
def self.browser
|
45
|
-
'gnome-open'
|
49
|
+
::Launchy::Argv.new( 'gnome-open' )
|
46
50
|
end
|
47
51
|
end
|
48
52
|
|
@@ -56,19 +60,32 @@ module Launchy::Detect
|
|
56
60
|
end
|
57
61
|
|
58
62
|
def self.browser
|
59
|
-
'exo-open'
|
63
|
+
::Launchy::Argv.new( 'exo-open' )
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# Fall back environment as the last case
|
68
|
+
class Xdg < NixDesktopEnvironment
|
69
|
+
def self.is_current_desktop_environment?
|
70
|
+
Launchy::Application.find_executable( browser )
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.browser
|
74
|
+
::Launchy::Argv.new( 'xdg-open' )
|
60
75
|
end
|
61
76
|
end
|
62
77
|
|
63
|
-
|
78
|
+
# The one that is found when all else fails. And this must be declared last
|
79
|
+
class NotFound < NixDesktopEnvironment
|
64
80
|
def self.is_current_desktop_environment?
|
65
|
-
|
81
|
+
true
|
66
82
|
end
|
67
83
|
|
68
84
|
def self.browser
|
69
|
-
|
85
|
+
::Launchy::Argv.new
|
70
86
|
end
|
71
87
|
end
|
88
|
+
|
72
89
|
end
|
73
90
|
end
|
74
91
|
|
@@ -37,7 +37,7 @@ module Launchy::Detect
|
|
37
37
|
# and in that case system shell escaping rules are not done.
|
38
38
|
#
|
39
39
|
def shell_commands( cmd, args )
|
40
|
-
cmdline = [ cmd.shellsplit ]
|
40
|
+
cmdline = [ cmd.to_s.shellsplit ]
|
41
41
|
cmdline << args.flatten.collect{ |a| a.to_s }
|
42
42
|
return commandline_normalize( cmdline )
|
43
43
|
end
|
@@ -81,8 +81,21 @@ module Launchy::Detect
|
|
81
81
|
|
82
82
|
# escape the reserved shell characters in windows command shell
|
83
83
|
# http://technet.microsoft.com/en-us/library/cc723564.aspx
|
84
|
+
#
|
85
|
+
# Also make sure that the item after 'start' is guaranteed to be quoted.
|
86
|
+
# https://github.com/copiousfreetime/launchy/issues/62
|
84
87
|
def shell_commands( cmd, *args )
|
85
|
-
|
88
|
+
parts = cmd.shellsplit
|
89
|
+
|
90
|
+
if start_idx = parts.index('start') then
|
91
|
+
title_idx = start_idx + 1
|
92
|
+
title = parts[title_idx]
|
93
|
+
title = title.sub(/^/,'"') unless title[0] == '"'
|
94
|
+
title = title.sub(/$/,'"') unless title[-1] == '"'
|
95
|
+
parts[title_idx] = title
|
96
|
+
end
|
97
|
+
|
98
|
+
cmdline = [ parts ]
|
86
99
|
cmdline << args.flatten.collect { |a| a.to_s.gsub(/([&|()<>^])/, "^\\1") }
|
87
100
|
return commandline_normalize( cmdline )
|
88
101
|
end
|
data/lib/launchy/version.rb
CHANGED
data/spec/application_spec.rb
CHANGED
@@ -30,8 +30,8 @@ describe Launchy::Application do
|
|
30
30
|
lambda { Launchy::Application.handling( uri ) }.must_raise( Launchy::ApplicationNotFoundError )
|
31
31
|
end
|
32
32
|
|
33
|
-
it "can find open or curl" do
|
34
|
-
found = %w[ open curl ].any? do |app|
|
33
|
+
it "can find open or curl or xdg-open" do
|
34
|
+
found = %w[ open curl xdg-open ].any? do |app|
|
35
35
|
Launchy::Application.find_executable( app )
|
36
36
|
end
|
37
37
|
found.must_equal true
|
@@ -10,11 +10,12 @@ describe Launchy::Application::Browser do
|
|
10
10
|
after do
|
11
11
|
Launchy.reset_global_options
|
12
12
|
ENV.delete( 'KDE_FULL_SESSION' )
|
13
|
+
ENV.delete( 'BROWSER' )
|
13
14
|
end
|
14
15
|
|
15
|
-
{ 'windows' => 'start /b' ,
|
16
|
+
{ 'windows' => 'start "launchy" /b' ,
|
16
17
|
'darwin' => '/usr/bin/open',
|
17
|
-
'cygwin' => 'cmd /C start /b',
|
18
|
+
'cygwin' => 'cmd /C start "launchy" /b',
|
18
19
|
|
19
20
|
# when running these tests on a linux box, this test will fail
|
20
21
|
'linux' => nil }.each do |host_os, cmdline|
|
@@ -14,6 +14,8 @@ describe Launchy::Detect::NixDesktopEnvironment do
|
|
14
14
|
{ "KDE_FULL_SESSION" => Launchy::Detect::NixDesktopEnvironment::Kde,
|
15
15
|
"GNOME_DESKTOP_SESSION_ID" => Launchy::Detect::NixDesktopEnvironment::Gnome }.each_pair do |k,v|
|
16
16
|
it "can detect the desktop environment of a *nix machine using ENV[#{k}]" do
|
17
|
+
ENV.delete( "KDE_FULL_SESSION" )
|
18
|
+
ENV.delete( "GNOME_DESKTOP_SESSION_ID" )
|
17
19
|
ENV[k] = "launchy-test"
|
18
20
|
nix_env = Launchy::Detect::NixDesktopEnvironment.detect
|
19
21
|
nix_env.must_equal( v )
|
@@ -22,24 +24,17 @@ describe Launchy::Detect::NixDesktopEnvironment do
|
|
22
24
|
end
|
23
25
|
end
|
24
26
|
|
25
|
-
it "detects the fluxbox desktop environment" do
|
26
|
-
ENV['DESKTOP_SESSION'] = 'fluxbox'
|
27
|
-
fluxbox_env = Launchy::Detect::NixDesktopEnvironment.detect
|
28
|
-
fluxbox_env.must_equal( Launchy::Detect::NixDesktopEnvironment::Fluxbox )
|
29
|
-
fluxbox_env.browser.must_equal( Launchy::Detect::NixDesktopEnvironment::Fluxbox.browser )
|
30
|
-
ENV.delete( 'DESKTOP_SESSION' )
|
31
|
-
end
|
32
|
-
|
33
27
|
it "returns false for XFCE if xprop is not found" do
|
34
28
|
Launchy.host_os = "linux"
|
35
29
|
Launchy::Detect::NixDesktopEnvironment::Xfce.is_current_desktop_environment?.must_equal( false )
|
36
30
|
end
|
37
31
|
|
38
|
-
it "returns
|
32
|
+
it "returns NotFound if it cannot determine the *nix desktop environment" do
|
39
33
|
Launchy.host_os = "linux"
|
40
34
|
ENV.delete( "KDE_FULL_SESSION" )
|
41
35
|
ENV.delete( "GNOME_DESKTOP_SESSION_ID" )
|
42
|
-
Launchy::Detect::NixDesktopEnvironment.detect
|
36
|
+
not_found = Launchy::Detect::NixDesktopEnvironment.detect
|
37
|
+
not_found.must_equal( Launchy::Detect::NixDesktopEnvironment::NotFound )
|
38
|
+
not_found.browser.must_equal( Launchy::Argv.new )
|
43
39
|
end
|
44
|
-
|
45
40
|
end
|
data/spec/launchy_spec.rb
CHANGED
@@ -6,11 +6,15 @@ describe Launchy do
|
|
6
6
|
Launchy.reset_global_options
|
7
7
|
@stderr = $stderr
|
8
8
|
$stderr = StringIO.new
|
9
|
+
@stdout = $stdout
|
10
|
+
$stdout = StringIO.new
|
11
|
+
@invalid_url = 'blah://example.com/invalid'
|
9
12
|
end
|
10
13
|
|
11
14
|
after do
|
12
15
|
Launchy.reset_global_options
|
13
16
|
$stderr = @stderr
|
17
|
+
$stdout = @stdout
|
14
18
|
end
|
15
19
|
|
16
20
|
it "logs to stderr when LAUNCHY_DEBUG environment variable is set" do
|
@@ -23,16 +27,32 @@ describe Launchy do
|
|
23
27
|
ENV["LAUNCHY_DEBUG"] = nil
|
24
28
|
end
|
25
29
|
|
26
|
-
it "sets the global option :dry_run to
|
30
|
+
it "sets the global option :dry_run to true if LAUNCHY_DRY_RUN environment variable is 'true'" do
|
27
31
|
ENV['LAUNCHY_DRY_RUN'] = 'true'
|
28
32
|
Launchy.extract_global_options({})
|
29
|
-
Launchy.dry_run?.must_equal
|
33
|
+
Launchy.dry_run?.must_equal true
|
30
34
|
ENV['LAUNCHY_DRY_RUN'] = nil
|
31
35
|
end
|
32
36
|
|
37
|
+
it "sets the global option :debug to true if LAUNCHY_DEBUG environment variable is 'true'" do
|
38
|
+
ENV['LAUNCHY_DEBUG'] = 'true'
|
39
|
+
Launchy.extract_global_options({})
|
40
|
+
Launchy.debug?.must_equal true
|
41
|
+
ENV['LAUNCHY_DEBUG'] = nil
|
42
|
+
end
|
43
|
+
|
33
44
|
it "has the global option :debug" do
|
34
45
|
Launchy.extract_global_options( { :debug => 'true' } )
|
35
46
|
Launchy.debug?.must_equal true
|
47
|
+
Launchy.extract_global_options( { :debug => true } )
|
48
|
+
Launchy.debug?.must_equal true
|
49
|
+
end
|
50
|
+
|
51
|
+
it "has the global option :dry_run" do
|
52
|
+
Launchy.extract_global_options( { :dry_run => 'true' } )
|
53
|
+
Launchy.dry_run?.must_equal true
|
54
|
+
Launchy.extract_global_options( { :dry_run => true } )
|
55
|
+
Launchy.dry_run?.must_equal true
|
36
56
|
end
|
37
57
|
|
38
58
|
it "has the global option :application" do
|
@@ -51,10 +71,37 @@ describe Launchy do
|
|
51
71
|
end
|
52
72
|
|
53
73
|
it "raises an exception if no scheme is found for the given uri" do
|
54
|
-
lambda { Launchy.open(
|
74
|
+
lambda { Launchy.open( @invalid_url ) }.must_raise Launchy::ApplicationNotFoundError
|
75
|
+
end
|
76
|
+
|
77
|
+
it "asssumes we open a local file if we have an exception if we have an invalid scheme and a valid path" do
|
78
|
+
uri = "blah://example.com/#{__FILE__}"
|
79
|
+
Launchy.open( uri , :dry_run => true )
|
80
|
+
$stdout.string.strip.must_equal "/usr/bin/open #{uri}"
|
81
|
+
end
|
82
|
+
|
83
|
+
it "opens a local file if we have a drive letter and a valid path on windows" do
|
84
|
+
uri = "C:#{__FILE__}"
|
85
|
+
Launchy.open( uri, :dry_run => true, :host_os => 'windows' )
|
86
|
+
$stdout.string.strip.must_equal 'cmd /c start "launchy" /b ' + uri
|
87
|
+
end
|
88
|
+
|
89
|
+
it "calls the block if instead of raising an exception if there is an error" do
|
90
|
+
Launchy.open( @invalid_url ) { $stderr.puts "oops had an error opening #{@invalid_url}" }
|
91
|
+
$stderr.string.strip.must_equal "oops had an error opening #{@invalid_url}"
|
92
|
+
end
|
93
|
+
|
94
|
+
it "calls the block with the values passed to launchy and the error" do
|
95
|
+
options = { :dry_run => true }
|
96
|
+
Launchy.open( @invalid_url, :dry_run => true ) { |e| $stderr.puts "had an error opening #{@invalid_url} with options #{options}: #{e}" }
|
97
|
+
$stderr.string.strip.must_equal "had an error opening #{@invalid_url} with options #{options}: No application found to handle '#{@invalid_url}'"
|
98
|
+
end
|
99
|
+
|
100
|
+
it "raises the error in the called block" do
|
101
|
+
lambda { Launchy.open( @invalid_url ) { raise StandardError, "KABOOM!" } }.must_raise StandardError
|
55
102
|
end
|
56
103
|
|
57
|
-
[ 'www.example.com', 'www.example.com/foo/bar' ].each do |x|
|
104
|
+
[ 'www.example.com', 'www.example.com/foo/bar', "C:#{__FILE__}" ].each do |x|
|
58
105
|
it "picks a Browser for #{x}" do
|
59
106
|
app = Launchy.app_for_uri_string( x )
|
60
107
|
app.must_equal( Launchy::Application::Browser )
|
data/tasks/default.rake
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# vim: syntax=ruby
|
2
2
|
require 'rake/clean'
|
3
|
+
require 'digest'
|
3
4
|
#------------------------------------------------------------------------------
|
4
5
|
# If you want to Develop on this project just run 'rake develop' and you'll
|
5
6
|
# have all you need to get going. If you want to use bundler for development,
|
@@ -11,7 +12,7 @@ namespace :develop do
|
|
11
12
|
# gemspec.
|
12
13
|
task :default do
|
13
14
|
require 'rubygems/dependency_installer'
|
14
|
-
installer = Gem::DependencyInstaller.new
|
15
|
+
installer = ::Gem::DependencyInstaller.new
|
15
16
|
|
16
17
|
This.set_coverage_gem
|
17
18
|
|
@@ -30,7 +31,7 @@ namespace :develop do
|
|
30
31
|
# Create a Gemfile that just references the gemspec
|
31
32
|
file 'Gemfile' => :gemspec do
|
32
33
|
File.open( "Gemfile", "w+" ) do |f|
|
33
|
-
f.puts 'source
|
34
|
+
f.puts 'source "https://rubygems.org/"'
|
34
35
|
f.puts 'gemspec'
|
35
36
|
end
|
36
37
|
end
|
@@ -53,9 +54,12 @@ begin
|
|
53
54
|
require 'rake/testtask'
|
54
55
|
Rake::TestTask.new( :test ) do |t|
|
55
56
|
t.ruby_opts = %w[ -w -rubygems ]
|
56
|
-
t.libs = %w[ lib spec ]
|
57
|
-
t.pattern = "spec
|
57
|
+
t.libs = %w[ lib spec test ]
|
58
|
+
t.pattern = "{test,spec}/**/{test_*,*_spec}.rb"
|
58
59
|
end
|
60
|
+
|
61
|
+
task :test_requirements
|
62
|
+
task :test => :test_requirements
|
59
63
|
task :default => :test
|
60
64
|
rescue LoadError
|
61
65
|
This.task_warning( 'test' )
|
@@ -71,11 +75,12 @@ begin
|
|
71
75
|
RDoc::Task.new do |t|
|
72
76
|
t.markup = 'tomdoc'
|
73
77
|
t.rdoc_dir = 'doc'
|
74
|
-
t.main = 'README.
|
78
|
+
t.main = 'README.md'
|
75
79
|
t.title = "#{This.name} #{This.version}"
|
76
|
-
t.rdoc_files.include( '*.rdoc', '
|
80
|
+
t.rdoc_files.include( FileList['*.{rdoc,md,txt}'], FileList['ext/**/*.c'],
|
81
|
+
FileList['lib/**/*.rb'] )
|
77
82
|
end
|
78
|
-
rescue LoadError
|
83
|
+
rescue StandardError, LoadError
|
79
84
|
This.task_warning( 'rdoc' )
|
80
85
|
end
|
81
86
|
|
@@ -146,19 +151,70 @@ end
|
|
146
151
|
#------------------------------------------------------------------------------
|
147
152
|
# Fixme - look for fixmes and report them
|
148
153
|
#------------------------------------------------------------------------------
|
149
|
-
|
150
|
-
task :
|
151
|
-
|
152
|
-
|
154
|
+
namespace :fixme do
|
155
|
+
task :default => 'manifest:check' do
|
156
|
+
This.manifest.each do |file|
|
157
|
+
next if file == __FILE__
|
158
|
+
next unless file =~ %r/(txt|rb|md|rdoc|css|html|xml|css)\Z/
|
159
|
+
puts "FIXME: Rename #{file}" if file =~ /fixme/i
|
160
|
+
IO.readlines( file ).each_with_index do |line, idx|
|
161
|
+
prefix = "FIXME: #{file}:#{idx+1}".ljust(42)
|
162
|
+
puts "#{prefix} => #{line.strip}" if line =~ /fixme/i
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def fixme_project_root
|
168
|
+
This.project_path( '../fixme' )
|
169
|
+
end
|
170
|
+
|
171
|
+
def fixme_project_path( subtree )
|
172
|
+
fixme_project_root.join( subtree )
|
173
|
+
end
|
174
|
+
|
175
|
+
def local_fixme_files
|
176
|
+
This.manifest.select { |p| p =~ %r|^tasks/| }
|
177
|
+
end
|
153
178
|
|
154
|
-
|
179
|
+
def outdated_fixme_files
|
180
|
+
local_fixme_files.reject do |local|
|
181
|
+
upstream = fixme_project_path( local )
|
182
|
+
Digest::SHA256.file( local ) == Digest::SHA256.file( upstream )
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
def fixme_up_to_date?
|
187
|
+
outdated_fixme_files.empty?
|
188
|
+
end
|
155
189
|
|
156
|
-
|
157
|
-
|
158
|
-
|
190
|
+
desc "See if the fixme tools are outdated"
|
191
|
+
task :outdated => :release_check do
|
192
|
+
if fixme_up_to_date? then
|
193
|
+
puts "Fixme files are up to date."
|
194
|
+
else
|
195
|
+
outdated_fixme_files.each do |f|
|
196
|
+
puts "#{f} is outdated"
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
desc "Update outdated fixme files"
|
202
|
+
task :update => :release_check do
|
203
|
+
if fixme_up_to_date? then
|
204
|
+
puts "Fixme files are already up to date."
|
205
|
+
else
|
206
|
+
puts "Updating fixme files:"
|
207
|
+
outdated_fixme_files.each do |local|
|
208
|
+
upstream = fixme_project_path( local )
|
209
|
+
puts " * #{local}"
|
210
|
+
FileUtils.cp( upstream, local )
|
211
|
+
end
|
212
|
+
puts "Use your git commands as appropriate."
|
159
213
|
end
|
160
214
|
end
|
161
215
|
end
|
216
|
+
desc "Look for fixmes and report them"
|
217
|
+
task :fixme => "fixme:default"
|
162
218
|
|
163
219
|
#------------------------------------------------------------------------------
|
164
220
|
# Gem Specification
|
@@ -172,11 +228,14 @@ task :gemspec do
|
|
172
228
|
end
|
173
229
|
|
174
230
|
# the gemspec is also a dev artifact and should not be kept around.
|
175
|
-
CLOBBER << This.gemspec_file
|
231
|
+
CLOBBER << This.gemspec_file.to_s
|
232
|
+
|
233
|
+
# .rbc files from ruby 2.0
|
234
|
+
CLOBBER << FileList["**/*.rbc"]
|
176
235
|
|
177
236
|
# The standard gem packaging task, everyone has it.
|
178
237
|
require 'rubygems/package_task'
|
179
|
-
Gem::PackageTask.new( This.platform_gemspec ) do
|
238
|
+
::Gem::PackageTask.new( This.platform_gemspec ) do
|
180
239
|
# nothing
|
181
240
|
end
|
182
241
|
|