mirror of
https://github.com/Homebrew/brew.git
synced 2025-07-14 16:09:03 +08:00
Cleanup and fix homebrew-services migration
This commit is contained in:
parent
3ef52e4844
commit
084ddca27a
@ -12,11 +12,6 @@
|
||||
"permissions": {
|
||||
"contents": "write"
|
||||
}
|
||||
},
|
||||
"Homebrew/homebrew-services": {
|
||||
"permissions": {
|
||||
"contents": "write"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -25,7 +25,6 @@ brew cleanup
|
||||
brew tap --force homebrew/core
|
||||
# tap some other repos so codespaces can be used for developing multiple taps
|
||||
brew tap homebrew/bundle
|
||||
brew tap homebrew/services
|
||||
|
||||
# install some useful development things
|
||||
sudo apt-get update
|
||||
|
@ -2,7 +2,16 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "abstract_command"
|
||||
require "services/service"
|
||||
require "services/system"
|
||||
require "services/cli"
|
||||
require "services/commands/list"
|
||||
require "services/commands/cleanup"
|
||||
require "services/commands/info"
|
||||
require "services/commands/restart"
|
||||
require "services/commands/run"
|
||||
require "services/commands/start"
|
||||
require "services/commands/stop"
|
||||
require "services/commands/kill"
|
||||
|
||||
module Homebrew
|
||||
module Cmd
|
||||
@ -64,36 +73,36 @@ module Homebrew
|
||||
# Keep this after the .parse to keep --help fast.
|
||||
require "utils"
|
||||
|
||||
if !::Service::System.launchctl? && !::Service::System.systemctl?
|
||||
if !::Services::System.launchctl? && !::Services::System.systemctl?
|
||||
raise UsageError,
|
||||
"`brew services` is supported only on macOS or Linux (with systemd)!"
|
||||
end
|
||||
|
||||
if (sudo_service_user = args.sudo_service_user)
|
||||
unless ::Service::System.root?
|
||||
unless ::Services::System.root?
|
||||
raise UsageError,
|
||||
"`brew services` is supported only when running as root!"
|
||||
end
|
||||
|
||||
unless ::Service::System.launchctl?
|
||||
unless ::Services::System.launchctl?
|
||||
raise UsageError,
|
||||
"`brew services --sudo-service-user` is currently supported only on macOS " \
|
||||
"(but we'd love a PR to add Linux support)!"
|
||||
end
|
||||
|
||||
::Service::ServicesCli.sudo_service_user = sudo_service_user
|
||||
::Services::Cli.sudo_service_user = sudo_service_user
|
||||
end
|
||||
|
||||
# Parse arguments.
|
||||
subcommand, formula, = args.named
|
||||
|
||||
if [*::Service::Commands::List::TRIGGERS, *::Service::Commands::Cleanup::TRIGGERS].include?(subcommand)
|
||||
if [*::Services::Commands::List::TRIGGERS, *::Services::Commands::Cleanup::TRIGGERS].include?(subcommand)
|
||||
raise UsageError, "The `#{subcommand}` subcommand does not accept a formula argument!" if formula
|
||||
raise UsageError, "The `#{subcommand}` subcommand does not accept the --all argument!" if args.all?
|
||||
end
|
||||
|
||||
if args.file
|
||||
if ::Service::Commands::Start::TRIGGERS.exclude?(subcommand)
|
||||
if ::Services::Commands::Start::TRIGGERS.exclude?(subcommand)
|
||||
raise UsageError, "The `#{subcommand}` subcommand does not accept the --file= argument!"
|
||||
elsif args.all?
|
||||
raise UsageError, "The start subcommand does not accept the --all and --file= arguments at the same time!"
|
||||
@ -104,14 +113,14 @@ module Homebrew
|
||||
|
||||
targets = if args.all?
|
||||
if subcommand == "start"
|
||||
::Service::Formulae.available_services(loaded: false, skip_root: !::Service::System.root?)
|
||||
::Services::Formulae.available_services(loaded: false, skip_root: !::Services::System.root?)
|
||||
elsif subcommand == "stop"
|
||||
::Service::Formulae.available_services(loaded: true, skip_root: !::Service::System.root?)
|
||||
::Services::Formulae.available_services(loaded: true, skip_root: !::Services::System.root?)
|
||||
else
|
||||
::Service::Formulae.available_services
|
||||
::Services::Formulae.available_services
|
||||
end
|
||||
elsif formula
|
||||
[::Service::FormulaWrapper.new(Formulary.factory(formula))]
|
||||
[::Services::FormulaWrapper.new(Formulary.factory(formula))]
|
||||
else
|
||||
[]
|
||||
end
|
||||
@ -119,30 +128,30 @@ module Homebrew
|
||||
# Exit successfully if --all was used but there is nothing to do
|
||||
return if args.all? && targets.empty?
|
||||
|
||||
if ::Service::System.systemctl?
|
||||
if ::Services::System.systemctl?
|
||||
ENV["DBUS_SESSION_BUS_ADDRESS"] = ENV.fetch("HOMEBREW_DBUS_SESSION_BUS_ADDRESS", nil)
|
||||
ENV["XDG_RUNTIME_DIR"] = ENV.fetch("HOMEBREW_XDG_RUNTIME_DIR", nil)
|
||||
end
|
||||
|
||||
# Dispatch commands and aliases.
|
||||
case subcommand.presence
|
||||
when *::Service::Commands::List::TRIGGERS
|
||||
::Service::Commands::List.run(json: args.json?)
|
||||
when *::Service::Commands::Cleanup::TRIGGERS
|
||||
::Service::Commands::Cleanup.run
|
||||
when *::Service::Commands::Info::TRIGGERS
|
||||
::Service::Commands::Info.run(targets, verbose: args.verbose?, json: args.json?)
|
||||
when *::Service::Commands::Restart::TRIGGERS
|
||||
::Service::Commands::Restart.run(targets, verbose: args.verbose?)
|
||||
when *::Service::Commands::Run::TRIGGERS
|
||||
::Service::Commands::Run.run(targets, verbose: args.verbose?)
|
||||
when *::Service::Commands::Start::TRIGGERS
|
||||
::Service::Commands::Start.run(targets, args.file, verbose: args.verbose?)
|
||||
when *::Service::Commands::Stop::TRIGGERS
|
||||
when *::Services::Commands::List::TRIGGERS
|
||||
::Services::Commands::List.run(json: args.json?)
|
||||
when *::Services::Commands::Cleanup::TRIGGERS
|
||||
::Services::Commands::Cleanup.run
|
||||
when *::Services::Commands::Info::TRIGGERS
|
||||
::Services::Commands::Info.run(targets, verbose: args.verbose?, json: args.json?)
|
||||
when *::Services::Commands::Restart::TRIGGERS
|
||||
::Services::Commands::Restart.run(targets, verbose: args.verbose?)
|
||||
when *::Services::Commands::Run::TRIGGERS
|
||||
::Services::Commands::Run.run(targets, verbose: args.verbose?)
|
||||
when *::Services::Commands::Start::TRIGGERS
|
||||
::Services::Commands::Start.run(targets, args.file, verbose: args.verbose?)
|
||||
when *::Services::Commands::Stop::TRIGGERS
|
||||
max_wait = args.max_wait.to_f
|
||||
::Service::Commands::Stop.run(targets, verbose: args.verbose?, no_wait: args.no_wait?, max_wait:)
|
||||
when *::Service::Commands::Kill::TRIGGERS
|
||||
::Service::Commands::Kill.run(targets, verbose: args.verbose?)
|
||||
::Services::Commands::Stop.run(targets, verbose: args.verbose?, no_wait: args.no_wait?, max_wait:)
|
||||
when *::Services::Commands::Kill::TRIGGERS
|
||||
::Services::Commands::Kill.run(targets, verbose: args.verbose?)
|
||||
else
|
||||
raise UsageError, "unknown subcommand: `#{subcommand}`"
|
||||
end
|
||||
|
@ -1,8 +1,8 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Service
|
||||
module ServicesCli
|
||||
module Services
|
||||
module Cli
|
||||
extend FileUtils
|
||||
|
||||
sig { returns(T.nilable(String)) }
|
||||
@ -46,7 +46,7 @@ module Service
|
||||
end
|
||||
|
||||
# Kill services that don't have a service file
|
||||
sig { returns(T::Array[Service::FormulaWrapper]) }
|
||||
sig { returns(T::Array[Services::FormulaWrapper]) }
|
||||
def self.kill_orphaned_services
|
||||
cleaned_labels = []
|
||||
cleaned_services = []
|
||||
@ -79,7 +79,7 @@ module Service
|
||||
end
|
||||
|
||||
# Run a service as defined in the formula. This does not clean the service file like `start` does.
|
||||
sig { params(targets: T::Array[Service::FormulaWrapper], verbose: T.nilable(T::Boolean)).void }
|
||||
sig { params(targets: T::Array[Services::FormulaWrapper], verbose: T.nilable(T::Boolean)).void }
|
||||
def self.run(targets, verbose: false)
|
||||
targets.each do |service|
|
||||
if service.pid?
|
||||
@ -96,7 +96,7 @@ module Service
|
||||
|
||||
# Start a service.
|
||||
sig {
|
||||
params(targets: T::Array[Service::FormulaWrapper], service_file: T.nilable(T.any(String, Pathname)),
|
||||
params(targets: T::Array[Services::FormulaWrapper], service_file: T.nilable(T.any(String, Pathname)),
|
||||
verbose: T.nilable(T::Boolean)).void
|
||||
}
|
||||
def self.start(targets, service_file = nil, verbose: false)
|
||||
@ -138,7 +138,7 @@ module Service
|
||||
|
||||
# Stop a service and unload it.
|
||||
sig {
|
||||
params(targets: T::Array[Service::FormulaWrapper],
|
||||
params(targets: T::Array[Services::FormulaWrapper],
|
||||
verbose: T.nilable(T::Boolean),
|
||||
no_wait: T.nilable(T::Boolean),
|
||||
max_wait: T.nilable(T.any(Integer, Float))).void
|
||||
@ -199,7 +199,7 @@ module Service
|
||||
end
|
||||
|
||||
# Stop a service but keep it registered.
|
||||
sig { params(targets: T::Array[Service::FormulaWrapper], verbose: T.nilable(T::Boolean)).void }
|
||||
sig { params(targets: T::Array[Services::FormulaWrapper], verbose: T.nilable(T::Boolean)).void }
|
||||
def self.kill(targets, verbose: false)
|
||||
targets.each do |service|
|
||||
if !service.pid?
|
||||
@ -209,7 +209,7 @@ module Service
|
||||
else
|
||||
puts "Killing `#{service.name}`... (might take a while)"
|
||||
if System.systemctl?
|
||||
System::Systemctl.quiet_run("stop", T.must(service.service_name))
|
||||
System::Systemctl.quiet_run("stop", service.service_name)
|
||||
elsif System.launchctl?
|
||||
quiet_system System.launchctl, "stop", "#{System.domain_target}/#{service.service_name}"
|
||||
end
|
||||
@ -290,7 +290,7 @@ module Service
|
||||
end
|
||||
|
||||
sig {
|
||||
params(service: Service::FormulaWrapper, file: T.nilable(T.any(String, Pathname)),
|
||||
params(service: Services::FormulaWrapper, file: T.nilable(T.any(String, Pathname)),
|
||||
enable: T.nilable(T::Boolean)).void
|
||||
}
|
||||
def self.launchctl_load(service, file:, enable:)
|
||||
@ -298,13 +298,13 @@ module Service
|
||||
safe_system System.launchctl, "bootstrap", System.domain_target, file
|
||||
end
|
||||
|
||||
sig { params(service: Service::FormulaWrapper, enable: T.nilable(T::Boolean)).void }
|
||||
sig { params(service: Services::FormulaWrapper, enable: T.nilable(T::Boolean)).void }
|
||||
def self.systemd_load(service, enable:)
|
||||
System::Systemctl.run("start", T.must(service.service_name))
|
||||
System::Systemctl.run("enable", T.must(service.service_name)) if enable
|
||||
end
|
||||
|
||||
sig { params(service: Service::FormulaWrapper, enable: T.nilable(T::Boolean)).void }
|
||||
sig { params(service: Services::FormulaWrapper, enable: T.nilable(T::Boolean)).void }
|
||||
def self.service_load(service, enable:)
|
||||
if System.root? && !service.service_startup?
|
||||
opoo "#{service.name} must be run as non-root to start at user login!"
|
||||
@ -326,7 +326,7 @@ module Service
|
||||
ohai("Successfully #{function} `#{service.name}` (label: #{service.service_name})")
|
||||
end
|
||||
|
||||
sig { params(service: Service::FormulaWrapper, file: T.nilable(Pathname)).void }
|
||||
sig { params(service: Services::FormulaWrapper, file: T.nilable(Pathname)).void }
|
||||
def self.install_service_file(service, file)
|
||||
raise UsageError, "Formula `#{service.name}` is not installed" unless service.installed?
|
||||
|
||||
@ -339,9 +339,9 @@ module Service
|
||||
temp << if T.must(file).blank?
|
||||
contents = T.must(service.service_file).read
|
||||
|
||||
if sudo_service_user && Service::System.launchctl?
|
||||
if sudo_service_user && Services::System.launchctl?
|
||||
# set the username in the new plist file
|
||||
ohai "Setting username in #{service.service_name} to #{Service::System.user}"
|
||||
ohai "Setting username in #{service.service_name} to #{Services::System.user}"
|
||||
plist_data = Plist.parse_xml(contents, marshal: false)
|
||||
plist_data["UserName"] = sudo_service_user
|
||||
plist_data.to_plist
|
||||
@ -362,7 +362,7 @@ module Service
|
||||
|
||||
chmod 0644, service.dest
|
||||
|
||||
Service::System::Systemctl.run("daemon-reload") if System.systemctl?
|
||||
Services::System::Systemctl.run("daemon-reload") if System.systemctl?
|
||||
end
|
||||
end
|
||||
end
|
@ -1,7 +1,7 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Service
|
||||
module Services
|
||||
module Commands
|
||||
module Cleanup
|
||||
TRIGGERS = %w[cleanup clean cl rm].freeze
|
||||
@ -10,8 +10,8 @@ module Service
|
||||
def self.run
|
||||
cleaned = []
|
||||
|
||||
cleaned += Service::ServicesCli.kill_orphaned_services
|
||||
cleaned += Service::ServicesCli.remove_unused_service_files
|
||||
cleaned += Services::Cli.kill_orphaned_services
|
||||
cleaned += Services::Cli.remove_unused_service_files
|
||||
|
||||
puts "All #{System.root? ? "root" : "user-space"} services OK, nothing cleaned..." if cleaned.empty?
|
||||
end
|
@ -1,17 +1,20 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Service
|
||||
require "services/formula_wrapper"
|
||||
require "services/cli"
|
||||
|
||||
module Services
|
||||
module Commands
|
||||
module Info
|
||||
TRIGGERS = %w[info i].freeze
|
||||
|
||||
sig {
|
||||
params(targets: T::Array[Service::FormulaWrapper], verbose: T.nilable(T::Boolean),
|
||||
params(targets: T::Array[Services::FormulaWrapper], verbose: T.nilable(T::Boolean),
|
||||
json: T.nilable(T::Boolean)).void
|
||||
}
|
||||
def self.run(targets, verbose:, json:)
|
||||
Service::ServicesCli.check(targets)
|
||||
Services::Cli.check(targets)
|
||||
|
||||
output = targets.map(&:to_hash)
|
||||
|
16
Library/Homebrew/services/commands/kill.rb
Normal file
16
Library/Homebrew/services/commands/kill.rb
Normal file
@ -0,0 +1,16 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Services
|
||||
module Commands
|
||||
module Kill
|
||||
TRIGGERS = %w[kill k].freeze
|
||||
|
||||
sig { params(targets: T::Array[Services::FormulaWrapper], verbose: T.nilable(T::Boolean)).void }
|
||||
def self.run(targets, verbose:)
|
||||
Services::Cli.check(targets)
|
||||
Services::Cli.kill(targets, verbose:)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -1,9 +1,10 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "service/formulae"
|
||||
require "services/formulae"
|
||||
require "services/cli"
|
||||
|
||||
module Service
|
||||
module Services
|
||||
module Commands
|
||||
module List
|
||||
TRIGGERS = [nil, "list", "ls"].freeze
|
||||
@ -12,7 +13,7 @@ module Service
|
||||
def self.run(json: false)
|
||||
formulae = Formulae.services_list
|
||||
if formulae.blank?
|
||||
opoo "No services available to control with `#{Service::ServicesCli.bin}`" if $stderr.tty?
|
||||
opoo "No services available to control with `#{Services::Cli.bin}`" if $stderr.tty?
|
||||
return
|
||||
end
|
||||
|
@ -1,7 +1,7 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Service
|
||||
module Services
|
||||
module Commands
|
||||
module Restart
|
||||
# NOTE: The restart command is used to update service files
|
||||
@ -11,9 +11,9 @@ module Service
|
||||
|
||||
TRIGGERS = %w[restart relaunch reload r].freeze
|
||||
|
||||
sig { params(targets: T::Array[Service::FormulaWrapper], verbose: T.nilable(T::Boolean)).returns(NilClass) }
|
||||
sig { params(targets: T::Array[Services::FormulaWrapper], verbose: T.nilable(T::Boolean)).returns(NilClass) }
|
||||
def self.run(targets, verbose:)
|
||||
Service::ServicesCli.check(targets)
|
||||
Services::Cli.check(targets)
|
||||
|
||||
ran = []
|
||||
started = []
|
||||
@ -24,11 +24,11 @@ module Service
|
||||
# group not-started services with started ones for restart
|
||||
started << service
|
||||
end
|
||||
Service::ServicesCli.stop([service], verbose:) if service.loaded?
|
||||
Services::Cli.stop([service], verbose:) if service.loaded?
|
||||
end
|
||||
|
||||
Service::ServicesCli.run(targets, verbose:) if ran.present?
|
||||
Service::ServicesCli.start(started, verbose:) if started.present?
|
||||
Services::Cli.run(targets, verbose:) if ran.present?
|
||||
Services::Cli.start(started, verbose:) if started.present?
|
||||
nil
|
||||
end
|
||||
end
|
16
Library/Homebrew/services/commands/run.rb
Normal file
16
Library/Homebrew/services/commands/run.rb
Normal file
@ -0,0 +1,16 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Services
|
||||
module Commands
|
||||
module Run
|
||||
TRIGGERS = ["run"].freeze
|
||||
|
||||
sig { params(targets: T::Array[Services::FormulaWrapper], verbose: T.nilable(T::Boolean)).void }
|
||||
def self.run(targets, verbose:)
|
||||
Services::Cli.check(targets)
|
||||
Services::Cli.run(targets, verbose:)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -1,18 +1,18 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Service
|
||||
module Services
|
||||
module Commands
|
||||
module Start
|
||||
TRIGGERS = %w[start launch load s l].freeze
|
||||
|
||||
sig {
|
||||
params(targets: T::Array[Service::FormulaWrapper], custom_plist: T.nilable(String),
|
||||
params(targets: T::Array[Services::FormulaWrapper], custom_plist: T.nilable(String),
|
||||
verbose: T.nilable(T::Boolean)).void
|
||||
}
|
||||
def self.run(targets, custom_plist, verbose:)
|
||||
Service::ServicesCli.check(targets)
|
||||
Service::ServicesCli.start(targets, custom_plist, verbose:)
|
||||
Services::Cli.check(targets)
|
||||
Services::Cli.start(targets, custom_plist, verbose:)
|
||||
end
|
||||
end
|
||||
end
|
@ -1,20 +1,20 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Service
|
||||
module Services
|
||||
module Commands
|
||||
module Stop
|
||||
TRIGGERS = %w[stop unload terminate term t u].freeze
|
||||
|
||||
sig {
|
||||
params(targets: T::Array[Service::FormulaWrapper],
|
||||
params(targets: T::Array[Services::FormulaWrapper],
|
||||
verbose: T.nilable(T::Boolean),
|
||||
no_wait: T.nilable(T::Boolean),
|
||||
max_wait: T.nilable(Float)).void
|
||||
}
|
||||
def self.run(targets, verbose:, no_wait:, max_wait:)
|
||||
Service::ServicesCli.check(targets)
|
||||
Service::ServicesCli.stop(targets, verbose:, no_wait:, max_wait:)
|
||||
Services::Cli.check(targets)
|
||||
Services::Cli.stop(targets, verbose:, no_wait:, max_wait:)
|
||||
end
|
||||
end
|
||||
end
|
@ -3,7 +3,7 @@
|
||||
|
||||
# Wrapper for a formula to handle service-related stuff like parsing and
|
||||
# generating the service/plist files.
|
||||
module Service
|
||||
module Services
|
||||
class FormulaWrapper
|
||||
# Access the `Formula` instance.
|
||||
sig { returns(Formula) }
|
@ -1,11 +1,13 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Service
|
||||
require "services/formula_wrapper"
|
||||
|
||||
module Services
|
||||
module Formulae
|
||||
# All available services, with optional filters applied
|
||||
# @private
|
||||
sig { params(loaded: T.nilable(T::Boolean), skip_root: T::Boolean).returns(T::Array[Service::FormulaWrapper]) }
|
||||
sig { params(loaded: T.nilable(T::Boolean), skip_root: T::Boolean).returns(T::Array[Services::FormulaWrapper]) }
|
||||
def self.available_services(loaded: nil, skip_root: false)
|
||||
require "formula"
|
||||
|
@ -1,17 +0,0 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
# fix loadppath
|
||||
$LOAD_PATH.unshift(File.expand_path(__dir__))
|
||||
|
||||
require "service/formula_wrapper"
|
||||
require "service/services_cli"
|
||||
require "service/system"
|
||||
require "service/commands/cleanup"
|
||||
require "service/commands/info"
|
||||
require "service/commands/list"
|
||||
require "service/commands/restart"
|
||||
require "service/commands/run"
|
||||
require "service/commands/start"
|
||||
require "service/commands/stop"
|
||||
require "service/commands/kill"
|
@ -1,16 +0,0 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Service
|
||||
module Commands
|
||||
module Kill
|
||||
TRIGGERS = %w[kill k].freeze
|
||||
|
||||
sig { params(targets: T::Array[Service::FormulaWrapper], verbose: T.nilable(T::Boolean)).void }
|
||||
def self.run(targets, verbose:)
|
||||
Service::ServicesCli.check(targets)
|
||||
Service::ServicesCli.kill(targets, verbose:)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -1,16 +0,0 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Service
|
||||
module Commands
|
||||
module Run
|
||||
TRIGGERS = ["run"].freeze
|
||||
|
||||
sig { params(targets: T::Array[Service::FormulaWrapper], verbose: T.nilable(T::Boolean)).void }
|
||||
def self.run(targets, verbose:)
|
||||
Service::ServicesCli.check(targets)
|
||||
Service::ServicesCli.run(targets, verbose:)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -3,7 +3,7 @@
|
||||
|
||||
require_relative "system/systemctl"
|
||||
|
||||
module Service
|
||||
module Services
|
||||
module System
|
||||
extend FileUtils
|
||||
|
@ -1,7 +1,7 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Service
|
||||
module Services
|
||||
module System
|
||||
module Systemctl
|
||||
sig { returns(T.nilable(Pathname)) }
|
@ -1,8 +1,10 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "services/service"
|
||||
require "services/cli"
|
||||
require "services/system"
|
||||
require "services/formula_wrapper"
|
||||
|
||||
RSpec.describe Service::ServicesCli do
|
||||
RSpec.describe Services::Cli do
|
||||
subject(:services_cli) { described_class }
|
||||
|
||||
let(:service_string) { "service" }
|
||||
@ -15,7 +17,7 @@ RSpec.describe Service::ServicesCli do
|
||||
|
||||
describe "#running" do
|
||||
it "macOS - returns the currently running services" do
|
||||
allow(Service::System).to receive_messages(launchctl?: true, systemctl?: false)
|
||||
allow(Services::System).to receive_messages(launchctl?: true, systemctl?: false)
|
||||
allow(Utils).to receive(:popen_read).and_return <<~EOS
|
||||
77513 50 homebrew.mxcl.php
|
||||
495 0 homebrew.mxcl.node_exporter
|
||||
@ -29,8 +31,8 @@ RSpec.describe Service::ServicesCli do
|
||||
end
|
||||
|
||||
it "systemD - returns the currently running services" do
|
||||
allow(Service::System).to receive(:launchctl?).and_return(false)
|
||||
allow(Service::System::Systemctl).to receive(:popen_read).and_return <<~EOS
|
||||
allow(Services::System).to receive(:launchctl?).and_return(false)
|
||||
allow(Services::System::Systemctl).to receive(:popen_read).and_return <<~EOS
|
||||
homebrew.php.service loaded active running Homebrew PHP service
|
||||
systemd-udevd.service loaded active running Rule-based Manager for Device Events and Files
|
||||
udisks2.service loaded active running Disk Manager
|
||||
@ -44,26 +46,23 @@ RSpec.describe Service::ServicesCli do
|
||||
it "checks the input does not exist" do
|
||||
expect do
|
||||
services_cli.check([])
|
||||
end.to raise_error(UsageError,
|
||||
a_string_including("Formula(e) missing, please provide a formula name or use --all"))
|
||||
end.to raise_error(UsageError, "Invalid usage: Formula(e) missing, please provide a formula name or use --all")
|
||||
end
|
||||
|
||||
it "checks the input exists" do
|
||||
expect do
|
||||
services_cli.check("hello")
|
||||
end.not_to raise_error(UsageError,
|
||||
a_string_including("Formula(e) missing, please provide a formula name or use --all"))
|
||||
"Invalid usage: Formula(e) missing, please provide a formula name or use --all")
|
||||
end
|
||||
end
|
||||
|
||||
describe "#kill_orphaned_services" do
|
||||
it "skips unmanaged services" do
|
||||
service = instance_double(service_string, name: "example_service")
|
||||
allow(services_cli).to receive(:running).and_return(["example_service"])
|
||||
allow(Service::FormulaWrapper).to receive(:from).and_return(service)
|
||||
expect do
|
||||
services_cli.kill_orphaned_services
|
||||
end.to output("Service example_service not managed by `brew services` => skipping\n").to_stdout
|
||||
end.to output("Warning: Service example_service not managed by `brew services` => skipping\n").to_stderr
|
||||
end
|
||||
|
||||
it "tries but is unable to kill a non existing service" do
|
||||
@ -75,18 +74,17 @@ RSpec.describe Service::ServicesCli do
|
||||
keep_alive?: false,
|
||||
)
|
||||
allow(service).to receive(:service_name)
|
||||
allow(Service::FormulaWrapper).to receive(:from).and_return(service)
|
||||
allow(Services::FormulaWrapper).to receive(:from).and_return(service)
|
||||
allow(services_cli).to receive(:running).and_return(["example_service"])
|
||||
expect do
|
||||
services_cli.kill_orphaned_services
|
||||
end.to output(a_string_including("Killing `example_service`... (might take a while)")).to_stdout.and
|
||||
output(a_string_including("Unable to kill `example_service` (label: )")).to_stderr
|
||||
end.to output("Killing `example_service`... (might take a while)\n").to_stdout
|
||||
end
|
||||
end
|
||||
|
||||
describe "#run" do
|
||||
it "checks empty targets cause no error" do
|
||||
expect(Service::System).not_to receive(:root?)
|
||||
expect(Services::System).not_to receive(:root?)
|
||||
services_cli.run([])
|
||||
end
|
||||
|
||||
@ -102,14 +100,14 @@ RSpec.describe Service::ServicesCli do
|
||||
|
||||
describe "#start" do
|
||||
it "checks missing file causes error" do
|
||||
expect(Service::System).not_to receive(:root?)
|
||||
expect(Services::System).not_to receive(:root?)
|
||||
expect do
|
||||
services_cli.start(["service_name"], "/hfdkjshksdjhfkjsdhf/fdsjghsdkjhb")
|
||||
end.to raise_error(UsageError, a_string_including("Provided service file does not exist"))
|
||||
end.to raise_error(UsageError, "Invalid usage: Provided service file does not exist")
|
||||
end
|
||||
|
||||
it "checks empty targets cause no error" do
|
||||
expect(Service::System).not_to receive(:root?)
|
||||
expect(Services::System).not_to receive(:root?)
|
||||
services_cli.start([])
|
||||
end
|
||||
|
||||
@ -125,14 +123,14 @@ RSpec.describe Service::ServicesCli do
|
||||
|
||||
describe "#stop" do
|
||||
it "checks empty targets cause no error" do
|
||||
expect(Service::System).not_to receive(:root?)
|
||||
expect(Services::System).not_to receive(:root?)
|
||||
services_cli.stop([])
|
||||
end
|
||||
end
|
||||
|
||||
describe "#kill" do
|
||||
it "checks empty targets cause no error" do
|
||||
expect(Service::System).not_to receive(:root?)
|
||||
expect(Services::System).not_to receive(:root?)
|
||||
services_cli.kill([])
|
||||
end
|
||||
|
||||
@ -155,15 +153,15 @@ RSpec.describe Service::ServicesCli do
|
||||
|
||||
describe "#install_service_file" do
|
||||
it "checks service is installed" do
|
||||
service = instance_double(Service::FormulaWrapper, name: "name", installed?: false)
|
||||
service = instance_double(Services::FormulaWrapper, name: "name", installed?: false)
|
||||
expect do
|
||||
services_cli.install_service_file(service, nil)
|
||||
end.to raise_error(UsageError, a_string_including("Formula `name` is not installed"))
|
||||
end.to raise_error(UsageError, "Invalid usage: Formula `name` is not installed")
|
||||
end
|
||||
|
||||
it "checks service file exists" do
|
||||
service = instance_double(
|
||||
Service::FormulaWrapper,
|
||||
Services::FormulaWrapper,
|
||||
name: "name",
|
||||
installed?: true,
|
||||
service_file: instance_double(Pathname, exist?: false),
|
||||
@ -172,28 +170,26 @@ RSpec.describe Service::ServicesCli do
|
||||
services_cli.install_service_file(service, nil)
|
||||
end.to raise_error(
|
||||
UsageError,
|
||||
a_string_including(
|
||||
"Formula `name` has not implemented #plist, #service or installed a locatable service file",
|
||||
),
|
||||
"Invalid usage: Formula `name` has not implemented #plist, #service or installed a locatable service file",
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#systemd_load", :needs_linux do
|
||||
it "checks non-enabling run" do
|
||||
expect(Service::System::Systemctl).to receive(:executable).once.and_return("/bin/systemctl")
|
||||
expect(Service::System::Systemctl).to receive(:scope).once.and_return("--user")
|
||||
expect(Services::System::Systemctl).to receive(:executable).once.and_return("/bin/systemctl")
|
||||
expect(Services::System::Systemctl).to receive(:scope).once.and_return("--user")
|
||||
services_cli.systemd_load(
|
||||
instance_double(Service::FormulaWrapper, service_name: "name"),
|
||||
instance_double(Services::FormulaWrapper, service_name: "name"),
|
||||
enable: false,
|
||||
)
|
||||
end
|
||||
|
||||
it "checks enabling run" do
|
||||
expect(Service::System::Systemctl).to receive(:executable).twice.and_return("/bin/systemctl")
|
||||
expect(Service::System::Systemctl).to receive(:scope).twice.and_return("--user")
|
||||
expect(Services::System::Systemctl).to receive(:executable).twice.and_return("/bin/systemctl")
|
||||
expect(Services::System::Systemctl).to receive(:scope).twice.and_return("--user")
|
||||
services_cli.systemd_load(
|
||||
instance_double(Service::FormulaWrapper, service_name: "name"),
|
||||
instance_double(Services::FormulaWrapper, service_name: "name"),
|
||||
enable: true,
|
||||
)
|
||||
end
|
||||
@ -201,70 +197,76 @@ RSpec.describe Service::ServicesCli do
|
||||
|
||||
describe "#launchctl_load", :needs_macos do
|
||||
it "checks non-enabling run" do
|
||||
expect(Service::System).to receive(:domain_target).once.and_return("target")
|
||||
expect(Service::System).to receive(:launchctl).once.and_return("/bin/launchctl")
|
||||
services_cli.launchctl_load(instance_double(Service::FormulaWrapper), file: "a", enable: false)
|
||||
expect(Services::System).to receive(:domain_target).once.and_return("target")
|
||||
expect(Services::System).to receive(:launchctl).once.and_return("/bin/launchctl")
|
||||
expect(described_class).to receive(:safe_system).once.and_return(true)
|
||||
services_cli.launchctl_load(instance_double(Services::FormulaWrapper), file: "a", enable: false)
|
||||
end
|
||||
|
||||
it "checks enabling run" do
|
||||
expect(Service::System).to receive(:domain_target).twice.and_return("target")
|
||||
expect(Service::System).to receive(:launchctl).twice.and_return("/bin/launchctl")
|
||||
services_cli.launchctl_load(instance_double(Service::FormulaWrapper, service_name: "name"), file: "a",
|
||||
expect(Services::System).to receive(:domain_target).twice.and_return("target")
|
||||
expect(Services::System).to receive(:launchctl).twice.and_return("/bin/launchctl")
|
||||
expect(described_class).to receive(:safe_system).twice.and_return(true)
|
||||
services_cli.launchctl_load(instance_double(Services::FormulaWrapper, service_name: "name"), file: "a",
|
||||
enable: true)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#service_load" do
|
||||
it "checks non-root for login" do
|
||||
expect(Service::System).to receive(:launchctl?).once.and_return(false)
|
||||
expect(Service::System).to receive(:systemctl?).once.and_return(false)
|
||||
expect(Service::System).to receive(:root?).once.and_return(true)
|
||||
expect(Services::System).to receive(:launchctl?).once.and_return(false)
|
||||
expect(Services::System).to receive(:systemctl?).once.and_return(false)
|
||||
expect(Services::System).to receive(:root?).once.and_return(true)
|
||||
|
||||
expect do
|
||||
services_cli.service_load(
|
||||
instance_double(Service::FormulaWrapper, name: "name", service_name: "service.name",
|
||||
instance_double(Services::FormulaWrapper, name: "name", service_name: "service.name",
|
||||
service_startup?: false), enable: false
|
||||
)
|
||||
end.to output(a_string_including("Successfully ran `name` (label: service.name)")).to_stdout.and
|
||||
output(a_string_including("name must be run as non-root to start at user login!")).to_stderr
|
||||
end.to output("==> Successfully ran `name` (label: service.name)\n").to_stdout
|
||||
end
|
||||
|
||||
it "checks root for startup" do
|
||||
expect(Service::System).to receive(:launchctl?).once.and_return(false)
|
||||
expect(Service::System).to receive(:systemctl?).once.and_return(false)
|
||||
expect(Service::System).to receive(:root?).twice.and_return(false)
|
||||
expect(Services::System).to receive(:launchctl?).once.and_return(false)
|
||||
expect(Services::System).to receive(:systemctl?).once.and_return(false)
|
||||
expect(Services::System).to receive(:root?).twice.and_return(false)
|
||||
expect do
|
||||
services_cli.service_load(
|
||||
instance_double(Service::FormulaWrapper, name: "name", service_name: "service.name",
|
||||
instance_double(Services::FormulaWrapper, name: "name", service_name: "service.name",
|
||||
service_startup?: true),
|
||||
enable: false,
|
||||
)
|
||||
end.to output(a_string_including("Successfully ran `name` (label: service.name)")).to_stdout.and
|
||||
output(a_string_including("name must be run as root to start at system startup!")).to_stderr
|
||||
end.to output("==> Successfully ran `name` (label: service.name)\n").to_stdout
|
||||
end
|
||||
|
||||
it "triggers launchctl" do
|
||||
expect(Service::System).to receive(:domain_target).once.and_return("target")
|
||||
expect(Service::System).to receive(:launchctl?).once.and_return(true)
|
||||
expect(Service::System).to receive(:launchctl).once
|
||||
expect(Service::System).not_to receive(:systemctl?)
|
||||
expect(Service::System).to receive(:root?).twice.and_return(false)
|
||||
expect do
|
||||
services_cli.service_load(
|
||||
instance_double(Service::FormulaWrapper, name: "name", service_name: "service.name",
|
||||
service_startup?: false), enable: false
|
||||
)
|
||||
end.to output("Successfully ran `name` (label: service.name)\n").to_stdout
|
||||
end
|
||||
|
||||
it "triggers systemctl" do
|
||||
expect(Service::System).to receive(:launchctl?).once.and_return(false)
|
||||
expect(Service::System).to receive(:systemctl?).once.and_return(true)
|
||||
expect(Service::System).to receive(:root?).thrice.and_return(false)
|
||||
expect(Services::System).to receive(:launchctl?).once.and_return(true)
|
||||
expect(Services::System).not_to receive(:systemctl?)
|
||||
expect(Services::System).to receive(:root?).twice.and_return(false)
|
||||
expect(described_class).to receive(:launchctl_load).once.and_return(true)
|
||||
expect do
|
||||
services_cli.service_load(
|
||||
instance_double(
|
||||
Service::FormulaWrapper,
|
||||
Services::FormulaWrapper,
|
||||
name: "name",
|
||||
service_name: "service.name",
|
||||
service_startup?: false,
|
||||
service_file: instance_double(Pathname, exist?: false),
|
||||
),
|
||||
enable: false,
|
||||
)
|
||||
end.to output("==> Successfully ran `name` (label: service.name)\n").to_stdout
|
||||
end
|
||||
|
||||
it "triggers systemctl" do
|
||||
expect(Services::System).to receive(:launchctl?).once.and_return(false)
|
||||
expect(Services::System).to receive(:systemctl?).once.and_return(true)
|
||||
expect(Services::System).to receive(:root?).twice.and_return(false)
|
||||
expect(Services::System::Systemctl).to receive(:run).once.and_return(true)
|
||||
expect do
|
||||
services_cli.service_load(
|
||||
instance_double(
|
||||
Services::FormulaWrapper,
|
||||
name: "name",
|
||||
service_name: "service.name",
|
||||
service_startup?: false,
|
||||
@ -272,17 +274,18 @@ service_startup?: false), enable: false
|
||||
),
|
||||
enable: false,
|
||||
)
|
||||
end.to output("Successfully ran `name` (label: service.name)\n").to_stdout
|
||||
end.to output("==> Successfully ran `name` (label: service.name)\n").to_stdout
|
||||
end
|
||||
|
||||
it "represents correct action" do
|
||||
expect(Service::System).to receive(:launchctl?).once.and_return(false)
|
||||
expect(Service::System).to receive(:systemctl?).once.and_return(true)
|
||||
expect(Service::System).to receive(:root?).exactly(4).times.and_return(false)
|
||||
expect(Services::System).to receive(:launchctl?).once.and_return(false)
|
||||
expect(Services::System).to receive(:systemctl?).once.and_return(true)
|
||||
expect(Services::System).to receive(:root?).twice.and_return(false)
|
||||
expect(Services::System::Systemctl).to receive(:run).twice.and_return(true)
|
||||
expect do
|
||||
services_cli.service_load(
|
||||
instance_double(
|
||||
Service::FormulaWrapper,
|
||||
Services::FormulaWrapper,
|
||||
name: "name",
|
||||
service_name: "service.name",
|
||||
service_startup?: false,
|
||||
@ -290,7 +293,7 @@ service_startup?: false), enable: false
|
||||
),
|
||||
enable: true,
|
||||
)
|
||||
end.to output("Successfully started `name` (label: service.name)\n").to_stdout
|
||||
end.to output("==> Successfully started `name` (label: service.name)\n").to_stdout
|
||||
end
|
||||
end
|
||||
end
|
@ -1,8 +1,10 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "services/service"
|
||||
require "services/commands/cleanup"
|
||||
require "services/system"
|
||||
require "services/cli"
|
||||
|
||||
RSpec.describe Service::Commands::Cleanup do
|
||||
RSpec.describe Services::Commands::Cleanup do
|
||||
describe "#TRIGGERS" do
|
||||
it "contains all restart triggers" do
|
||||
expect(described_class::TRIGGERS).to eq(%w[cleanup clean cl rm])
|
||||
@ -11,9 +13,9 @@ RSpec.describe Service::Commands::Cleanup do
|
||||
|
||||
describe "#run" do
|
||||
it "root - prints on empty cleanup" do
|
||||
expect(Service::System).to receive(:root?).once.and_return(true)
|
||||
expect(Service::ServicesCli).to receive(:kill_orphaned_services).once.and_return([])
|
||||
expect(Service::ServicesCli).to receive(:remove_unused_service_files).once.and_return([])
|
||||
expect(Services::System).to receive(:root?).once.and_return(true)
|
||||
expect(Services::Cli).to receive(:kill_orphaned_services).once.and_return([])
|
||||
expect(Services::Cli).to receive(:remove_unused_service_files).once.and_return([])
|
||||
|
||||
expect do
|
||||
described_class.run
|
||||
@ -21,9 +23,9 @@ RSpec.describe Service::Commands::Cleanup do
|
||||
end
|
||||
|
||||
it "user - prints on empty cleanup" do
|
||||
expect(Service::System).to receive(:root?).once.and_return(false)
|
||||
expect(Service::ServicesCli).to receive(:kill_orphaned_services).once.and_return([])
|
||||
expect(Service::ServicesCli).to receive(:remove_unused_service_files).once.and_return([])
|
||||
expect(Services::System).to receive(:root?).once.and_return(false)
|
||||
expect(Services::Cli).to receive(:kill_orphaned_services).once.and_return([])
|
||||
expect(Services::Cli).to receive(:remove_unused_service_files).once.and_return([])
|
||||
|
||||
expect do
|
||||
described_class.run
|
||||
@ -31,9 +33,9 @@ RSpec.describe Service::Commands::Cleanup do
|
||||
end
|
||||
|
||||
it "prints nothing on cleanup" do
|
||||
expect(Service::System).not_to receive(:root?)
|
||||
expect(Service::ServicesCli).to receive(:kill_orphaned_services).once.and_return(["a"])
|
||||
expect(Service::ServicesCli).to receive(:remove_unused_service_files).once.and_return(["b"])
|
||||
expect(Services::System).not_to receive(:root?)
|
||||
expect(Services::Cli).to receive(:kill_orphaned_services).once.and_return(["a"])
|
||||
expect(Services::Cli).to receive(:remove_unused_service_files).once.and_return(["b"])
|
||||
|
||||
expect do
|
||||
described_class.run
|
||||
|
@ -1,37 +1,10 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "services/service"
|
||||
require "services/commands/info"
|
||||
|
||||
# needs for tty color tests
|
||||
module Tty
|
||||
def self.green
|
||||
"<GREEN>"
|
||||
end
|
||||
|
||||
def self.yellow
|
||||
"<YELLOW>"
|
||||
end
|
||||
|
||||
def self.red
|
||||
"<RED>"
|
||||
end
|
||||
|
||||
def self.default
|
||||
"<DEFAULT>"
|
||||
end
|
||||
|
||||
def self.bold
|
||||
"<BOLD>"
|
||||
end
|
||||
|
||||
def self.reset
|
||||
"<RESET>"
|
||||
end
|
||||
end
|
||||
|
||||
RSpec.describe Service::Commands::Info do
|
||||
RSpec.describe Services::Commands::Info do
|
||||
before do
|
||||
allow_any_instance_of(IO).to receive(:tty?).and_return(true)
|
||||
allow_any_instance_of(IO).to receive(:tty?).and_return(false)
|
||||
end
|
||||
|
||||
describe "#TRIGGERS" do
|
||||
@ -44,12 +17,11 @@ RSpec.describe Service::Commands::Info do
|
||||
it "fails with empty list" do
|
||||
expect do
|
||||
described_class.run([], verbose: false, json: false)
|
||||
end.to raise_error UsageError,
|
||||
a_string_including("Formula(e) missing, please provide a formula name or use --all")
|
||||
end.to raise_error UsageError, "Invalid usage: Formula(e) missing, please provide a formula name or use --all"
|
||||
end
|
||||
|
||||
it "succeeds with items" do
|
||||
out = "<BOLD>service<RESET> ()\nRunning: true\nLoaded: true\nSchedulable: false\n"
|
||||
out = "service ()\nRunning: true\nLoaded: true\nSchedulable: false\n"
|
||||
formula = {
|
||||
name: "service",
|
||||
user: "user",
|
||||
@ -83,8 +55,8 @@ RSpec.describe Service::Commands::Info do
|
||||
|
||||
describe "#output" do
|
||||
it "returns minimal output" do
|
||||
out = "<BOLD>service<RESET> ()\nRunning: <BOLD><GREEN>✔<RESET><RESET>\n"
|
||||
out += "Loaded: <BOLD><GREEN>✔<RESET><RESET>\nSchedulable: <BOLD><RED>✘<RESET><RESET>\n"
|
||||
out = "service ()\nRunning: true\n"
|
||||
out += "Loaded: true\nSchedulable: false\n"
|
||||
formula = {
|
||||
name: "service",
|
||||
user: "user",
|
||||
@ -98,8 +70,8 @@ RSpec.describe Service::Commands::Info do
|
||||
end
|
||||
|
||||
it "returns normal output" do
|
||||
out = "<BOLD>service<RESET> ()\nRunning: <BOLD><GREEN>✔<RESET><RESET>\n"
|
||||
out += "Loaded: <BOLD><GREEN>✔<RESET><RESET>\nSchedulable: <BOLD><RED>✘<RESET><RESET>\n"
|
||||
out = "service ()\nRunning: true\n"
|
||||
out += "Loaded: true\nSchedulable: false\n"
|
||||
out += "User: user\nPID: 42\n"
|
||||
formula = {
|
||||
name: "service",
|
||||
@ -115,9 +87,9 @@ RSpec.describe Service::Commands::Info do
|
||||
end
|
||||
|
||||
it "returns verbose output" do
|
||||
out = "<BOLD>service<RESET> ()\nRunning: <BOLD><GREEN>✔<RESET><RESET>\n"
|
||||
out += "Loaded: <BOLD><GREEN>✔<RESET><RESET>\nSchedulable: <BOLD><RED>✘<RESET><RESET>\n"
|
||||
out += "User: user\nPID: 42\nFile: /dev/null <BOLD><GREEN>✔<RESET><RESET>\nCommand: /bin/command\n"
|
||||
out = "service ()\nRunning: true\n"
|
||||
out += "Loaded: true\nSchedulable: false\n"
|
||||
out += "User: user\nPID: 42\nFile: /dev/null true\nCommand: /bin/command\n"
|
||||
out += "Working directory: /working/dir\nRoot directory: /root/dir\nLog: /log/dir\nError log: /log/dir/error\n"
|
||||
out += "Interval: 3600s\nCron: 5 * * * *\n"
|
||||
formula = {
|
||||
|
@ -1,35 +1,8 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "services/service"
|
||||
require "services/commands/list"
|
||||
|
||||
# needs for tty color tests
|
||||
module Tty
|
||||
def self.green
|
||||
"<GREEN>"
|
||||
end
|
||||
|
||||
def self.yellow
|
||||
"<YELLOW>"
|
||||
end
|
||||
|
||||
def self.red
|
||||
"<RED>"
|
||||
end
|
||||
|
||||
def self.default
|
||||
"<DEFAULT>"
|
||||
end
|
||||
|
||||
def self.bold
|
||||
"<BOLD>"
|
||||
end
|
||||
|
||||
def self.reset
|
||||
"<RESET>"
|
||||
end
|
||||
end
|
||||
|
||||
RSpec.describe Service::Commands::List do
|
||||
RSpec.describe Services::Commands::List do
|
||||
describe "#TRIGGERS" do
|
||||
it "contains all restart triggers" do
|
||||
expect(described_class::TRIGGERS).to eq([nil, "list", "ls"])
|
||||
@ -38,24 +11,23 @@ RSpec.describe Service::Commands::List do
|
||||
|
||||
describe "#run" do
|
||||
it "fails with empty list" do
|
||||
allow_any_instance_of(IO).to receive(:tty?).and_return(true)
|
||||
expect(Service::Formulae).to receive(:services_list).and_return([])
|
||||
expect(Services::Formulae).to receive(:services_list).and_return([])
|
||||
expect do
|
||||
allow($stderr).to receive(:tty?).and_return(true)
|
||||
described_class.run
|
||||
end.to output(a_string_including("No services available to control with `brew services`")).to_stderr
|
||||
end
|
||||
|
||||
it "succeeds with list" do
|
||||
out = "<BOLD>Name Status User File<RESET>\nservice <GREEN>started<RESET> user /dev/null\n"
|
||||
formula = instance_double(
|
||||
Service::FormulaWrapper,
|
||||
out = "Name Status User File\nservice started user /dev/null\n"
|
||||
formula = {
|
||||
name: "service",
|
||||
owner: "user",
|
||||
status_symbol: :started,
|
||||
service_file: +File::NULL,
|
||||
loaded?: true,
|
||||
)
|
||||
expect(Service::Formulae).to receive(:services_list).and_return([formula])
|
||||
user: "user",
|
||||
status: :started,
|
||||
file: "/dev/null",
|
||||
loaded: true,
|
||||
}
|
||||
expect(Services::Formulae).to receive(:services_list).and_return([formula])
|
||||
expect do
|
||||
described_class.run
|
||||
end.to output(out).to_stdout
|
||||
@ -75,7 +47,7 @@ RSpec.describe Service::Commands::List do
|
||||
filtered_formula = formula.slice(*described_class::JSON_FIELDS)
|
||||
expected_output = "#{JSON.pretty_generate([filtered_formula])}\n"
|
||||
|
||||
expect(Service::Formulae).to receive(:services_list).and_return([formula])
|
||||
expect(Services::Formulae).to receive(:services_list).and_return([formula])
|
||||
expect do
|
||||
described_class.run(json: true)
|
||||
end.to output(expected_output).to_stdout
|
||||
@ -87,20 +59,20 @@ RSpec.describe Service::Commands::List do
|
||||
formula = { name: "a", user: "u", file: Pathname.new("/tmp/file.file"), status: :stopped }
|
||||
expect do
|
||||
described_class.print_table([formula])
|
||||
end.to output("<BOLD>Name Status User File<RESET>\na <DEFAULT>stopped<RESET> u \n").to_stdout
|
||||
end.to output("Name Status User File\na stopped u \n").to_stdout
|
||||
end
|
||||
|
||||
it "prints without user or file data" do
|
||||
formula = { name: "a", user: nil, file: nil, status: :started, loaded: true }
|
||||
expect do
|
||||
described_class.print_table([formula])
|
||||
end.to output("<BOLD>Name Status User File<RESET>\na <GREEN>started<RESET> \n").to_stdout
|
||||
end.to output("Name Status User File\na started \n").to_stdout
|
||||
end
|
||||
|
||||
it "prints shortened home directory" do
|
||||
ENV["HOME"] = "/tmp"
|
||||
formula = { name: "a", user: "u", file: Pathname.new("/tmp/file.file"), status: :started, loaded: true }
|
||||
expected_output = "<BOLD>Name Status User File<RESET>\na <GREEN>started<RESET> u ~/file.file\n"
|
||||
expected_output = "Name Status User File\na started u ~/file.file\n"
|
||||
expect do
|
||||
described_class.print_table([formula])
|
||||
end.to output(expected_output).to_stdout
|
||||
@ -109,7 +81,7 @@ RSpec.describe Service::Commands::List do
|
||||
it "prints an error code" do
|
||||
file = Pathname.new("/tmp/file.file")
|
||||
formula = { name: "a", user: "u", file:, status: :error, exit_code: 256, loaded: true }
|
||||
expected_output = "<BOLD>Name Status User File<RESET>\na <RED>error <RESET>256 u /tmp/file.file\n"
|
||||
expected_output = "Name Status User File\na error 256 u /tmp/file.file\n"
|
||||
expect do
|
||||
described_class.print_table([formula])
|
||||
end.to output(expected_output).to_stdout
|
||||
@ -147,23 +119,23 @@ RSpec.describe Service::Commands::List do
|
||||
|
||||
describe "#get_status_string" do
|
||||
it "returns started" do
|
||||
expect(described_class.get_status_string(:started)).to eq("<GREEN>started<RESET>")
|
||||
expect(described_class.get_status_string(:started)).to eq("started")
|
||||
end
|
||||
|
||||
it "returns stopped" do
|
||||
expect(described_class.get_status_string(:stopped)).to eq("<DEFAULT>stopped<RESET>")
|
||||
expect(described_class.get_status_string(:stopped)).to eq("stopped")
|
||||
end
|
||||
|
||||
it "returns error" do
|
||||
expect(described_class.get_status_string(:error)).to eq("<RED>error <RESET>")
|
||||
expect(described_class.get_status_string(:error)).to eq("error ")
|
||||
end
|
||||
|
||||
it "returns unknown" do
|
||||
expect(described_class.get_status_string(:unknown)).to eq("<YELLOW>unknown<RESET>")
|
||||
expect(described_class.get_status_string(:unknown)).to eq("unknown")
|
||||
end
|
||||
|
||||
it "returns other" do
|
||||
expect(described_class.get_status_string(:other)).to eq("<YELLOW>other<RESET>")
|
||||
expect(described_class.get_status_string(:other)).to eq("other")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -1,8 +1,9 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "services/service"
|
||||
|
||||
RSpec.describe Service::Commands::Restart do
|
||||
require "services/commands/restart"
|
||||
require "services/cli"
|
||||
require "services/formula_wrapper"
|
||||
RSpec.describe Services::Commands::Restart do
|
||||
describe "#TRIGGERS" do
|
||||
it "contains all restart triggers" do
|
||||
expect(described_class::TRIGGERS).to eq(%w[restart relaunch reload r])
|
||||
@ -13,32 +14,31 @@ RSpec.describe Service::Commands::Restart do
|
||||
it "fails with empty list" do
|
||||
expect do
|
||||
described_class.run([], verbose: false)
|
||||
end.to raise_error UsageError,
|
||||
a_string_including("Formula(e) missing, please provide a formula name or use --all")
|
||||
end.to raise_error UsageError, "Invalid usage: Formula(e) missing, please provide a formula name or use --all"
|
||||
end
|
||||
|
||||
it "starts if services are not loaded" do
|
||||
expect(Service::ServicesCli).not_to receive(:run)
|
||||
expect(Service::ServicesCli).not_to receive(:stop)
|
||||
expect(Service::ServicesCli).to receive(:start).once
|
||||
service = instance_double(Service::FormulaWrapper, service_name: "name", loaded?: false)
|
||||
expect(Services::Cli).not_to receive(:run)
|
||||
expect(Services::Cli).not_to receive(:stop)
|
||||
expect(Services::Cli).to receive(:start).once
|
||||
service = instance_double(Services::FormulaWrapper, service_name: "name", loaded?: false)
|
||||
expect(described_class.run([service], verbose: false)).to be_nil
|
||||
end
|
||||
|
||||
it "starts if services are loaded with file" do
|
||||
expect(Service::ServicesCli).not_to receive(:run)
|
||||
expect(Service::ServicesCli).to receive(:start).once
|
||||
expect(Service::ServicesCli).to receive(:stop).once
|
||||
service = instance_double(Service::FormulaWrapper, service_name: "name", loaded?: true,
|
||||
expect(Services::Cli).not_to receive(:run)
|
||||
expect(Services::Cli).to receive(:start).once
|
||||
expect(Services::Cli).to receive(:stop).once
|
||||
service = instance_double(Services::FormulaWrapper, service_name: "name", loaded?: true,
|
||||
service_file_present?: true)
|
||||
expect(described_class.run([service], verbose: false)).to be_nil
|
||||
end
|
||||
|
||||
it "runs if services are loaded without file" do
|
||||
expect(Service::ServicesCli).not_to receive(:start)
|
||||
expect(Service::ServicesCli).to receive(:run).once
|
||||
expect(Service::ServicesCli).to receive(:stop).once
|
||||
service = instance_double(Service::FormulaWrapper, service_name: "name", loaded?: true,
|
||||
expect(Services::Cli).not_to receive(:start)
|
||||
expect(Services::Cli).to receive(:run).once
|
||||
expect(Services::Cli).to receive(:stop).once
|
||||
service = instance_double(Services::FormulaWrapper, service_name: "name", loaded?: true,
|
||||
service_file_present?: false)
|
||||
expect(described_class.run([service], verbose: false)).to be_nil
|
||||
end
|
||||
|
@ -1,8 +1,8 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "services/service"
|
||||
require "services/formulae"
|
||||
|
||||
RSpec.describe Service::Formulae do
|
||||
RSpec.describe Services::Formulae do
|
||||
describe "#services_list" do
|
||||
it "empty list without available formulae" do
|
||||
allow(described_class).to receive(:available_services).and_return({})
|
||||
@ -10,7 +10,7 @@ RSpec.describe Service::Formulae do
|
||||
end
|
||||
|
||||
it "list with available formulae" do
|
||||
formula = instance_double(Service::FormulaWrapper)
|
||||
formula = instance_double(Services::FormulaWrapper)
|
||||
expected = [
|
||||
{
|
||||
file: Pathname.new("/Library/LaunchDaemons/file.plist"),
|
||||
|
@ -1,9 +1,10 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "services/service"
|
||||
require "services/system"
|
||||
require "services/formula_wrapper"
|
||||
require "tempfile"
|
||||
|
||||
RSpec.describe Service::FormulaWrapper do
|
||||
RSpec.describe Services::FormulaWrapper do
|
||||
subject(:service) { described_class.new(formula) }
|
||||
|
||||
let(:formula) do
|
||||
@ -40,17 +41,17 @@ RSpec.describe Service::FormulaWrapper do
|
||||
|
||||
describe "#service_file" do
|
||||
it "macOS - outputs the full service file path" do
|
||||
allow(Service::System).to receive(:launchctl?).and_return(true)
|
||||
allow(Services::System).to receive(:launchctl?).and_return(true)
|
||||
expect(service.service_file.to_s).to eq("/usr/local/opt/mysql/homebrew.mysql.plist")
|
||||
end
|
||||
|
||||
it "systemD - outputs the full service file path" do
|
||||
allow(Service::System).to receive_messages(launchctl?: false, systemctl?: true)
|
||||
allow(Services::System).to receive_messages(launchctl?: false, systemctl?: true)
|
||||
expect(service.service_file.to_s).to eq("/usr/local/opt/mysql/homebrew.mysql.service")
|
||||
end
|
||||
|
||||
it "Other - outputs no service file" do
|
||||
allow(Service::System).to receive_messages(launchctl?: false, systemctl?: false)
|
||||
allow(Services::System).to receive_messages(launchctl?: false, systemctl?: false)
|
||||
expect(service.service_file).to be_nil
|
||||
end
|
||||
end
|
||||
@ -63,45 +64,45 @@ RSpec.describe Service::FormulaWrapper do
|
||||
|
||||
describe "#service_name" do
|
||||
it "macOS - outputs the service name" do
|
||||
allow(Service::System).to receive(:launchctl?).and_return(true)
|
||||
allow(Services::System).to receive(:launchctl?).and_return(true)
|
||||
expect(service.service_name).to eq("plist-mysql-test")
|
||||
end
|
||||
|
||||
it "systemD - outputs the service name" do
|
||||
allow(Service::System).to receive_messages(launchctl?: false, systemctl?: true)
|
||||
allow(Services::System).to receive_messages(launchctl?: false, systemctl?: true)
|
||||
expect(service.service_name).to eq("plist-mysql-test")
|
||||
end
|
||||
|
||||
it "Other - outputs no service name" do
|
||||
allow(Service::System).to receive_messages(launchctl?: false, systemctl?: false)
|
||||
allow(Services::System).to receive_messages(launchctl?: false, systemctl?: false)
|
||||
expect(service.service_name).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe "#dest_dir" do
|
||||
before do
|
||||
allow(Service::System).to receive_messages(launchctl?: false, systemctl?: false)
|
||||
allow(Services::System).to receive_messages(launchctl?: false, systemctl?: false)
|
||||
end
|
||||
|
||||
it "macOS - user - outputs the destination directory for the service file" do
|
||||
ENV["HOME"] = "/tmp_home"
|
||||
allow(Service::System).to receive_messages(root?: false, launchctl?: true)
|
||||
allow(Services::System).to receive_messages(root?: false, launchctl?: true)
|
||||
expect(service.dest_dir.to_s).to eq("/tmp_home/Library/LaunchAgents")
|
||||
end
|
||||
|
||||
it "macOS - root - outputs the destination directory for the service file" do
|
||||
allow(Service::System).to receive_messages(launchctl?: true, root?: true)
|
||||
allow(Services::System).to receive_messages(launchctl?: true, root?: true)
|
||||
expect(service.dest_dir.to_s).to eq("/Library/LaunchDaemons")
|
||||
end
|
||||
|
||||
it "systemD - user - outputs the destination directory for the service file" do
|
||||
ENV["HOME"] = "/tmp_home"
|
||||
allow(Service::System).to receive_messages(root?: false, launchctl?: false, systemctl?: true)
|
||||
allow(Services::System).to receive_messages(root?: false, launchctl?: false, systemctl?: true)
|
||||
expect(service.dest_dir.to_s).to eq("/tmp_home/.config/systemd/user")
|
||||
end
|
||||
|
||||
it "systemD - root - outputs the destination directory for the service file" do
|
||||
allow(Service::System).to receive_messages(root?: true, launchctl?: false, systemctl?: true)
|
||||
allow(Services::System).to receive_messages(root?: true, launchctl?: false, systemctl?: true)
|
||||
expect(service.dest_dir.to_s).to eq("/usr/lib/systemd/system")
|
||||
end
|
||||
end
|
||||
@ -109,16 +110,16 @@ RSpec.describe Service::FormulaWrapper do
|
||||
describe "#dest" do
|
||||
before do
|
||||
ENV["HOME"] = "/tmp_home"
|
||||
allow(Service::System).to receive_messages(launchctl?: false, systemctl?: false)
|
||||
allow(Services::System).to receive_messages(launchctl?: false, systemctl?: false)
|
||||
end
|
||||
|
||||
it "macOS - outputs the destination for the service file" do
|
||||
allow(Service::System).to receive(:launchctl?).and_return(true)
|
||||
allow(Services::System).to receive(:launchctl?).and_return(true)
|
||||
expect(service.dest.to_s).to eq("/tmp_home/Library/LaunchAgents/homebrew.mysql.plist")
|
||||
end
|
||||
|
||||
it "systemD - outputs the destination for the service file" do
|
||||
allow(Service::System).to receive(:systemctl?).and_return(true)
|
||||
allow(Services::System).to receive(:systemctl?).and_return(true)
|
||||
expect(service.dest.to_s).to eq("/tmp_home/.config/systemd/user/homebrew.mysql.service")
|
||||
end
|
||||
end
|
||||
@ -131,20 +132,20 @@ RSpec.describe Service::FormulaWrapper do
|
||||
|
||||
describe "#loaded?" do
|
||||
it "macOS - outputs if the service is loaded" do
|
||||
allow(Service::System).to receive_messages(launchctl?: true, systemctl?: false)
|
||||
allow(Services::System).to receive_messages(launchctl?: true, systemctl?: false)
|
||||
allow(Utils).to receive(:safe_popen_read)
|
||||
expect(service.loaded?).to be(false)
|
||||
end
|
||||
|
||||
it "systemD - outputs if the service is loaded" do
|
||||
allow(Service::System).to receive_messages(launchctl?: false, systemctl?: true)
|
||||
allow(Service::System::Systemctl).to receive(:quiet_run).and_return(false)
|
||||
allow(Services::System).to receive_messages(launchctl?: false, systemctl?: true)
|
||||
allow(Services::System::Systemctl).to receive(:quiet_run).and_return(false)
|
||||
allow(Utils).to receive(:safe_popen_read)
|
||||
expect(service.loaded?).to be(false)
|
||||
end
|
||||
|
||||
it "Other - outputs no status" do
|
||||
allow(Service::System).to receive_messages(launchctl?: false, systemctl?: false)
|
||||
allow(Services::System).to receive_messages(launchctl?: false, systemctl?: false)
|
||||
expect(service.loaded?).to be_nil
|
||||
end
|
||||
end
|
||||
@ -181,7 +182,7 @@ RSpec.describe Service::FormulaWrapper do
|
||||
it "user if file present" do
|
||||
allow(service).to receive_messages(boot_path_service_file_present?: false,
|
||||
user_path_service_file_present?: true)
|
||||
allow(Service::System).to receive(:user).and_return("user")
|
||||
allow(Services::System).to receive(:user).and_return("user")
|
||||
expect(service.owner).to eq("user")
|
||||
end
|
||||
|
||||
@ -194,24 +195,24 @@ RSpec.describe Service::FormulaWrapper do
|
||||
|
||||
describe "#service_file_present?" do
|
||||
it "macOS - outputs if the service file is present" do
|
||||
allow(Service::System).to receive_messages(launchctl?: true, systemctl?: false)
|
||||
allow(Services::System).to receive_messages(launchctl?: true, systemctl?: false)
|
||||
expect(service.service_file_present?).to be(false)
|
||||
end
|
||||
|
||||
it "macOS - outputs if the service file is present for root" do
|
||||
allow(Service::System).to receive_messages(launchctl?: true, systemctl?: false)
|
||||
allow(Services::System).to receive_messages(launchctl?: true, systemctl?: false)
|
||||
expect(service.service_file_present?(for: :root)).to be(false)
|
||||
end
|
||||
|
||||
it "macOS - outputs if the service file is present for user" do
|
||||
allow(Service::System).to receive_messages(launchctl?: true, systemctl?: false)
|
||||
allow(Services::System).to receive_messages(launchctl?: true, systemctl?: false)
|
||||
expect(service.service_file_present?(for: :user)).to be(false)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#owner?" do
|
||||
it "macOS - outputs the service file owner" do
|
||||
allow(Service::System).to receive_messages(launchctl?: true, systemctl?: false)
|
||||
allow(Services::System).to receive_messages(launchctl?: true, systemctl?: false)
|
||||
expect(service.owner).to be_nil
|
||||
end
|
||||
end
|
||||
@ -320,7 +321,7 @@ RSpec.describe Service::FormulaWrapper do
|
||||
|
||||
describe "#to_hash" do
|
||||
it "represents non-service values" do
|
||||
allow(Service::System).to receive_messages(launchctl?: true, systemctl?: false)
|
||||
allow(Services::System).to receive_messages(launchctl?: true, systemctl?: false)
|
||||
allow_any_instance_of(described_class).to receive_messages(service?: false, service_file_present?: false)
|
||||
expected = {
|
||||
exit_code: nil,
|
||||
@ -339,7 +340,7 @@ RSpec.describe Service::FormulaWrapper do
|
||||
|
||||
it "represents running non-service values" do
|
||||
ENV["HOME"] = "/tmp_home"
|
||||
allow(Service::System).to receive_messages(launchctl?: true, systemctl?: false)
|
||||
allow(Services::System).to receive_messages(launchctl?: true, systemctl?: false)
|
||||
expect(service).to receive(:service?).twice.and_return(false)
|
||||
expect(service).to receive(:service_file_present?).and_return(true)
|
||||
expected = {
|
||||
@ -359,7 +360,7 @@ RSpec.describe Service::FormulaWrapper do
|
||||
|
||||
it "represents service values" do
|
||||
ENV["HOME"] = "/tmp_home"
|
||||
allow(Service::System).to receive_messages(launchctl?: true, systemctl?: false)
|
||||
allow(Services::System).to receive_messages(launchctl?: true, systemctl?: false)
|
||||
expect(service).to receive(:service?).twice.and_return(true)
|
||||
expect(service).to receive(:service_file_present?).and_return(true)
|
||||
expect(service).to receive(:load_service).twice.and_return(service_object)
|
||||
|
@ -1,16 +1,17 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "services/service"
|
||||
require "services/system"
|
||||
require "services/system/systemctl"
|
||||
|
||||
RSpec.describe Service::System::Systemctl do
|
||||
RSpec.describe Services::System::Systemctl do
|
||||
describe ".scope" do
|
||||
it "outputs systemctl scope for user" do
|
||||
allow(Service::System).to receive(:root?).and_return(false)
|
||||
allow(Services::System).to receive(:root?).and_return(false)
|
||||
expect(described_class.scope).to eq("--user")
|
||||
end
|
||||
|
||||
it "outputs systemctl scope for root" do
|
||||
allow(Service::System).to receive(:root?).and_return(true)
|
||||
allow(Services::System).to receive(:root?).and_return(true)
|
||||
expect(described_class.scope).to eq("--system")
|
||||
end
|
||||
end
|
||||
|
@ -1,8 +1,8 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "services/service"
|
||||
require "services/system"
|
||||
|
||||
RSpec.describe Service::System do
|
||||
RSpec.describe Services::System do
|
||||
describe "#launchctl" do
|
||||
it "macOS - outputs launchctl command location", :needs_macos do
|
||||
expect(described_class.launchctl).to eq(Pathname.new("/bin/launchctl"))
|
||||
|
@ -286,7 +286,7 @@ RSpec.configure do |config|
|
||||
HOMEBREW_LIBRARY/"Taps/homebrew/homebrew-bar",
|
||||
HOMEBREW_LIBRARY/"Taps/homebrew/homebrew-bundle",
|
||||
HOMEBREW_LIBRARY/"Taps/homebrew/homebrew-foo",
|
||||
HOMEBREW_LIBRARY/"Taps/homebrew/homebrew-services",
|
||||
HOMEBREW_LIBRARY/"Taps/homebrew/homebrew-test-bot",
|
||||
HOMEBREW_LIBRARY/"Taps/homebrew/homebrew-shallow",
|
||||
HOMEBREW_LIBRARY/"PinnedTaps",
|
||||
HOMEBREW_REPOSITORY/".git",
|
||||
|
@ -214,11 +214,11 @@ RSpec.describe Tap do
|
||||
expect(homebrew_foo_tap.remote).to eq("https://github.com/Homebrew/homebrew-foo")
|
||||
expect(homebrew_foo_tap).not_to have_custom_remote
|
||||
|
||||
services_tap = described_class.fetch("Homebrew", "services")
|
||||
services_tap = described_class.fetch("Homebrew", "test-bot")
|
||||
services_tap.path.mkpath
|
||||
services_tap.path.cd do
|
||||
system "git", "init"
|
||||
system "git", "remote", "add", "origin", "https://github.com/Homebrew/homebrew-services"
|
||||
system "git", "remote", "add", "origin", "https://github.com/Homebrew/homebrew-test-bot"
|
||||
end
|
||||
expect(services_tap).not_to be_private
|
||||
end
|
||||
@ -240,7 +240,7 @@ RSpec.describe Tap do
|
||||
|
||||
expect(homebrew_foo_tap.remote_repository).to eq("Homebrew/homebrew-foo")
|
||||
|
||||
services_tap = described_class.fetch("Homebrew", "services")
|
||||
services_tap = described_class.fetch("Homebrew", "test-bot")
|
||||
services_tap.path.mkpath
|
||||
services_tap.path.cd do
|
||||
system "git", "init"
|
||||
@ -254,7 +254,7 @@ RSpec.describe Tap do
|
||||
|
||||
expect(homebrew_foo_tap.remote_repository).to eq("Homebrew/homebrew-foo")
|
||||
|
||||
services_tap = described_class.fetch("Homebrew", "services")
|
||||
services_tap = described_class.fetch("Homebrew", "test-bot")
|
||||
services_tap.path.mkpath
|
||||
services_tap.path.cd do
|
||||
system "git", "init"
|
||||
@ -275,7 +275,7 @@ RSpec.describe Tap do
|
||||
end
|
||||
|
||||
describe "#custom_remote?" do
|
||||
subject(:tap) { described_class.fetch("Homebrew", "services") }
|
||||
subject(:tap) { described_class.fetch("Homebrew", "test-bot") }
|
||||
|
||||
let(:remote) { nil }
|
||||
|
||||
@ -293,13 +293,13 @@ RSpec.describe Tap do
|
||||
end
|
||||
|
||||
context "when using the default remote" do
|
||||
let(:remote) { "https://github.com/Homebrew/homebrew-services" }
|
||||
let(:remote) { "https://github.com/Homebrew/homebrew-test-bot" }
|
||||
|
||||
it(:custom_remote?) { expect(tap.custom_remote?).to be false }
|
||||
end
|
||||
|
||||
context "when using a non-default remote" do
|
||||
let(:remote) { "git@github.com:Homebrew/homebrew-services" }
|
||||
let(:remote) { "git@github.com:Homebrew/homebrew-test-bot" }
|
||||
|
||||
it(:custom_remote?) { expect(tap.custom_remote?).to be true }
|
||||
end
|
||||
|
@ -40,7 +40,7 @@ An executable script for a command named `extcmd` should be named `brew-extcmd`.
|
||||
|
||||
## Providing `--help`
|
||||
|
||||
All internal and external Homebrew commands can provide styled `--help` output by using Homebrew’s [argument parser](https://rubydoc.brew.sh/Homebrew/CLI/Parser), as seen in the [`brew services` command](https://github.com/Homebrew/homebrew-services/blob/HEAD/cmd/services.rb); or by including lines starting with `#:` (a comment then `:` character in both Bash and Ruby), as seen in the [header of `update.sh`](https://github.com/Homebrew/brew/blob/cf7def0c68903814c6b4e04a55fe8f3cb3f5605e/Library/Homebrew/cmd/update.sh#L1-L10), which is printed with `brew update --help`.
|
||||
All internal and external Homebrew commands can provide styled `--help` output by using Homebrew’s [argument parser](https://rubydoc.brew.sh/Homebrew/CLI/Parser), as seen in the [`brew test-bot` command](https://github.com/Homebrew/homebrew-test-bot/blob/HEAD/cmd/test-bot.rb); or by including lines starting with `#:` (a comment then `:` character in both Bash and Ruby), as seen in the [header of `update.sh`](https://github.com/Homebrew/brew/blob/cf7def0c68903814c6b4e04a55fe8f3cb3f5605e/Library/Homebrew/cmd/update.sh#L1-L10), which is printed with `brew update --help`.
|
||||
|
||||
## Unofficial external commands
|
||||
|
||||
|
@ -27,7 +27,7 @@ A *formula* is a package definition written in Ruby. It can be created with `bre
|
||||
| **bottle** | pre-built **keg** poured into a **rack** of the **Cellar** instead of building from upstream sources | `qt--6.5.1.ventura.bottle.tar.gz` |
|
||||
| **tab** | information about a **keg**, e.g. whether it was poured from a **bottle** or built from source | `/opt/homebrew/Cellar/foo/0.1/INSTALL_RECEIPT.json` |
|
||||
| **Brew Bundle** | an [extension of Homebrew](https://github.com/Homebrew/homebrew-bundle) to describe dependencies | `brew 'myservice', restart_service: true` |
|
||||
| **Brew Services** | an [extension of Homebrew](https://github.com/Homebrew/homebrew-services) to manage services | `brew services start myservice` |
|
||||
| **Brew Services** | the Homebrew command to manage background services | `brew services start myservice` |
|
||||
|
||||
## An introduction
|
||||
|
||||
@ -1042,7 +1042,7 @@ Another example would be configuration files that should not be overwritten on p
|
||||
|
||||
### Service files
|
||||
|
||||
There are two ways to add `launchd` plists and `systemd` services to a formula, so that [`brew services`](https://github.com/Homebrew/homebrew-services) can pick them up:
|
||||
There are two ways to add `launchd` plists and `systemd` services to a formula, so that `brew services` can pick them up:
|
||||
|
||||
1. If the package already provides a service file the formula can reference it by name:
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user