launchy 2.5.2 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 04d9c66ec0c8dcc2892bc46267fe37f7f1c82d14dad78d62c8adbd869a0d8a0f
4
- data.tar.gz: ecf5f8096d6f3ef2a4d9118b18086eba83ed62f50362c1964938faba8d53d624
3
+ metadata.gz: 9d637a77afa69826953a3226c55fc20334c6fa90e268912bcf9a208bc9b448e2
4
+ data.tar.gz: 2f5ff5e1401319e3a97655848f4f61b9bb33e786cd1b22b76aa20a7729e0b885
5
5
  SHA512:
6
- metadata.gz: 4abd13c2b9c600a9e2a50d07a2a8bfbe6ae21de1972063520669f558b5b7f3eca6dc5e4a2de63d1a19c6dcdeb43a53bddc22da210556a2a6c64ba263afed92ec
7
- data.tar.gz: 53feae60f4355edcddaa16497c5606f35eaccabd81d21f35d91ac3188314affd43f722970fe4c31249a89fbfadf7afc74579ee7d97f4740f1d339b0007a577e5
6
+ metadata.gz: bb02ca4bd30a8394ca2a6c8e86518eb4f403d5b56c574f7730d1581a19ca686c94a001c641a09620b799b620f9d8e6be54ad39c27bb980e67268d01f68d8eae1
7
+ data.tar.gz: ba3bc128ef33d39c87b50e187ca71e0f39a2382cdf3513122ec1a108b71a55d2e2a8e0f81f138a27b8c9b1f74b8df183fe0b626d9718236efb3cb6a653fd1e62
data/HISTORY.md CHANGED
@@ -1,4 +1,11 @@
1
1
  # Launchy Changelog
