launchy 2.5.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/spec/launchy_spec.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'spec_helper'
2
2
  require 'pathname'
3
+ require 'mock_application'
3
4
 
4
5
  describe Launchy do
5
6
 
@@ -66,15 +67,19 @@ describe Launchy do
66
67
  _(Launchy.host_os).must_equal 'my-special-os-v2'
67
68
  end
68
69
 
69
- it "has the global option :ruby_engine" do
70
- Launchy.extract_global_options( { :ruby_engine => "myruby" } )
71
- _(Launchy.ruby_engine).must_equal 'myruby'
72
- end
73
-
74
70
  it "raises an exception if no scheme is found for the given uri" do
75
71
  _(lambda { Launchy.open( @invalid_url ) }).must_raise Launchy::ApplicationNotFoundError
76
72
  end
77
73
 
74
+ it "raises an exepction if the browser failed to launch" do
75
+ skip("because headless CI") if ENV["CI"] == "true"
76
+ caught = nil
77
+ Launchy.open( @invalid_url, application: "browser") do |exception|
78
+ caught = exception
79
+ end
80
+ _(caught).must_be_kind_of Launchy::Error
81
+ end
82
+
78
83
  it "asssumes we open a local file if we have an exception if we have an invalid scheme and a valid path" do
79
84
  uri = "blah://example.com/#{__FILE__}"
80
85
  Launchy.open( uri , :dry_run => true )
@@ -86,7 +91,13 @@ describe Launchy do
86
91
  it "opens a local file if we have a drive letter and a valid path on windows" do
87
92
  uri = "C:#{__FILE__}"
88
93
  Launchy.open( uri, :dry_run => true, :host_os => 'windows' )
89
- _($stdout.string.strip).must_equal 'cmd /c start "launchy" /b ' + uri
94
+ _($stdout.string.strip).must_equal 'start launchy /b ' + uri
95
+ end
96
+
97
+ it "opens a data url with a forced browser application" do
98
+ uri = "data:text/html,hello%20world"
99
+ Launchy.open( uri, :dry_run => true, :application => "browser" )
100
+ _($stdout.string.strip).must_match(/open/) # /usr/bin/open or xdg-open
90
101
  end
91
102
 
92
103
  it "calls the block if instead of raising an exception if there is an error" do
@@ -104,6 +115,11 @@ describe Launchy do
104
115
  _(lambda { Launchy.open( @invalid_url ) { raise StandardError, "KABOOM!" } }).must_raise StandardError
105
116
  end
106
117
 
118
+ it "can force a specific application to be used" do
119
+ result = Launchy.open( "http://example.com", :application => "mockapplication" )
120
+ _(result).must_equal "MockApplication opened http://example.com"
121
+ end
122
+
107
123
  [ 'www.example.com', 'www.example.com/foo/bar', "C:#{__FILE__}" ].each do |x|
108
124
  it "picks a Browser for #{x}" do
109
125
  app = Launchy.app_for_uri_string( x )
@@ -116,4 +132,11 @@ describe Launchy do
116
132
  app = Launchy.app_for_uri_string( path )
117
133
  _(app).must_equal( Launchy::Application::Browser )
118
134
  end
135
+
136
+ [ "BROWSER", "bRoWsEr", "browser", "Browser" ].each do |x|
137
+ it "can find the browser by name #{x}" do
138
+ app = Launchy.app_for_name( x )
139
+ _(app).must_equal( Launchy::Application::Browser )
140
+ end
141
+ end
119
142
  end
@@ -6,4 +6,8 @@ class MockApplication < Launchy::Application
6
6
  def self.handles?( uri )
7
7
  schemes.include?( uri.scheme )
8
8
  end
9
+
10
+ def open( uri, options = {} )
11
+ return "MockApplication opened #{uri}"
12
+ end
9
13
  end
data/spec/spec_helper.rb CHANGED
@@ -1,8 +1,5 @@
1
- if RUBY_VERSION >= '1.9.2' then
2
- require 'simplecov'
3
- puts "Using coverage!"
4
- SimpleCov.start if ENV['COVERAGE']
5
- end
1
+ require 'simplecov'
2
+ SimpleCov.start if ENV['COVERAGE']
6
3
 
7
4
  gem 'minitest'
8
5
  require 'launchy'
