(mut options: ServiceOptions)
| 135 | } |
| 136 | |
| 137 | fn install(mut options: ServiceOptions) -> anyhow::Result<ServiceInstallResult> { |
| 138 | let plist_path = plist_path()?; |
| 139 | let log_dir = log_dir()?; |
| 140 | fs::create_dir_all( |
| 141 | plist_path |
| 142 | .parent() |
| 143 | .ok_or_else(|| anyhow!("resolve LaunchAgents directory"))?, |
| 144 | )?; |
| 145 | fs::create_dir_all(&log_dir)?; |
| 146 | |
| 147 | let client_root = match options.client_root.as_ref() { |
| 148 | Some(path) => path.clone(), |
| 149 | None => default_client_root()?, |
| 150 | }; |
| 151 | let executable = current_executable_path()?; |
| 152 | let stdout_log = log_dir.join("simdeck.log"); |
| 153 | let stderr_log = log_dir.join("simdeck.err.log"); |
| 154 | |
| 155 | let domain = launchctl_domain()?; |
| 156 | unload_existing_services(&domain)?; |
| 157 | |
| 158 | options.port = choose_service_port_for_bind(options.port, options.bind)?; |
| 159 | let plist = plist_contents( |
| 160 | &executable, |
| 161 | &client_root, |
| 162 | &stdout_log, |
| 163 | &stderr_log, |
| 164 | &options, |
| 165 | ); |
| 166 | |
| 167 | fs::write(&plist_path, plist).with_context(|| format!("write {}", plist_path.display()))?; |
| 168 | |
| 169 | run_launchctl(["bootstrap", &domain, plist_path.to_string_lossy().as_ref()])?; |
| 170 | |
| 171 | let advertise_host = options.advertise_host.clone(); |
| 172 | let access_token = options.access_token.clone(); |
| 173 | let pairing_code = options.pairing_code.clone(); |
| 174 | Ok(ServiceInstallResult { |
| 175 | service: SERVICE_LABEL.to_owned(), |
| 176 | plist_path, |
| 177 | executable_path: executable, |
| 178 | stdout_log, |
| 179 | stderr_log, |
| 180 | port: options.port, |
| 181 | advertise_host, |
| 182 | access_token, |
| 183 | pairing_code, |
| 184 | reused: false, |
| 185 | }) |
| 186 | } |
| 187 | |
| 188 | fn print_install_result(result: &ServiceInstallResult) -> anyhow::Result<()> { |
| 189 | println!( |
no test coverage detected