#!/usr/bin/env ruby # frozen_string_literal: true # # list_running_app_ids # ### ### dependencies ### require "open3" require "set" require "io/console" ### ### globals ### # rubocop:disable Style/GlobalVars $opt_test = nil $COLUMNS = IO.console.winsize.last ### ### methods ### def check_ruby return if RUBY_VERSION.to_f >= 2.0 print "You are currently using Ruby ", RUBY_VERSION, ", but version 2.0 or above is required." exit 1 end def usage <<~EOS list_running_app_ids [ -t ] Print a list of currently running Applications and associated Bundle IDs, which may be useful in a Cask uninstall stanza, eg uninstall quit: 'bundle.id.goes.here' Applications attributed to Apple are excluded from the output. With optional "-t ", silently test if a given app is running, exiting with an error code if not. See CONTRIBUTING.md for more information. EOS end def process_args until ARGV.empty? if ARGV.first =~ /^-+t(?:est)?$/ && ARGV.length > 1 ARGV.shift $opt_test = ARGV.shift elsif /^-+h(?:elp)?$/.match?(ARGV.first) puts usage exit 0 else puts usage exit 1 end end end def load_apps out, err, status = Open3.capture3("/usr/bin/osascript", "-e", 'tell application "System Events" to get (name, bundle identifier, unix id) of every process') if status.exitstatus.positive? puts err exit status.exitstatus end out = out.split(", ") one_third = out.length / 3 @app_names = out.shift(one_third) @bundle_ids = out.shift(one_third) @unix_ids = out.shift(one_third) end def test_app(bundle) @bundle_ids.include?(bundle) ? 0 : 1 end def excluded_bundle_id(bundle_id) /^com\.apple\./.match(bundle_id) end def excluded_app_name(app_name) /^osascript$/.match(app_name) # this script itself end def report_apps running = Set.new @app_names.zip(@bundle_ids, @unix_ids).each do |app_name, bundle_id, _unix_id| next if excluded_bundle_id bundle_id next if excluded_app_name app_name bundle_id.gsub!(/^(missing value)$/, '<\1>') running.add "#{bundle_id.ljust($COLUMNS / 2)}\t#{app_name}" end puts "#{"bundle_id".ljust($COLUMNS / 2)}\tapp_name" puts "-" * $COLUMNS puts running.to_a.sort.join "\n" end ### ### main ### check_ruby process_args load_apps if $opt_test exit test_app($opt_test) else report_apps end # rubocop:enable Style/GlobalVars