data/tasks/default.rake CHANGED
@@ -36,11 +36,13 @@ task :develop => "develop:default"
36
36
  # Minitest - standard TestTask
37
37
  #------------------------------------------------------------------------------
38
38
  begin
39
- require 'rake/testtask'
40
- Rake::TestTask.new( :test ) do |t|
41
- t.ruby_opts = %w[ -w ]
42
- t.libs = %w[ lib spec test ]
43
- t.pattern = "{test,spec}/**/{test_*,*_spec}.rb"
39
+ require 'minitest/test_task'
40
+ Minitest::TestTask.create( :test) do |t|
41
+ t.libs << "lib"
42
+ t.libs << "spec"
43
+ t.libs << "test"
44
+ t.warning = true
45
+ t.test_globs = "{test,spec}/**/{test_*,*_spec}.rb"
44
46
  end
45
47
 
46
48
  task :test_requirements
@@ -143,14 +145,20 @@ namespace :fixme do
143
145
  end
144
146
 
145
147
  def local_fixme_files
146
- This.manifest.select { |p| p =~ %r|^tasks/| }
148
+ local_files = This.manifest.select { |p| p =~ %r|^tasks/| }
149
+ local_files.concat( Dir.glob( ".semaphore/*" ) )
147
150
  end
148
151
 
149
152
  def outdated_fixme_files
150
153
  local_fixme_files.select do |local|
151
154
  upstream = fixme_project_path( local )
152
- upstream.exist? &&
153
- ( Digest::SHA256.file( local ) != Digest::SHA256.file( upstream ) )
155
+ if upstream.exist? then
156
+ if File.exist?( local ) then
157
+ ( Digest::SHA256.file( local ) != Digest::SHA256.file( upstream ) )
158
+ else
159
+ true
160
+ end
161
+ end
154
162
  end
155
163
  end
156
164
 
@@ -159,7 +167,7 @@ namespace :fixme do
159
167
  end
160
168
 
161
169
  desc "See if the fixme tools are outdated"
162
- task :outdated => :release_check do
170
+ task :outdated do
163
171
  if fixme_up_to_date? then
164
172
  puts "Fixme files are up to date."
165
173
  else
@@ -170,7 +178,7 @@ namespace :fixme do
170
178
  end
171
179
 
172
180
  desc "Update outdated fixme files"
173
- task :update => :release_check do
181
+ task :update do
174
182
  if fixme_up_to_date? then
175
183
  puts "Fixme files are already up to date."
176
184
  else
@@ -201,7 +209,7 @@ task :gemspec do
201
209
  end
202
210
 
203
211
  # .rbc files from ruby 2.0
204
- CLOBBER << FileList["**/*.rbc"]
212
+ CLOBBER << "**/*.rbc"
205
213
 
206
214
  # The standard gem packaging task, everyone has it.
207
215
  require 'rubygems/package_task'
@@ -213,19 +221,19 @@ end
213
221
  # Release - the steps we go through to do a final release, this is pulled from
214
222
  # a compbination of mojombo's rakegem, hoe and hoe-git
215
223
  #
216
- # 1) make sure we are on the master branch
224
+ # 1) make sure we are on the main branch
217
225
  # 2) make sure there are no uncommitted items
218
226
  # 3) check the manifest and make sure all looks good
219
227
  # 4) build the gem
220
228
  # 5) do an empty commit to have the commit message of the version
221
229
  # 6) tag that commit as the version
222
- # 7) push master
230
+ # 7) push main
223
231
  # 8) push the tag
224
232
  # 7) pus the gem
225
233
  #------------------------------------------------------------------------------
226
234
  task :release_check do
227
- unless `git branch` =~ /^\* master$/
228
- abort "You must be on the master branch to release!"
235
+ unless `git branch` =~ /^\* main/
236
+ abort "You must be on the main branch to release!"
229
237
  end
230
238
  unless `git status` =~ /^nothing to commit/m
231
239
  abort "Nope, sorry, you have unfinished business"
@@ -236,7 +244,7 @@ desc "Create tag v#{This.version}, build and push #{This.platform_gemspec.full_n
236
244
  task :release => [ :release_check, 'manifest:check', :gem ] do
237
245
  sh "git commit --allow-empty -a -m 'Release #{This.version}'"
