diff --git a/xbar/brew-cask-updates.1h.rb b/xbar/brew-cask-updates.1h.rb
deleted file mode 100755
index 887f546..0000000
--- a/xbar/brew-cask-updates.1h.rb
+++ /dev/null
@@ -1,209 +0,0 @@
-#!/usr/bin/env ruby
-# frozen_string_literal: true
-
-# Brew Cask Updates
-# v2.0.0
-# Jim Myhrberg
-# jimeh
-# Show outdated Homebrew casks
-# https://i.imgur.com/aAD0pqO.png
-# ruby
-#
-# string(VAR_BREW_PATH="/usr/local/bin/brew"): Path to "brew" executable.
-
-# rubocop:disable Style/IfUnlessModifier
-
-require 'open3'
-require 'json'
-
-module Xbar
- class Printer
- attr_reader :nested_level
-
- SUB_STR = '--'
- SEP_STR = '---'
- PARAM_SEP = '|'
-
- def initialize(nested_level = 0)
- @nested_level = nested_level
- end
-
- def item(label = nil, **props)
- print_item(label, **props) if !label.nil? && !label.empty?
-
- yield(sub_printer) if block_given?
- end
-
- def separator
- print_item(SEP_STR)
- end
- alias sep separator
-
- private
-
- def print_item(text, **props)
- output = [text]
- unless props.empty?
- output << PARAM_SEP
- output += props.map { |k, v| "#{k}=\"#{v}\"" }
- end
-
- $stdout.print(SUB_STR * nested_level, output.join(' '))
- $stdout.puts
- end
-
- def sub_printer
- @sub_printer || self.class.new(nested_level + 1)
- end
- end
-end
-
-module Brew
- class CommandError < StandardError; end
-
- class Common
- def self.prefix(value = nil)
- return @prefix if value.nil? || value == ''
-
- @prefix = value
- end
-
- private
-
- def prefix
- self.class.prefix
- end
-
- def default_printer
- @default_printer ||= ::Xbar::Printer.new
- end
-
- def cmd(*args)
- out, err, s = Open3.capture3(*args)
- raise CommandError, "#{args.join(' ')}: #{err}" if s.exitstatus != 0
-
- out
- end
-
- def brew_path
- @brew_path ||= ENV.fetch('VAR_BREW_PATH', '/usr/local/bin/brew')
- end
-
- def brew_check(printer = nil)
- printer ||= default_printer
- return if File.exist?(brew_path)
-
- printer.item("#{prefix}↑:warning:", dropdown: false)
- printer.sep
- printer.item('Homebrew not found', color: 'red')
- printer.item("Executable \"#{brew_path}\" does not exist.")
- printer.sep
- printer.item(
- 'Visit https://brew.sh/ for installation instructions',
- href: 'https://brew.sh'
- )
-
- exit 0
- end
-
- def brew_update
- cmd(brew_path, 'update')
- rescue CommandError => e
- # Continue as if nothing happened when brew update fails, as it likely
- # to be due to another update process is already running.
- end
- end
-
- class Cask
- attr_reader :name, :installed_version, :latest_version
-
- def initialize(attributes = {})
- @name = attributes['name']
- @installed_version = attributes['installed_versions']
- @latest_version = attributes['current_version']
- end
-
- alias current_version installed_version
- end
-
- class CaskUpdates < Common
- prefix ':tropical_drink:'
-
- def run
- printer = default_printer
-
- brew_check(printer)
- brew_update
-
- printer.item("#{prefix}↑#{casks.size}", dropdown: false)
- printer.sep
- printer.item('Brew Cask Updates')
- printer.item("#{casks.size} outdated") do |printer|
- printer.sep
- printer.item(':hourglass: Refresh', refresh: true)
- end
-
- print_casks(printer)
- printer.sep
- printer.item('Refresh', refresh: true)
- end
-
- private
-
- def print_casks(printer)
- return unless casks.size.positive?
-
- printer.item(
- 'Upgrade all casks',
- terminal: true, refresh: true,
- shell: brew_path, param1: 'upgrade'
- )
- printer.sep
- printer.item('Upgrade:')
- casks.each do |cask|
- printer.item(cask.name) do |printer|
- printer.item(
- 'Upgrade',
- terminal: true, refresh: true, shell: brew_path,
- param1: 'upgrade', param2: '--cask', param3: cask.name
- )
- printer.item(
- "Upgrade (#{cask.current_version} → #{cask.latest_version})",
- alternate: true, terminal: true, refresh: true,
- shell: brew_path, param1: 'upgrade', param2: '--cask',
- param3: cask.name
- )
- printer.sep
- printer.item("Installed: #{cask.installed_version}")
- printer.item("Latest: #{cask.latest_version}")
- printer.sep
- printer.item('Uninstall') do |printer|
- printer.item('Are you sure?')
- printer.sep
- printer.item(
- 'Yes',
- terminal: true, refresh: true,
- shell: brew_path, param1: 'uninstall',
- param2: '--cask', param3: cask.name
- )
- end
- end
- end
- end
-
- def casks
- @casks ||= JSON.parse(
- cmd(brew_path, 'outdated', '--cask', '--json')
- )['casks'].map { |line| Cask.new(line) }
- end
- end
-end
-
-begin
- Brew::CaskUpdates.new.run
-rescue StandardError => e
- puts "ERROR: #{e.message}:\n\t#{e.backtrace.join("\n\t")}"
- exit 1
-end
-
-# rubocop:enable Style/IfUnlessModifier
diff --git a/xbar/brew-formula-updates.1h.rb b/xbar/brew-updates.1h.rb
similarity index 67%
rename from xbar/brew-formula-updates.1h.rb
rename to xbar/brew-updates.1h.rb
index efb609f..fd5cd5d 100755
--- a/xbar/brew-formula-updates.1h.rb
+++ b/xbar/brew-updates.1h.rb
@@ -1,12 +1,12 @@
#!/usr/bin/env ruby
# frozen_string_literal: true
-# Brew Formula Updates
+# Brew Updates
# v2.0.0
# Jim Myhrberg
# jimeh
-# Show outdated Homebrew formulas
-# https://i.imgur.com/6PC6OPg.png
+# List and manage outdated Homebrew formulas and casks
+# https://i.imgur.com/gHrTZpd.png
# ruby
#
# string(VAR_BREW_PATH="/usr/local/bin/brew"): Path to "brew" executable.
@@ -131,8 +131,20 @@ module Brew
end
end
+ class Cask
+ attr_reader :name, :installed_version, :latest_version
+
+ def initialize(attributes = {})
+ @name = attributes['name']
+ @installed_version = attributes['installed_versions']
+ @latest_version = attributes['current_version']
+ end
+
+ alias current_version installed_version
+ end
+
class FormulaUpdates < Common
- prefix ':beer:'
+ prefix ':beers:'
def run
printer = default_printer
@@ -140,21 +152,28 @@ module Brew
brew_check(printer)
brew_update
- printer.item("#{prefix}↑#{formulas.size}", dropdown: false)
+ printer.item("#{prefix}↑#{formulas.size + casks.size}", dropdown: false)
printer.sep
- printer.item('Brew Formula Updates')
+ printer.item('Brew Updates')
pinned_msg = " / #{pinned.size} pinned" if pinned.size.positive?
printer.item(
- "#{formulas.size} outdated#{pinned_msg}"
+ "#{formulas.size} formulas / #{casks.size} casks#{pinned_msg}"
) do |printer|
printer.sep
printer.item(':hourglass: Refresh', refresh: true)
end
+ printer.item('Upgrade All') do |printer|
+ printer.item('Are you sure?')
+ printer.item(
+ 'Yes',
+ terminal: true, refresh: true, shell: brew_path, param1: 'upgrade'
+ )
+ end
print_formulas(printer)
+ print_casks(printer)
print_pinned(printer)
printer.sep
- printer.item('Refresh', refresh: true)
end
private
@@ -162,12 +181,16 @@ module Brew
def print_formulas(printer)
return unless formulas.size.positive?
- printer.item(
- 'Upgrade all formula',
- terminal: true, refresh: true, shell: brew_path, param1: 'upgrade'
- )
printer.sep
- printer.item('Upgrade:')
+ printer.item('Formulas:')
+ printer.item('Upgrade All') do |printer|
+ printer.item('Are you sure?')
+ printer.item(
+ 'Yes',
+ terminal: true, refresh: true, shell: brew_path, param1: 'upgrade',
+ param2: '--formula'
+ )
+ end
formulas.each do |formula|
printer.item(formula.name) do |printer|
printer.item(
@@ -196,7 +219,6 @@ module Brew
)
printer.item('Uninstall') do |printer|
printer.item('Are you sure?')
- printer.sep
printer.item(
'Yes',
terminal: true, refresh: true,
@@ -207,11 +229,55 @@ module Brew
end
end
+ def print_casks(printer)
+ return unless casks.size.positive?
+
+ printer.sep
+ printer.item('Casks:')
+ printer.item('Upgrade All') do |printer|
+ printer.item('Are you sure?')
+ printer.item(
+ 'Yes',
+ terminal: true, refresh: true,
+ shell: brew_path, param1: 'upgrade', param2: '--cask'
+ )
+ end
+ casks.each do |cask|
+ printer.item(cask.name) do |printer|
+ printer.item(
+ 'Upgrade',
+ terminal: true, refresh: true, shell: brew_path,
+ param1: 'upgrade', param2: '--cask', param3: cask.name
+ )
+ printer.item(
+ "Upgrade (#{cask.current_version} → #{cask.latest_version})",
+ alternate: true, terminal: true, refresh: true,
+ shell: brew_path, param1: 'upgrade', param2: '--cask',
+ param3: cask.name
+ )
+ printer.sep
+ printer.item("Installed: #{cask.installed_version}")
+ printer.item("Latest: #{cask.latest_version}")
+ printer.sep
+ printer.item('Uninstall') do |printer|
+ printer.item('Are you sure?')
+ printer.sep
+ printer.item(
+ 'Yes',
+ terminal: true, refresh: true,
+ shell: brew_path, param1: 'uninstall',
+ param2: '--cask', param3: cask.name
+ )
+ end
+ end
+ end
+ end
+
def print_pinned(printer)
return unless pinned.size.positive?
printer.sep
- printer.item('Pinned:')
+ printer.item('Pinned Formulas:')
pinned.each do |formula|
printer.item(formula.name) do |printer|
printer.item('Upgrade')
@@ -233,7 +299,6 @@ module Brew
)
printer.item('Uninstall') do |printer|
printer.item('Are you sure?')
- printer.sep
printer.item(
'Yes',
terminal: true, refresh: true,
@@ -245,17 +310,23 @@ module Brew
end
def formulas
- @formulas ||= outdated.reject(&:pinned)
+ @formulas ||= all_formulas.reject(&:pinned)
end
def pinned
- @pinned ||= outdated.select(&:pinned)
+ @pinned ||= all_formulas.select(&:pinned)
+ end
+
+ def all_formulas
+ @all_formulas ||= outdated['formulae'].map { |line| Formula.new(line) }
+ end
+
+ def casks
+ @casks ||= outdated['casks'].map { |line| Cask.new(line) }
end
def outdated
- @outdated ||= JSON.parse(
- cmd(brew_path, 'outdated', '--formula', '--json')
- )['formulae'].map { |line| Formula.new(line) }
+ @outdated ||= JSON.parse(cmd(brew_path, 'outdated', '--json'))
end
end
end