2
+ ## Version 3.0.0 - 2024-03-03
3
+ * Remove unused `deprecated.rb` file - <https://github.com/copiousfreetime/launchy/issues/148>
4
+ * Update supported ruby versin to be 3.x
5
+ * use the `:application` parameter - <https://github.com/copiousfreetime/launchy/issues/121>
6
+ * adjust the semaphore configuration to allow better caching
7
+ * replace the homegrown process runner with [`childprocess`](https://rubygems.org/gems/childprocess)
8
+
2
9
  ## Version 2.5.2 - 2022-12-27
3
10
  * Update Addressable - <https://github.com/copiousfreetime/launchy/pull/145> - JamieKDonnelly
4
11
  * Fix deprecated usage of `Object#=~` - <https://github.com/copiousfreetime/launchy/pull/138> - marcrohloff
data/Manifest.txt CHANGED
@@ -10,16 +10,14 @@ lib/launchy/application.rb
10
10
  lib/launchy/applications/browser.rb
11
11
  lib/launchy/argv.rb
12
12
  lib/launchy/cli.rb
13
- lib/launchy/deprecated.rb
14
13
  lib/launchy/descendant_tracker.rb
15
14
  lib/launchy/detect.rb
16
15
  lib/launchy/detect/host_os.rb
17
16
  lib/launchy/detect/host_os_family.rb
18
17
  lib/launchy/detect/nix_desktop_environment.rb
19
- lib/launchy/detect/ruby_engine.rb
20
- lib/launchy/detect/runner.rb
21
18
  lib/launchy/error.rb
22
19
  lib/launchy/os_family.rb
20
+ lib/launchy/runner.rb
23
21
  lib/launchy/version.rb
24
22
  spec/application_spec.rb
25
23
  spec/applications/browser_spec.rb
@@ -27,8 +25,6 @@ spec/cli_spec.rb
27
25
  spec/detect/host_os_family_spec.rb
28
26
  spec/detect/host_os_spec.rb
29
27
  spec/detect/nix_desktop_environment_spec.rb
30
- spec/detect/ruby_engine_spec.rb
31
- spec/detect/runner_spec.rb
32
28
  spec/launchy_spec.rb
33
29
  spec/mock_application.rb
34
30
  spec/spec_helper.rb
data/README.md CHANGED
@@ -92,7 +92,6 @@ At the moment, the only available options are:
92
92
  :debug Turn on debugging output
93
93
  :application Explicitly state what application class is going to be used
94
94
  :host_os Explicitly state what host operating system to pretend to be
95
- :ruby_engine Explicitly state what ruby engine to pretend to be under
96
95
  :dry_run Do nothing and print the command that would be executed on $stdout
97
96
 
98
97
  If `Launchy.open` is invoked with a block, then no exception will be thrown, and
@@ -110,41 +109,6 @@ exception that was raised.
110
109
  puts "Attempted to open #{uri} and failed because #{exception}"
111
110
  end
112
111
 
113
- ## UPGRADING from versions before 2.0.0
114
-
115
- The previously published version of Launchy before the 2.0.0 series was 0.4.0.
116
- There have been so many changes, and a mistaken tag at 1.0.0, that I have
117
- decided to bump all the way to 2.x.y.
118
-
119
- I have attempted to keep backward compatibility with the previous examples. The
120
- previous API examples of:
121
-
122
- Launchy::Browser.run("https://www.ruby-lang.org/")
123
-
124
- and
125
-
126
- Launchy::Browser.new.visit("https://www.ruby-lang.org/")
127
-
128
- will still work, and you will get a deprecation notice, along with the line
129
- of code you should probably update. For example, this is what would print out
130
- in the github gem if it was updated to use 2.0.x but not use the supported API.
131
-
132
- % gh home
133
- WARNING: You made a call to a deprecated Launchy API. This call should be changed to 'Launchy.open( uri )'
134
- WARNING: I think I was able to find the location that needs to be fixed. Please go look at:
135
- WARNING:
136
- WARNING: /Users/jeremy/.rvm/gems/ruby-1.8.7-p334/gems/github-0.6.2/lib/commands/helpers.rb:275:in `open'
137
- WARNING: helper :open do |url|
138
- WARNING: has_launchy? proc {
139
- WARNING: Launchy::Browser.new.visit url
140
- WARNING: }
141
- WARNING: end
142
- WARNING:
143
- WARNING: If this is not the case, please file a bug. Please file a bug at https://github.com/copiousfreetime/launchy/issues/new
144
-
145
- These deprecation notices will go away with version 3.0 and the only available
146
- API will be the documented one.
147
-
148
112
  ## ISC LICENSE
149
113
 
150
114
  https://opensource.org/licenses/isc-license.txt
data/Rakefile CHANGED
@@ -8,11 +8,13 @@ This.homepage = "https://github.com/copiousfreetime/#{ This.name }"
8
8
 
9
9
  This.ruby_gemspec do |spec|
10
10
  spec.add_dependency( 'addressable', '~> 2.8')
11
+ spec.add_dependency( 'childprocess', '~> 5.0')
11
12
 
12
13
  spec.add_development_dependency( 'rake' , '~> 13.0')
13
- spec.add_development_dependency( 'minitest' , '~> 5.15' )
14
- spec.add_development_dependency( 'rdoc' , '~> 6.4' )
15
- spec.add_development_dependency( 'simplecov', '~> 0.21' )
14
+ spec.add_development_dependency( 'minitest' , '~> 5.21' )
15
+ spec.add_development_dependency( 'minitest-junit' , '~> 1.0' )
16
+ spec.add_development_dependency( 'rdoc' , '~> 6.6' )
17
+ spec.add_development_dependency( 'simplecov', '~> 0.22' )
16
18
 
17
19
  spec.licenses = ['ISC']
18
20
 
@@ -24,8 +24,18 @@ module Launchy
24
24
  raise ApplicationNotFoundError, "No application found to handle '#{uri}'"
25
25
  end
26
26
 
27
+ # Find the application with the given name
27
28
  #
29
+ # returns the Class that has the given name
30
+ def for_name( name )
31
+ klass = find_child( :has_name?, name )
32
+ return klass if klass
33
+ raise ApplicationNotFoundError, "No application found named '#{name}'"
34
+ end
35
+
28
36
  # Find the given executable in the available paths
37
+ #
38
+ # returns the path to the executable or nil if not found
29
39
  def find_executable( bin, *paths )
30
40
  paths = Launchy.path.split( File::PATH_SEPARATOR ) if paths.empty?
31
41
  paths.each do |path|
@@ -38,16 +48,21 @@ module Launchy
38
48
  Launchy.log "#{self.name} : Unable to find `#{bin}' in #{paths.join(", ")}"
39
49
  return nil
40
50
  end
51
+
52
+ # Does this class have the given name-like string?
53
+ #
54
+ # returns true if the class has the given name
55
+ def has_name?( qname )
56
+ qname.to_s.downcase == self.name.split("::").last.downcase
57
+ end
41
58
  end
42
59
 
43
60
  attr_reader :host_os_family
44
- attr_reader :ruby_engine
45
61
  attr_reader :runner
46
62
 
47
63
  def initialize
48
64
  @host_os_family = Launchy::Detect::HostOsFamily.detect
49
- @ruby_engine = Launchy::Detect::RubyEngine.detect
50
- @runner = Launchy::Detect::Runner.detect
65
+ @runner = Launchy::Runner.new
51
66
  end
52
67
 
53
68
  def find_executable( bin, *paths )
data/lib/launchy/cli.rb CHANGED
@@ -15,7 +15,7 @@ module Launchy
15
15
  op.separator ""
16
16
  op.separator "Launch Options:"
17
17
 
18
- op.on( "-a", "--application APPLICATION",
18
+ op.on( "-a", "--application APPLICATION",
19
19
  "Explicitly specify the application class to use in the launch") do |app|
20
20
  @options[:application] = app
21
21
  end
@@ -25,11 +25,6 @@ module Launchy
25
25
  @options[:debug] = true
26
26
  end
27
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
28
  op.on( "-n", "--dry-run", "Don't launchy, print the command to be executed on stdout" ) do |x|
34
29
  @options[:dry_run] = true
35
30
  end
@@ -20,7 +20,7 @@ module Launchy::Detect
20
20
  end
21
21
 
22
22
  def default_host_os
23
- ::RbConfig::CONFIG['host_os']
23
+ ::RbConfig::CONFIG['host_os'].downcase
24
24
  end
25
25
 
26
26
  def override_host_os
@@ -42,7 +42,7 @@ module Launchy::Detect
42
42
  #
43
43
  class Windows < HostOsFamily
44
44
  def self.matching_regex
45
- /(mingw|mswin|windows)/i
45
+ /(mingw|mswin|msys|windows)/i
46
46
  end
47
47
  def app_list( app ) app.windows_app_list; end
48
48
  end
@@ -56,7 +56,7 @@ module Launchy::Detect
56
56
 
57
57
  class Nix < HostOsFamily
58
58
  def self.matching_regex
59
- /(linux|bsd|aix|solaris)/i
59
+ /(linux|bsd|aix|solaris|sunos|dragonfly)/i
60
60
  end
61
61
  def app_list( app ) app.nix_app_list; end
62
62
  end
@@ -5,6 +5,4 @@ end
5
5
 
6
6
  require 'launchy/detect/host_os'
7
7
  require 'launchy/detect/host_os_family'
8
- require 'launchy/detect/ruby_engine'
9
8
  require 'launchy/detect/nix_desktop_environment'
10
- require 'launchy/detect/runner'
@@ -0,0 +1,46 @@
1
+ require 'childprocess'
2
+ module Launchy
3
+ class Runner
4
+ def run( cmd, *args )
5
+ raise Launchy::CommandNotFoundError, "No command found to run with args '#{args.join(' ')}'. If this is unexpected, #{Launchy.bug_report_message}" unless cmd
6
+ if Launchy.dry_run? then
7
+ $stdout.puts dry_run( cmd, *args )
8
+ else
9
+ wet_run( cmd, *args )
10
+ end
11
+ end
12
+
13
+ def wet_run( cmd, *args )
14
+ argv = [ cmd, *args ].flatten
15
+ Launchy.log "ChildProcess: argv => #{argv.inspect}"
16
+ process = ChildProcess.build( *argv )
17
+
18
+ process.io.inherit!
19
+ process.leader = true
20
+ process.detach = true
21
+ process.start
22
+ end
23
+
24
+ def dry_run( cmd, *args )
25
+ shell_commands(cmd, args).join(" ")
26
+ end
27
+
28
+ # cut it down to just the shell commands that will be passed to exec or
29
+ # posix_spawn. The cmd argument is split according to shell rules and the
30
+ # args are not escaped because the whole set is passed to system as *args
31
+ # and in that case system shell escaping rules are not done.
32
+ #
33
+ def shell_commands( cmd, args )
34
+ cmdline = [ cmd.to_s.shellsplit ]
35
+ cmdline << args.flatten.collect{ |a| a.to_s }
36
+ return commandline_normalize( cmdline )
37
+ end
38
+
39
+ def commandline_normalize( cmdline )
40
+ c = cmdline.flatten!
41
+ c = c.find_all { |a| (not a.nil?) and ( a.size > 0 ) }
42
+ Launchy.log "commandline_normalized => #{c.join(' ')}"
43
+ return c
44
+ end
45
+ end
46
+ end
@@ -1,5 +1,5 @@
1
1
  module Launchy
2
- VERSION = "2.5.2"
2
+ VERSION = "3.0.0"
3
3
 
4
4
  module Version
5
5
 
data/lib/launchy.rb CHANGED
@@ -1,4 +1,6 @@
1
1
  require 'addressable/uri'
2
+ require 'shellwords'
3
+ require 'stringio'
2
4
 
3
5
  #
4
6
  # The entry point into Launchy. This is the sole supported public API.
@@ -11,7 +13,6 @@ require 'addressable/uri'
11
13
  # :application Explicitly state what application class is going to be used.
12
14
  # This must be a child class of Launchy::Application
13
15
  # :host_os Explicitly state what host operating system to pretend to be
14
- # :ruby_engine Explicitly state what ruby engine to pretend to be under
15
16
  # :dry_run Do nothing and print the command that would be executed on $stdout
16
17
  #
17
18
  # Other options may be used, and those will be passed directly to the
@@ -26,7 +27,14 @@ module Launchy
26
27
  def open(uri_s, options = {}, &error_block )
27
28
  leftover = extract_global_options( options )
28
29
  uri = string_to_uri( uri_s )
29
- app = app_for_uri( uri )
30
+ if name = options[:application] then
31
+ app = app_for_name( name )
32
+ end
33
+
34
+ if app.nil? then
35
+ app = app_for_uri( uri )
36
+ end
37
+
30
38
  app.new.open( uri, leftover )
31
39
  rescue Launchy::Error => le
32
40
  raise le
@@ -34,7 +42,7 @@ module Launchy
34
42
  msg = "Failure in opening uri #{uri_s.inspect} with options #{options.inspect}: #{e}"
35
43
  raise Launchy::Error, msg
36
44
  ensure
37
- if $! and block_given? then
45
+ if $! && block_given? then
38
46
  yield $!
39
47
  return # explicitly swallow the errors
40
48
  end
@@ -44,6 +52,12 @@ module Launchy
44
52
  Launchy::Application.handling( uri )
45
53
  end
46
54
 
55
+ def app_for_name( name )
56
+ Launchy::Application.for_name( name )
57
+ rescue Launchy::ApplicationNotFoundError
58
+ nil
59
+ end
60
+
47
61
  def app_for_uri_string( s )
48
62
  app_for_uri( string_to_uri( s ) )
49
63
  end
@@ -64,7 +78,6 @@ module Launchy
64
78
  Launchy.debug = false
65
79
  Launchy.application = nil
66
80
  Launchy.host_os = nil
67
- Launchy.ruby_engine = nil
68
81
  Launchy.dry_run = false
69
82
  Launchy.path = ENV['PATH']
70
83
  end
@@ -74,7 +87,6 @@ module Launchy
74
87
  Launchy.debug = leftover.delete( :debug ) || ENV['LAUNCHY_DEBUG']
75
88
  Launchy.application = leftover.delete( :application ) || ENV['LAUNCHY_APPLICATION']
76
89
  Launchy.host_os = leftover.delete( :host_os ) || ENV['LAUNCHY_HOST_OS']
77
- Launchy.ruby_engine = leftover.delete( :ruby_engine ) || ENV['LAUNCHY_RUBY_ENGINE']
78
90
  Launchy.dry_run = leftover.delete( :dry_run ) || ENV['LAUNCHY_DRY_RUN']
79
91
  end
80
92
 
@@ -104,14 +116,6 @@ module Launchy
104
116
  @host_os || ENV['LAUNCHY_HOST_OS']
105
117
  end
106
118
 
107
- def ruby_engine=( ruby_engine )
108
- @ruby_engine = ruby_engine
109
- end
110
-
111
- def ruby_engine
112
- @ruby_engine || ENV['LAUNCHY_RUBY_ENGINE']
113
- end
114
-
115
119
  def dry_run=( dry_run )
116
120
  @dry_run = to_bool( dry_run )
117
121
  end
@@ -160,4 +164,4 @@ require 'launchy/descendant_tracker'
160
164
  require 'launchy/error'
161
165
  require 'launchy/application'
162
166
  require 'launchy/detect'
163
- require 'launchy/deprecated'
167
+ require 'launchy/runner'
data/spec/cli_spec.rb CHANGED
@@ -59,7 +59,6 @@ describe Launchy::Cli do
59
59
 
60
60
  {
61
61
  '--application' => [ :application, 'Browser'],
62
- '--engine' => [ :ruby_engine, 'rbx'],
63
62
  '--host-os' => [ :host_os, 'cygwin'] }.each_pair do |opt, val|
64
63
  it "the commandline option #{opt} sets the program option #{val[0]}" do
65
64
  argv = [ opt, val[1], "https://github.com/copiousfreetime/launchy" ]
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'
@@ -224,7 +232,7 @@ end
224
232
  # 7) pus the gem
225
233
  #------------------------------------------------------------------------------
226
234
  task :release_check do
227
- unless `git branch` =~ /^\* main$/
235
+ unless `git branch` =~ /^\* main/
228
236
  abort "You must be on the main branch to release!"
229
237
  end
230
238
  unless `git status` =~ /^nothing to commit/m
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?
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.2
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Hinegardner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-12-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
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
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.15'
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.15'
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.4'
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.4'
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.21'
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.21'
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
@@ -160,7 +184,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
160
184
  - !ruby/object:Gem::Version
161
185
  version: '0'
162
186
  requirements: []
163
- rubygems_version: 3.3.26
187
+ rubygems_version: 3.5.3
164
188
  signing_key:
165
189
  specification_version: 4
166
190
  summary: Launchy is helper class for launching cross-platform applications in a fire
@@ -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
@@ -1,37 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Launchy::Detect::RubyEngine do
4
-
5
- before do
6
- Launchy.reset_global_options
7
- end
8
-
9
- after do
10
- Launchy.reset_global_options
11
- end
12
-
13
- %w[ ruby jruby rbx macruby ].each do |ruby|
14
- it "detects the #{ruby} RUBY_ENGINE" do
15
- _(Launchy::Detect::RubyEngine.detect( ruby ).ancestors).must_include Launchy::Detect::RubyEngine
16
- end
17
- end
18
-
19
- it "uses the global ruby_engine overrides" do
20
- ENV['LAUNCHY_RUBY_ENGINE'] = "rbx"
21
- _(Launchy::Detect::RubyEngine.detect).must_equal Launchy::Detect::RubyEngine::Rbx
22
- ENV.delete('LAUNCHY_RUBY_ENGINE')
23
- end
24
-
25
- it "does not find a ruby engine of 'foo'" do
26
- _(lambda { Launchy::Detect::RubyEngine.detect( 'foo' ) }).must_raise Launchy::Detect::RubyEngine::NotFoundError
27
- end
28
-
29
- { 'rbx' => :rbx?,
30
- 'ruby' => :mri?,
31
- 'macruby' => :macruby?,
32
- 'jruby' => :jruby? }.each_pair do |engine, method|
33
- it "#{method} returns true for #{engine} " do
34
- _(Launchy::Detect::RubyEngine.detect( engine ).send( method )).must_equal true
35
- end
36
- end
37
- end
@@ -1,103 +0,0 @@
1
- # coding: utf-8
2
- require 'spec_helper'
3
-
4
- describe Launchy::Detect::Runner do
5
- before do
6
- Launchy.reset_global_options
7
- @test_url = "http://example.com/?foo=bar&baz=wibble"
8
- end
9
-
10
- after do
11
- Launchy.reset_global_options
12
- end
13
-
14
- it "raises an error when there is an unknown host os" do
15
- Launchy.host_os = "foo"
16
- _(lambda{ Launchy::Detect::Runner.detect }).must_raise Launchy::Detect::HostOsFamily::NotFoundError
17
- end
18
-
19
- it "raises an error when there is an unknown ruby engine" do
20
- Launchy.ruby_engine = "wibble"
21
- _(lambda{ Launchy::Detect::Runner.detect }).must_raise Launchy::Detect::RubyEngine::NotFoundError
22
- end
23
-
24
- it "raises and error when there is no command found" do
25
- runner = Launchy::Detect::Runner.detect
26
- _(lambda{ runner.run( nil, *%w[ arg1 arg2 arg 3] ) }).must_raise Launchy::CommandNotFoundError
27
- end
28
-
29
- # On anything that has fork, use Forkable
30
- %w[ linux darwin cygwin ].each do |host_os|
31
- %w[ ruby rbx macruby ].each do |engine_name|
32
- it "engine '#{engine_name}' on OS '#{host_os}' uses runner Forkable" do
33
- Launchy.host_os = host_os
34
- Launchy.ruby_engine = engine_name
35
- engine = Launchy::Detect::Runner.detect
36
- _(engine).must_be_instance_of Launchy::Detect::Runner::Forkable
37
- end
38
- end
39
- end
40
-
41
-
42
- # Jruby always uses the Jruby runner except on Windows
43
- { 'mingw' => Launchy::Detect::Runner::Windows,
44
- 'linux' => Launchy::Detect::Runner::Jruby,
45
- 'darwin' => Launchy::Detect::Runner::Jruby,
46
- 'cygwin' => Launchy::Detect::Runner::Jruby, }.each_pair do |host_os, runner|
47
- it "engine 'jruby' on OS '#{host_os}' uses runner #{runner.name}" do
48
- Launchy.host_os = host_os
49
- Launchy.ruby_engine = 'jruby'
50
- engine = Launchy::Detect::Runner.detect
51
- _(engine).must_be_instance_of runner
52
- end
53
- end
54
-
55
- # If you are on windows, no matter what engine, you use the windows runner
56
- %w[ ruby rbx jruby macruby ].each do |engine_name|
57
- it "uses a Windows runner when the engine is '#{engine_name}'" do
58
- Launchy.host_os = "mingw"
59
- Launchy.ruby_engine = engine_name
60
- e = Launchy::Detect::Runner.detect
61
- _(e).must_be_instance_of Launchy::Detect::Runner::Windows
62
- end
63
- end
64
-
65
- it "Windows launches use the 'cmd' command" do
66
- win = Launchy::Detect::Runner::Windows.new
67
- cmd = win.dry_run( "not-really", [ "http://example.com" ] )
68
- _(cmd).must_equal 'cmd /c not-really http://example.com'
69
- end
70
-
71
- %w[ & | ( ) < > ^ ].each do |reserved_char|
72
- it "Windows escapes '#{reserved_char}' in urls" do
73
- win = Launchy::Detect::Runner::Windows.new
74
- parts = [ 'http://example.com/?foo=bar', 'baz=wibble' ]
75
- url = parts.join( reserved_char )
76
- output_url = parts.join( "^#{reserved_char}" )
77
-
78
- _(win.all_args( "not-really", [ url ] )).must_equal [ 'cmd', '/c', 'not-really', output_url ]
79
-
80
- cmd = win.dry_run( "not-really", [ url ] )
81
- _(cmd).must_equal "cmd /c not-really #{output_url}"
82
- end
83
- end
84
-
85
- it "Jruby doesnot escapes '&' in urls" do
86
- jruby = Launchy::Detect::Runner::Jruby.new
87
- cmd = jruby.dry_run( "not-really", [ @test_url ])
88
- _(cmd).must_equal 'not-really http://example.com/?foo=bar&baz=wibble'
89
- end
90
-
91
- it "does not escape %38 items in urls" do
92
- l = Launchy::Detect::Runner::Forkable.new
93
- cmd = l.dry_run( "not-really", [ "https://ja.wikipedia.org/wiki/%E3%81%82" ] )
94
- _(cmd).must_equal( 'not-really https://ja.wikipedia.org/wiki/%E3%81%82' )
95
- end
96
-
97
- it "can launch a utf8 url" do
98
- url = "https://ja.wikipedia.org/wiki/あ"
99
- l = Launchy::Detect::Runner::Forkable.new
100
- cmd = l.dry_run( "not-really", [ url ] )
101
- _(cmd).must_equal( "not-really #{url}" )
102
- end
103
- end