238
246
  sh "git tag -a -m 'v#{This.version}' v#{This.version}"
239
- sh "git push origin master"
247
+ sh "git push origin main"
240
248
  sh "git push origin v#{This.version}"
241
249
  sh "gem push pkg/#{This.platform_gemspec.full_name}.gem"
242
250
  end
data/tasks/this.rb CHANGED
@@ -25,10 +25,10 @@ class ThisProject
25
25
  #
26
26
  # Yields self
27
27
  def initialize(&block)
28
- @exclude_from_manifest = Regexp.union(/\.(git|DS_Store)/,
28
+ @exclude_from_manifest = Regexp.union(/\.(git|DS_Store|semaphore)/,
29
29
  /^(doc|coverage|pkg|tmp|Gemfile(\.lock)?)/,
30
30
  /^[^\/]+\.gemspec/,
31
- /\.(swp|jar|bundle|so|rvmrc|travis.yml|byebug_history)$/,
31
+ /\.(swp|jar|bundle|so|rvmrc|travis.yml|byebug_history|fossa.yml|ruby-version)$/,
32
32
  /~$/)
33
33
  @gemspecs = Hash.new
34
34
  yield self if block_given?
@@ -146,7 +146,7 @@ class ThisProject
146
146
  spec.rdoc_options = [ "--main" , 'README.md',
147
147
  "--markup", "tomdoc" ]
148
148
 
149
- spec.required_ruby_version = '>= 2.4.0'
149
+ spec.required_ruby_version = '>= 2.3.0'
150
150
  end
151
151
  end
152
152
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: launchy
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.0
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Hinegardner
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-28 00:00:00.000000000 Z
11
+ date: 2024-03-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -16,14 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '2.7'
19
+ version: '2.8'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '2.7'
26
+ version: '2.8'
27
+ - !ruby/object:Gem::Dependency
28
+ name: childprocess
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '5.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '5.0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rake
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -44,42 +58,56 @@ dependencies:
44
58
  requirements:
45
59
  - - "~>"
46
60
  - !ruby/object:Gem::Version
47
- version: '5.14'
61
+ version: '5.21'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '5.21'
69
+ - !ruby/object:Gem::Dependency
70
+ name: minitest-junit
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.0'
48
76
  type: :development
49
77
  prerelease: false
50
78
  version_requirements: !ruby/object:Gem::Requirement
51
79
  requirements:
52
80
  - - "~>"
53
81
  - !ruby/object:Gem::Version
54
- version: '5.14'
82
+ version: '1.0'
55
83
  - !ruby/object:Gem::Dependency
56
84
  name: rdoc
57
85
  requirement: !ruby/object:Gem::Requirement
58
86
  requirements:
59
87
  - - "~>"
60
88
  - !ruby/object:Gem::Version
61
- version: '6.2'
89
+ version: '6.6'
62
90
  type: :development
63
91
  prerelease: false
64
92
  version_requirements: !ruby/object:Gem::Requirement
65
93
  requirements:
66
94
  - - "~>"
67
95
  - !ruby/object:Gem::Version
68
- version: '6.2'
96
+ version: '6.6'
69
97
  - !ruby/object:Gem::Dependency
70
98
  name: simplecov
71
99
  requirement: !ruby/object:Gem::Requirement
72
100
  requirements:
73
101
  - - "~>"
74
102
  - !ruby/object:Gem::Version
75
- version: '0.18'
103
+ version: '0.22'
76
104
  type: :development
77
105
  prerelease: false
78
106
  version_requirements: !ruby/object:Gem::Requirement
79
107
  requirements:
80
108
  - - "~>"
81
109
  - !ruby/object:Gem::Version
82
- version: '0.18'
110
+ version: '0.22'
83
111
  description: Launchy is helper class for launching cross-platform applications in
84
112
  a fire and forget manner. There are application concepts (browser, email client,
85
113
  etc) that are common across all platforms, and they may be launched differently
@@ -107,16 +135,14 @@ files:
107
135
  - lib/launchy/applications/browser.rb
108
136
  - lib/launchy/argv.rb
109
137
  - lib/launchy/cli.rb
110
- - lib/launchy/deprecated.rb
111
138
  - lib/launchy/descendant_tracker.rb
112
139
  - lib/launchy/detect.rb
113
140
  - lib/launchy/detect/host_os.rb
114
141
  - lib/launchy/detect/host_os_family.rb
115
142
  - lib/launchy/detect/nix_desktop_environment.rb
116
- - lib/launchy/detect/ruby_engine.rb
117
- - lib/launchy/detect/runner.rb
118
143
  - lib/launchy/error.rb
119
144
  - lib/launchy/os_family.rb
145
+ - lib/launchy/runner.rb
120
146
  - lib/launchy/version.rb
121
147
  - spec/application_spec.rb
122
148
  - spec/applications/browser_spec.rb
@@ -124,8 +150,6 @@ files:
124
150
  - spec/detect/host_os_family_spec.rb
125
151
  - spec/detect/host_os_spec.rb
126
152
  - spec/detect/nix_desktop_environment_spec.rb
127
- - spec/detect/ruby_engine_spec.rb
128
- - spec/detect/runner_spec.rb
129
153
  - spec/launchy_spec.rb
130
154
  - spec/mock_application.rb
131
155
  - spec/spec_helper.rb
@@ -133,7 +157,7 @@ files:
133
157
  - spec/version_spec.rb
134
158
  - tasks/default.rake
135
159
  - tasks/this.rb
136
- homepage: http://github.com/copiousfreetime/launchy
160
+ homepage: https://github.com/copiousfreetime/launchy
137
161
  licenses:
138
162
  - ISC
139
163
  metadata:
@@ -141,7 +165,7 @@ metadata:
141
165
  changelog_uri: https://github.com/copiousfreetime/launchy/blob/master/README.md
142
166
  homepage_uri: https://github.com/copiousfreetime/launchy
143
167
  source_code_uri: https://github.com/copiousfreetime/launchy
144
- post_install_message:
168
+ post_install_message:
145
169
  rdoc_options:
146
170
  - "--main"
147
171
  - README.md
@@ -153,15 +177,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
153
177
  requirements:
154
178
  - - ">="
155
179
  - !ruby/object:Gem::Version
156
- version: 2.4.0
180
+ version: 2.3.0
157
181
  required_rubygems_version: !ruby/object:Gem::Requirement
158
182
  requirements:
159
183
  - - ">="
160
184
  - !ruby/object:Gem::Version
161
185
  version: '0'
162
186
  requirements: []
163
- rubygems_version: 3.0.3
164
- signing_key:
187
+ rubygems_version: 3.5.3
188
+ signing_key:
165
189
  specification_version: 4
166
190
  summary: Launchy is helper class for launching cross-platform applications in a fire
167
191
  and forget manner.
@@ -172,8 +196,6 @@ test_files:
172
196
  - spec/detect/host_os_family_spec.rb
173
197
  - spec/detect/host_os_spec.rb
174
198
  - spec/detect/nix_desktop_environment_spec.rb
175
- - spec/detect/ruby_engine_spec.rb
176
- - spec/detect/runner_spec.rb
177
199
  - spec/launchy_spec.rb
178
200
  - spec/mock_application.rb
179
201
  - spec/spec_helper.rb
@@ -1,52 +0,0 @@
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
@@ -1,78 +0,0 @@
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
@@ -1,152 +0,0 @@
1
- require 'shellwords'
2
- require 'stringio'
3
-
4
- module Launchy::Detect
5
- class Runner
6
- class NotFoundError < Launchy::Error; end
7
-
8
- extend ::Launchy::DescendantTracker
9
-
10
- # Detect the current command runner
11
- #
12
- # This will return an instance of the Runner to be used to do the
13
- # application launching.
14
- #
15
- # If a runner cannot be detected then raise Runner::NotFoundError
16
- #
17
- # The runner rules are, in order:
18
- #
19
- # 1) If you are on windows, you use the Windows Runner no matter what
20
- # 2) If you are using the jruby engine, use the Jruby Runner. Unless rule
21
- # (1) took effect
22
- # 3) Use Forkable (barring rules (1) and (2))
23
- def self.detect
24
- host_os_family = Launchy::Detect::HostOsFamily.detect
25
- ruby_engine = Launchy::Detect::RubyEngine.detect
26
-
27
- return Windows.new if host_os_family.windows?
28
- if ruby_engine.jruby? then
29
- return Jruby.new
30
- end
31
- return Forkable.new
32
- end
33
-
34
- #
35
- # cut it down to just the shell commands that will be passed to exec or
36
- # posix_spawn. The cmd argument is split according to shell rules and the
37
- # args are not escaped because they whole set is passed to system as *args
38
- # and in that case system shell escaping rules are not done.
39
- #
40
- def shell_commands( cmd, args )
41
- cmdline = [ cmd.to_s.shellsplit ]
42
- cmdline << args.flatten.collect{ |a| a.to_s }
43
- return commandline_normalize( cmdline )
44
- end
45
-
46
- def commandline_normalize( cmdline )
47
- c = cmdline.flatten!
48
- c = c.find_all { |a| (not a.nil?) and ( a.size > 0 ) }
49
- Launchy.log "commandline_normalized => #{c.join(' ')}"
50
- return c
51
- end
52
-
53
- def dry_run( cmd, *args )
54
- shell_commands(cmd, args).join(" ")
55
- end
56
-
57
- def run( cmd, *args )
58
- raise Launchy::CommandNotFoundError, "No command found to run with args '#{args.join(' ')}'. If this is unexpected, #{Launchy.bug_report_message}" unless cmd
59
- if Launchy.dry_run? then
60
- $stdout.puts dry_run( cmd, *args )
61
- else
62
- wet_run( cmd, *args )
63
- end
64
- end
65
-
66
-
67
- #---------------------------------------
68
- # The list of known runners
69
- #---------------------------------------
70
-
71
- class Windows < Runner
72
-
73
- def all_args( cmd, *args )
74
- args = [ 'cmd', '/c', *shell_commands( cmd, *args ) ]
75
- Launchy.log "Windows: all_args => #{args.inspect}"
76
- return args
77
- end
78
-
79
- def dry_run( cmd, *args )
80
- all_args( cmd, *args ).join(" ")
81
- end
82
-
83
- # escape the reserved shell characters in windows command shell
84
- # http://technet.microsoft.com/en-us/library/cc723564.aspx
85
- #
86
- # Also make sure that the item after 'start' is guaranteed to be quoted.
87
- # https://github.com/copiousfreetime/launchy/issues/62
88
- def shell_commands( cmd, *args )
89
- parts = cmd.shellsplit
90
-
91
- if start_idx = parts.index('start') then
92
- title_idx = start_idx + 1
93
- title = parts[title_idx]
94
- title = title.sub(/^/,'"') unless title[0] == '"'
95
- title = title.sub(/$/,'"') unless title[-1] == '"'
96
- parts[title_idx] = title
97
- end
98
-
99
- cmdline = [ parts ]
100
- cmdline << args.flatten.collect { |a| a.to_s.gsub(/([&|()<>^])/, "^\\1") }
101
- return commandline_normalize( cmdline )
102
- end
103
-
104
- def wet_run( cmd, *args )
105
- system( *all_args( cmd, *args ) )
106
- end
107
- end
108
-
109
- class Jruby < Runner
110
- def wet_run( cmd, *args )
111
- child_pid = spawn( *shell_commands( cmd, *args ) )
112
- Process.detach( child_pid )
113
- end
114
- end
115
-
116
- class Forkable < Runner
117
- attr_reader :child_pid
118
-
119
- def wet_run( cmd, *args )
120
- @child_pid = fork do
121
- close_file_descriptors unless Launchy.debug?
122
- Launchy.log("wet_run: before exec in child process")
123
- exec_or_raise( cmd, *args )
124
- exit!
125
- end
126
- Process.detach( @child_pid )
127
- end
128
-
129
- private
130
-
131
- # attaching to a StringIO instead of reopening so we don't loose the
132
- # STDERR, needed for exec_or_raise.
133
- def close_file_descriptors
134
- $stdin.reopen( "/dev/null")
135
-
136
- @saved_stdout = $stdout
137
- @saved_stderr = $stderr
138
-
139
- $stdout = StringIO.new
140
- $stderr = StringIO.new
141
- end
142
-
143
- def exec_or_raise( cmd, *args )
144
- exec( *shell_commands( cmd, *args ))
145
- rescue Exception => e
146
- $stderr = @saved_stderr
147
- $stdout = @saved_stdout
148
- raise e
149
- end
150
- end
151
- end
152
- end