diff --git a/Library/Homebrew/cmd/services.rb b/Library/Homebrew/cmd/services.rb index f072813778..ac0f3872c3 100644 --- a/Library/Homebrew/cmd/services.rb +++ b/Library/Homebrew/cmd/services.rb @@ -38,8 +38,9 @@ module Homebrew [`sudo`] `brew services start` (|`--all`|`--file=`): Start the service immediately and register it to launch at login (or boot). - [`sudo`] `brew services stop` (|`--all`): - Stop the service immediately and unregister it from launching at login (or boot). + [`sudo`] `brew services stop` (`--keep`) (`--no-wait`|`--max-wait=`) (|`--all`): + Stop the service immediately and unregister it from launching at login (or boot), + unless `--keep` is specified. [`sudo`] `brew services kill` (|`--all`): Stop the service immediately but keep it registered to launch at login (or boot). @@ -57,6 +58,7 @@ module Homebrew switch "--all", description: "Run on all services." switch "--json", description: "Output as JSON." switch "--no-wait", description: "Don't wait for `stop` to finish stopping the service." + switch "--keep", description: "When stopped, don't unregister the service from launching at login (or boot)." conflicts "--max-wait=", "--no-wait" named_args end @@ -117,6 +119,14 @@ module Homebrew end end + unless Homebrew::Services::Commands::Stop::TRIGGERS.include?(subcommand) + raise UsageError, "The `#{subcommand}` subcommand does not accept the --keep argument!" if args.keep? + raise UsageError, "The `#{subcommand}` subcommand does not accept the --no-wait argument!" if args.no_wait? + if args.max_wait + raise UsageError, "The `#{subcommand}` subcommand does not accept the --max-wait= argument!" + end + end + opoo "The --all argument overrides provided formula argument!" if formulae.present? && args.all? targets = if args.all? @@ -162,8 +172,13 @@ module Homebrew when *Homebrew::Services::Commands::Start::TRIGGERS Homebrew::Services::Commands::Start.run(targets, args.file, verbose: args.verbose?) when *Homebrew::Services::Commands::Stop::TRIGGERS - max_wait = args.max_wait.to_f - Homebrew::Services::Commands::Stop.run(targets, verbose: args.verbose?, no_wait: args.no_wait?, max_wait:) + Homebrew::Services::Commands::Stop.run( + targets, + verbose: args.verbose?, + no_wait: args.no_wait?, + max_wait: args.max_wait.to_f, + keep: args.keep?, + ) when *Homebrew::Services::Commands::Kill::TRIGGERS Homebrew::Services::Commands::Kill.run(targets, verbose: args.verbose?) else diff --git a/Library/Homebrew/services/cli.rb b/Library/Homebrew/services/cli.rb index 8e7e009526..0694b05bf0 100644 --- a/Library/Homebrew/services/cli.rb +++ b/Library/Homebrew/services/cli.rb @@ -159,12 +159,13 @@ module Homebrew verbose: T::Boolean, no_wait: T::Boolean, max_wait: T.nilable(T.any(Integer, Float)), + keep: T::Boolean, ).void } - def self.stop(targets, verbose: false, no_wait: false, max_wait: 0) + def self.stop(targets, verbose: false, no_wait: false, max_wait: 0, keep: false) targets.each do |service| unless service.loaded? - rm service.dest if service.dest.exist? # get rid of installed service file anyway, dude + rm service.dest if !keep && service.dest.exist? # get rid of installed service file anyway, dude if service.service_file_present? odie <<~EOS Service `#{service.name}` is started as `#{service.owner}`. Try: @@ -188,7 +189,11 @@ module Homebrew end if System.systemctl? - System::Systemctl.quiet_run(*systemctl_args, "disable", "--now", service.service_name) + if keep + System::Systemctl.quiet_run(*systemctl_args, "stop", service.service_name) + else + System::Systemctl.quiet_run(*systemctl_args, "disable", "--now", service.service_name) + end elsif System.launchctl? quiet_system System.launchctl, "bootout", "#{System.domain_target}/#{service.service_name}" unless no_wait @@ -204,9 +209,11 @@ module Homebrew quiet_system System.launchctl, "stop", "#{System.domain_target}/#{service.service_name}" if service.pid? end - rm service.dest if service.dest.exist? - # Run daemon-reload on systemctl to finish unloading stopped and deleted service. - System::Systemctl.run(*systemctl_args, "daemon-reload") if System.systemctl? + unless keep + rm service.dest if service.dest.exist? + # Run daemon-reload on systemctl to finish unloading stopped and deleted service. + System::Systemctl.run(*systemctl_args, "daemon-reload") if System.systemctl? + end if service.pid? || service.loaded? opoo "Unable to stop `#{service.name}` (label: #{service.service_name})" diff --git a/Library/Homebrew/services/commands/stop.rb b/Library/Homebrew/services/commands/stop.rb index 2b9136da10..bdf1882e06 100644 --- a/Library/Homebrew/services/commands/stop.rb +++ b/Library/Homebrew/services/commands/stop.rb @@ -15,11 +15,12 @@ module Homebrew verbose: T::Boolean, no_wait: T::Boolean, max_wait: T.nilable(Float), + keep: T::Boolean, ).void } - def self.run(targets, verbose:, no_wait:, max_wait:) + def self.run(targets, verbose:, no_wait:, max_wait:, keep:) Services::Cli.check(targets) - Services::Cli.stop(targets, verbose:, no_wait:, max_wait:) + Services::Cli.stop(targets, verbose:, no_wait:, max_wait:, keep:) end end end diff --git a/Library/Homebrew/sorbet/rbi/dsl/homebrew/cmd/services.rbi b/Library/Homebrew/sorbet/rbi/dsl/homebrew/cmd/services.rbi index 704adb3658..7660126179 100644 --- a/Library/Homebrew/sorbet/rbi/dsl/homebrew/cmd/services.rbi +++ b/Library/Homebrew/sorbet/rbi/dsl/homebrew/cmd/services.rbi @@ -20,6 +20,9 @@ class Homebrew::Cmd::Services::Args < Homebrew::CLI::Args sig { returns(T::Boolean) } def json?; end + sig { returns(T::Boolean) } + def keep?; end + sig { returns(T.nilable(String)) } def max_wait; end