File: launchy.rb

package info (click to toggle)
ruby-launchy 3.1.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 304 kB
  • sloc: ruby: 1,051; makefile: 6
file content (171 lines) | stat: -rw-r--r-- 4,502 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# frozen_string_literal: true

require "English"
require "addressable/uri"
require "shellwords"
require "stringio"

#
# The entry point into Launchy. This is the sole supported public API.
#
#   Launchy.open( uri, options = {} )
#
# The currently defined global options are:
#
#   :debug        Turn on debugging output
#   :application  Explicitly state what application class is going to be used.
#                 This must be a child class of Launchy::Application
#   :host_os      Explicitly state what host operating system to pretend to be
#   :dry_run      Do nothing and print the command that would be executed on $stdout
#
# Other options may be used, and those will be passed directly to the
# application class
#
module Launchy
  class << self
    #
    # Launch an application for the given uri string
    #
    def open(uri_s, options = {})
      leftover = extract_global_options(options)
      uri = string_to_uri(uri_s)
      if (name = options[:application])
        app = app_for_name(name)
      end

      app = app_for_uri(uri) if app.nil?

      app.new.open(uri, leftover)
    rescue Launchy::Error => e
      raise e
    rescue StandardError => e
      msg = "Failure in opening uri #{uri_s.inspect} with options #{options.inspect}: #{e}"
      raise Launchy::Error, msg
    ensure
      if $ERROR_INFO && block_given?
        yield $ERROR_INFO

        # explicitly return here to swallow the errors if there was an error
        # and we yielded to the block
        # rubocop:disable Lint/EnsureReturn
        return
        # rubocop:enable Lint/EnsureReturn
      end
    end

    def app_for_uri(uri)
      Launchy::Application.handling(uri)
    end

    def app_for_name(name)
      Launchy::Application.for_name(name)
    rescue Launchy::ApplicationNotFoundError
      nil
    end

    def app_for_uri_string(str)
      app_for_uri(string_to_uri(str))
    end

    def string_to_uri(str)
      str = str.to_s
      uri = Addressable::URI.parse(str)
      Launchy.log "URI parsing pass 1 : #{str} -> #{uri.to_hash}"
      unless uri.scheme
        uri = Addressable::URI.heuristic_parse(str)
        Launchy.log "URI parsing pass 2 : #{str} -> #{uri.to_hash}"
      end
      raise Launchy::ArgumentError, "Invalid URI given: #{str.inspect}" unless uri

      uri
    end

    def reset_global_options
      Launchy.debug       = false
      Launchy.application = nil
      Launchy.host_os     = nil
      Launchy.dry_run     = false
      Launchy.path        = ENV.fetch("PATH", nil)
    end

    def extract_global_options(options)
      leftover = options.dup
      Launchy.debug        = leftover.delete(:debug) || ENV.fetch("LAUNCHY_DEBUG", nil)
      Launchy.application  = leftover.delete(:application) || ENV.fetch("LAUNCHY_APPLICATION", nil)
      Launchy.host_os      = leftover.delete(:host_os) || ENV.fetch("LAUNCHY_HOST_OS", nil)
      Launchy.dry_run      = leftover.delete(:dry_run) || ENV.fetch("LAUNCHY_DRY_RUN", nil)
    end

    def debug=(enabled)
      @debug = to_bool(enabled)
    end

    # we may do logging before a call to 'open', hence the need to check
    # LAUNCHY_DEBUG here
    def debug?
      @debug || to_bool(ENV.fetch("LAUNCHY_DEBUG", nil))
    end

    def application=(app)
      @application = app
    end

    def application
      @application || ENV.fetch("LAUNCHY_APPLICATION", nil)
    end

    def host_os=(host_os)
      @host_os = host_os
    end

    def host_os
      @host_os || ENV.fetch("LAUNCHY_HOST_OS", nil)
    end

    def dry_run=(dry_run)
      @dry_run = to_bool(dry_run)
    end

    def dry_run?
      @dry_run || to_bool(ENV.fetch("LAUNCHY_DRY_RUN", nil))
    end

    def bug_report_message
      "Please rerun with environment variable LAUNCHY_DEBUG=true or the '-d' commandline option and file a bug at https://github.com/copiousfreetime/launchy/issues/new"
    end

    def log(msg)
      $stderr.puts "LAUNCHY_DEBUG: #{msg}" if Launchy.debug?
    end

    def path
      @path
    end

    def path=(path)
      @path = path
    end

    private

    def to_bool(arg)
      if arg.is_a? String
        arg == "true"
      else
        arg.is_a? TrueClass
      end
    end
  end

  # Iniitialize the global options to sane defaults during parse time.
  Launchy.reset_global_options
end

require "launchy/version"
require "launchy/argv"
require "launchy/cli"
require "launchy/descendant_tracker"
require "launchy/error"
require "launchy/application"
require "launchy/detect"
require "launchy/runner"