Class: Space::Src::CLI::Daemon::Uninstall

Inherits:
Dry::CLI::Command
  • Object
show all
Includes:
Helpers, GlobalOptions
Defined in:
lib/space_src/cli/daemon.rb

Instance Method Summary collapse

Methods included from GlobalOptions

included

Methods included from Helpers

build_plist, fail_with, format_failure, make_agent, plist_path

Instance Method Details

#call(plain: nil, json: nil, no_color: nil, quiet: nil) ⇒ Object



148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/space_src/cli/daemon.rb', line 148

def call(plain: nil, json: nil, no_color: nil, quiet: nil, **)
  mode = UI::Mode.resolve(
    flags: {plain: plain, json: json, no_color: no_color, quiet: quiet},
    env: CLI.env,
    out: out
  )
  pastel = Pastel.new(enabled: mode.color)

  paths = CLI.make_paths
  label = Launchd::Agent::DEFAULT_LABEL
  pp = plist_path(paths, label)

  agent = make_agent
  result = agent.uninstall
  # CF5 (Slice 5): the Agent maps a not-loaded bootout
  # (status 3 / "No such process") to Success — the
  # common case at a 6h refresh interval. A non-benign
  # bootout Failure (e.g. status 1 "Operation not
  # permitted") still surfaces here as a real failure
  # the operator needs to see. We still remove the
  # plist regardless (idempotent uninstall, Slice-4
  # gate G3): the bootout is the only best-effort step.
  if result.failure?
    err.puts "bootout reported: #{format_failure(result.failure)}"
  end

  if File.exist?(pp)
    File.delete(pp)
    out.puts pastel.green("removed plist: #{pp}")
  else
    out.puts pastel.yellow("plist not present: #{pp}")
  end

  CLI.record_outcome(Outcome.new(exit_code: 0))
end