| 
									
										
										
										
											2024-08-10 15:03:52 +01:00
										 |  |  | # typed: strict | 
					
						
							| 
									
										
										
										
											2023-04-13 23:33:31 -07:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module Utils | 
					
						
							|  |  |  |   # Helpers for `brew services` related code. | 
					
						
							|  |  |  |   module Service | 
					
						
							|  |  |  |     # Check if a service is running for a specified formula. | 
					
						
							|  |  |  |     sig { params(formula: Formula).returns(T::Boolean) } | 
					
						
							|  |  |  |     def self.running?(formula) | 
					
						
							|  |  |  |       if launchctl? | 
					
						
							|  |  |  |         quiet_system(launchctl, "list", formula.plist_name) | 
					
						
							|  |  |  |       elsif systemctl? | 
					
						
							|  |  |  |         quiet_system(systemctl, "is-active", "--quiet", formula.service_name) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Check if a service file is installed in the expected location. | 
					
						
							|  |  |  |     sig { params(formula: Formula).returns(T::Boolean) } | 
					
						
							|  |  |  |     def self.installed?(formula) | 
					
						
							|  |  |  |       (launchctl? && formula.launchd_service_path.exist?) || | 
					
						
							|  |  |  |         (systemctl? && formula.systemd_service_path.exist?) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Path to launchctl binary. | 
					
						
							|  |  |  |     sig { returns(T.nilable(Pathname)) } | 
					
						
							|  |  |  |     def self.launchctl | 
					
						
							|  |  |  |       return @launchctl if defined? @launchctl | 
					
						
							| 
									
										
										
										
											2023-12-07 03:16:15 +00:00
										 |  |  |       return if ENV["HOMEBREW_TEST_GENERIC_OS"] | 
					
						
							| 
									
										
										
										
											2023-04-13 23:33:31 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-10 15:03:52 +01:00
										 |  |  |       @launchctl = T.let(which("launchctl"), T.nilable(Pathname)) | 
					
						
							| 
									
										
										
										
											2023-04-13 23:33:31 -07:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Path to systemctl binary. | 
					
						
							|  |  |  |     sig { returns(T.nilable(Pathname)) } | 
					
						
							|  |  |  |     def self.systemctl | 
					
						
							|  |  |  |       return @systemctl if defined? @systemctl | 
					
						
							| 
									
										
										
										
											2023-12-07 03:16:15 +00:00
										 |  |  |       return if ENV["HOMEBREW_TEST_GENERIC_OS"] | 
					
						
							| 
									
										
										
										
											2023-04-13 23:33:31 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-10 15:03:52 +01:00
										 |  |  |       @systemctl = T.let(which("systemctl"), T.nilable(Pathname)) | 
					
						
							| 
									
										
										
										
											2023-04-13 23:33:31 -07:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     sig { returns(T::Boolean) } | 
					
						
							|  |  |  |     def self.launchctl? | 
					
						
							|  |  |  |       !launchctl.nil? | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     sig { returns(T::Boolean) } | 
					
						
							|  |  |  |     def self.systemctl? | 
					
						
							|  |  |  |       !systemctl.nil? | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2024-12-04 02:45:09 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Quote a string for use in systemd command lines, e.g., in `ExecStart`. | 
					
						
							|  |  |  |     # https://www.freedesktop.org/software/systemd/man/latest/systemd.syntax.html#Quoting | 
					
						
							|  |  |  |     sig { params(str: String).returns(String) } | 
					
						
							|  |  |  |     def self.systemd_quote(str) | 
					
						
							|  |  |  |       result = +"\"" | 
					
						
							|  |  |  |       # No need to escape single quotes and spaces, as we're always double | 
					
						
							|  |  |  |       # quoting the entire string. | 
					
						
							|  |  |  |       str.each_char do |char| | 
					
						
							|  |  |  |         result << case char | 
					
						
							| 
									
										
										
										
											2024-12-04 03:09:11 +08:00
										 |  |  |         when "\a" then "\\a" | 
					
						
							|  |  |  |         when "\b" then "\\b" | 
					
						
							|  |  |  |         when "\f" then "\\f" | 
					
						
							|  |  |  |         when "\n" then "\\n" | 
					
						
							|  |  |  |         when "\r" then "\\r" | 
					
						
							|  |  |  |         when "\t" then "\\t" | 
					
						
							|  |  |  |         when "\v" then "\\v" | 
					
						
							|  |  |  |         when "\\" then "\\\\" | 
					
						
							|  |  |  |         when "\"" then "\\\"" | 
					
						
							|  |  |  |         else char | 
					
						
							| 
									
										
										
										
											2024-12-04 02:45:09 +08:00
										 |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |       result << "\"" | 
					
						
							|  |  |  |       result.freeze | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2023-04-13 23:33:31 -07:00
										 |  |  |   end | 
					
						
							|  |  |  | end |