dotfiles

My personal shell configs and stuff
git clone git://git.alex.balgavy.eu/dotfiles.git
Log | Files | Refs | Submodules | README | LICENSE

commit c0fbdeee6486517d638b25e576b1ed3cd6a10c20
parent d4341655e9e3d47dd2c3ea1bc657c839ce71593f
Author: Alex Balgavy <alex@balgavy.eu>
Date:   Wed, 13 Jan 2021 23:02:27 +0100

updatemaster: fix caffeination, add NPM and gems

Diffstat:
Mscripts/updatemaster | 156+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------
1 file changed, 116 insertions(+), 40 deletions(-)

diff --git a/scripts/updatemaster b/scripts/updatemaster @@ -1,6 +1,5 @@ #!/usr/bin/env ruby # frozen_string_literal: true -# TODO: check caffeinate termination def check_deps(deps) deps.each do |dep| @@ -11,10 +10,6 @@ def check_deps(deps) end end -def stay_awake - system `caffeinate -d` -end - # The Homebrew package manager for macOS class Homebrew def initialize @@ -26,36 +21,51 @@ class Homebrew @outdated_formulae = `brew outdated --formula` end + def start_sudo_cache + puts 'Please enter the administrator password to install cask upgrades.' + system 'sudo -v' + @sudo_cache_pid = spawn 'while :; do sudo -n true; sleep 60; done 2>/dev/null' + end + def prompt_user + return if @outdated_casks.empty? + puts "\nOutdated casks:" @outdated_casks.each_with_index { |c, i| puts "#{i} #{c}" } print 'Numbers of casks to upgrade (space-separated): ' begin - @to_upgrade = gets.chomp.split.map { |casknum| @cask_names[Integer(casknum)] } + @to_upgrade = $stdin.gets.chomp.split.map { |casknum| @cask_names[Integer(casknum)] } rescue ArgumentError warn 'Only numbers allowed' exit 1 end - - puts "Please enter the administrator password to install cask upgrades." - system 'sudo -v' - @sudo_cache_pid = spawn "while :; do sudo -n true; sleep 60; done 2>/dev/null" + start_sudo_cache end def do_upgrade - puts "\nUpgrading all formulae.\nTo upgrade:" - puts @outdated_formulae - system 'brew upgrade --formula' + if @outdated_formulae.empty? + puts "\nNo formulae to upgrade." + else + puts "\nUpgrading all formulae.\nTo upgrade:" + puts @outdated_formulae + system 'brew upgrade --formula' + end + + return if @outdated_casks.empty? - puts "\nUpgrading casks:" - puts @to_upgrade + if @to_upgrade.empty? + puts 'Not upgrading any casks.' + else + puts "\nUpgrading casks:" + puts @to_upgrade - @to_upgrade.each { |cask| system "brew upgrade --cask --greedy --verbose #{cask}" } - puts 'Upgrade complete.' + @to_upgrade.each { |cask| system "brew upgrade --cask --greedy --verbose #{cask}" } + puts 'Upgrade complete.' + end end def cleanup - Process.kill "TERM", @sudo_cache_pid + Process.kill('TERM', @sudo_cache_pid) if @sudo_cache_pid system 'brew cleanup -s --prune-prefix' system 'brew cleanup' system 'brew doctor' @@ -79,30 +89,96 @@ class Pipx end end -begin - caffeine_thread = Thread.new { stay_awake } - package_systems = [Homebrew, Pipx] - - # Do all the prompting up front - systems_with_prompt = package_systems.select { |s| s.method_defined? 'prompt_user' } - unless systems_with_prompt.empty? - system_instances = systems_with_prompt.map(&:new) - system_instances.each(&:prompt_user) - system_instances.each do |pksys| - pksys.do_upgrade - pksys.cleanup if pksys.class.method_defined? 'cleanup' - end - package_systems -= systems_with_prompt +# Gems for Ruby +class RubyGems + def initialize + check_deps ['gem'] + puts '-- GEM --' + puts 'To upgrade:' + system 'gem outdated' end - # Complete remaining package systems - package_systems.each do |pksys_class| - pksys = pksys_class.new - pksys.prompt_user if pksys_class.method_defined? 'prompt_user' - pksys.do_upgrade - pksys.cleanup if pksys.class.method_defined? 'cleanup' + def do_upgrade + system 'gem update' end -rescue SystemExit, Interrupt - caffeine_thread.join + + def cleanup + system 'gem cleanup' + end +end + +# NPM for JS +class NPM + def initialize + check_deps ['npm'] + puts '-- NPM --' + puts 'To upgrade:' + system 'npm -g outdated' + end + + def do_upgrade + outdated = `npm outdated -g --parseable | sed 's!:.*!!g; s!.*/!!'`.split + outdated.each { |pkg| system "npm -g install #{pkg}@latest" } + system 'npm -g update' + end + + def cleanup + system 'npm -g dedupe' + system 'npm -g prune' + end +end + +def do_prompts(systems) + system_instances = systems.map(&:new) + system_instances.each(&:prompt_user) if (['-n', '--dry-run'] & ARGV).empty? + system_instances +end + +def split_systems_by_prompting(all_systems) + systems_with_prompt = all_systems.select { |s| s.method_defined? 'prompt_user' } + { prompting: systems_with_prompt, + no_prompting: all_systems - systems_with_prompt } +end + +def upgrade_cleanup(system_instance) + system_instance.do_upgrade if (['-n', '--dry-run'] & ARGV).empty? + system_instance.cleanup if system_instance.class.method_defined? 'cleanup' +end + +def main + package_systems = [Homebrew, Pipx, RubyGems, NPM] + + split_systems = split_systems_by_prompting package_systems + + # Do any prompts to get interactivity out of the way, then upgrade those first + do_prompts(split_systems[:prompting]).each { |s| upgrade_cleanup s } unless split_systems[:prompting].empty? + + # Finish up by upgrading systems that don't need user input + split_systems[:no_prompting].each do |nonprompting_sys| + pksys = nonprompting_sys.new + upgrade_cleanup pksys + end +end + +def handle_help + return if (['-h', '--help'] & ARGV).empty? + + puts <<~END_HELPTEXT + Usage: updatemaster [options] + + Options: + -h, --help display this helptext + -n, --dry-run don't upgrade anything, only update & cleanup + END_HELPTEXT exit 0 end + +handle_help +begin + caffeinate = spawn 'caffeinate -d' + main +rescue SystemExit, Interrupt + puts "\nInterrupted, exiting..." +end +Process.kill('SIGTERM', caffeinate) +Process.detach(caffeinate)