feat(xbar/brew-services): handle new none and scheduled statuses

Also fetch data from brew services as JSON instead of parsing the plain
text output of `brew services list`.
This commit is contained in:
2022-03-01 18:54:22 +00:00
parent 1455f9d4b7
commit d8ced670f0

View File

@@ -2,7 +2,7 @@
# frozen_string_literal: true # frozen_string_literal: true
# <xbar.title>Brew Services</xbar.title> # <xbar.title>Brew Services</xbar.title>
# <xbar.version>v2.2.2</xbar.version> # <xbar.version>v2.3.0</xbar.version>
# <xbar.author>Jim Myhrberg</xbar.author> # <xbar.author>Jim Myhrberg</xbar.author>
# <xbar.author.github>jimeh</xbar.author.github> # <xbar.author.github>jimeh</xbar.author.github>
# <xbar.desc>List and manage Homebrew Services</xbar.desc> # <xbar.desc>List and manage Homebrew Services</xbar.desc>
@@ -44,6 +44,9 @@ module Xbar
private private
def print_item(text, **props) def print_item(text, **props)
props = props.dup
alt = props.delete(:alt)
output = [text] output = [text]
unless props.empty? unless props.empty?
props = normalize_props(props) props = normalize_props(props)
@@ -53,6 +56,10 @@ module Xbar
$stdout.print(SUB_STR * nested_level, output.join(' ')) $stdout.print(SUB_STR * nested_level, output.join(' '))
$stdout.puts $stdout.puts
return if alt.nil? || alt.empty?
print_item(alt, **props.merge(alternate: true))
end end
def plugin_refresh_uri def plugin_refresh_uri
@@ -141,37 +148,22 @@ module Brew
end end
class Service class Service
attr_reader :name, :status, :user attr_reader :name, :status, :user, :file, :exit_code
def self.from_line(line) def initialize(args = {})
parts = line.split @name = args.key?('name') ? args['name'] : args[:name]
name = parts[0] @status = args.key?('status') ? args['status'] : args[:status]
if %w[started stopped error unknown].include?(parts[1]) @user = args.key?('user') ? args['user'] : args[:user]
status = parts[1] @file = args.key?('file') ? args['file'] : args[:file]
user = parts[2] @exit_code = args.key?('exit_code') ? args['exit_code'] : args[:exit_code]
else
# Some services (dbus and logrotate for example) don't show a status
# when running "brew services list" at the moment. Instead they only
# show the service name and the user. So we work around this issue.
status = 'unknown'
user = parts[1]
end
new(name: name, status: status, user: user)
end
def initialize(name:, status:, user: nil)
@name = name
@status = status
@user = user
end end
def started? def started?
@started ||= @status.downcase == 'started' @started ||= %w[started scheduled].include?(@status.downcase)
end end
def stopped? def stopped?
@stopped ||= @status.downcase == 'stopped' @stopped ||= %w[stopped none].include?(@status.downcase)
end end
def error? def error?
@@ -331,8 +323,11 @@ module Brew
end end
printer.sep printer.sep
printer.item("State: #{service.status}") printer.item("Status: #{service.status}")
printer.item("User: #{service.user || '<none>'}") printer.item("User: #{service.user || '<none>'}")
if !service.exit_code.nil? && !service.started?
printer.item("Exit code: #{service.exit_code}")
end
if service.stopped? if service.stopped?
printer.sep printer.sep
@@ -368,17 +363,11 @@ module Brew
def services def services
return @services if @services return @services if @services
found = false output = cmd(brew_path, 'services', 'list', '--json')
@services = cmd( data = JSON.parse(output)
brew_path, 'services', 'list'
).each_line.each_with_object([]) do |line, memo|
# Ignore header line and everything before it.
unless found
found = line.strip.match(/^Name\s+Status\s+User\s+(File|Plist)$/)
next
end
memo.push(Service.from_line(line)) @services = data.each_with_object([]) do |item, memo|
memo.push(Service.new(item))
end end
end end
end end