### Execute Installer Command Source: https://docs.rs/axoupdater/0.10.0/src/axoupdater/lib.rs.html Configures and executes an installer command, handling platform-specific arguments and environment variables. It captures the output and status of the installation process. ```rust let path = if cfg!(windows) { "powershell" } else { installer_path.as_str() }; let mut command = Cmd::new(path, "execute installer"); if cfg!(windows) { // don't fall over on default security-policy windows machines // which require opt-in to execing powershell scripts. // This doesn't bypass proper organization-set policies. command.arg("-ExecutionPolicy").arg("ByPass"); command.arg(&installer_path); } if self.print_installer_stdout { command.stdout(Stdio::inherit()); } if self.print_installer_stderr { command.stderr(Stdio::inherit()); } command.check(false); // On Windows, fixes a bug that occurs if the parent process is // PowerShell Core. // https://github.com/PowerShell/PowerShell/issues/18530 command.env_remove("PSModulePath"); let install_prefix = self.install_prefix_root()?; // Forces the generated installer to install to exactly this path, // regardless of how it's configured to install. command.env("CARGO_DIST_FORCE_INSTALL_DIR", &install_prefix); // Also set the app-specific name for this; in the future, the // CARGO_DIST_ version may be removed. let app_name = self.name.clone().unwrap_or_default(); let app_name_env_var = app_name_to_env_var(&app_name); let app_specific_env_var = format!("{app_name_env_var}_INSTALL_DIR"); command.env(app_specific_env_var, &install_prefix); // If the previous installation didn't modify the path, we shouldn't either if !self.modify_path { let app_specific_modify_path = format!("{app_name_env_var}_NO_MODIFY_PATH"); command.env(app_specific_modify_path, "1"); } let result = command.output(); ``` -------------------------------- ### Enable Installer Stdout Source: https://docs.rs/axoupdater/0.10.0/axoupdater/struct.AxoUpdater.html Enables the display of the underlying installer's standard output. ```rust pub fn enable_installer_stdout(&mut self) -> &mut AxoUpdater ``` -------------------------------- ### Configure Installer Path for AxoUpdater Source: https://docs.rs/axoupdater/0.10.0/src/axoupdater/lib.rs.html Sets a specific path for the installer, overriding the default behavior of downloading from the release source. Use this when you have a pre-determined installer location. ```rust pub fn configure_installer_path(&mut self, path: impl Into) -> &mut AxoUpdater { self.installer_path = Some(path.into().to_owned()); self } ``` -------------------------------- ### Get Potential Install Receipt Configuration Paths Source: https://docs.rs/axoupdater/0.10.0/src/axoupdater/receipt.rs.html Generates a list of possible locations for install receipts, prioritizing XDG_CONFIG_HOME if it's set. This function is part of the process to locate an existing install receipt. ```rust pub(crate) fn get_config_paths(app_name: &str) -> AxoupdateResult> { let mut potential_homes = vec![]; ``` -------------------------------- ### Use Release Installer for AxoUpdater Source: https://docs.rs/axoupdater/0.10.0/src/axoupdater/lib.rs.html Resets the installer path to `None`, enabling AxoUpdater to use the installer from the new release by default. This is the standard behavior. ```rust pub fn use_release_installer(&mut self) -> &mut AxoUpdater { self.installer_path = None; self } ``` -------------------------------- ### Enable All Installer Output Source: https://docs.rs/axoupdater/0.10.0/axoupdater/struct.AxoUpdater.html Enables all output streams (stdout and stderr) for the underlying installer. ```rust pub fn enable_installer_output(&mut self) -> &mut AxoUpdater ``` -------------------------------- ### Enable Installer Stdout Source: https://docs.rs/axoupdater/0.10.0/src/axoupdater/lib.rs.html Use `enable_installer_stdout` to ensure that the standard output of the underlying installer process is printed. This is enabled by default. ```rust pub fn enable_installer_stdout(&mut self) -> &mut AxoUpdater { self.print_installer_stdout = true; self } ``` -------------------------------- ### Enable All Installer Output Source: https://docs.rs/axoupdater/0.10.0/src/axoupdater/lib.rs.html Use `enable_installer_output` to enable both standard output and standard error printing for the underlying installer. This is the default behavior. ```rust pub fn enable_installer_output(&mut self) -> &mut AxoUpdater { self.print_installer_stdout = true; self.print_installer_stderr = true; self } ``` -------------------------------- ### Set Installation Directory for AxoUpdater Source: https://docs.rs/axoupdater/0.10.0/src/axoupdater/lib.rs.html Specifies the directory where the application will be installed. This is primarily used when installing without an explicit install prefix. ```rust pub fn set_install_dir(&mut self, path: impl Into) -> &mut AxoUpdater { self.install_prefix = Some(path.into()); self } ``` -------------------------------- ### Function Signature: perform_runtest Source: https://docs.rs/axoupdater/0.10.0/axoupdater/test/helpers/fn.perform_runtest.html This function installs your app and runs its updater. It performs assertions and returns the binary's installation path. Recommended for CI builds as it writes to real files. It always attempts to install to CARGO_HOME (~/.cargo/bin). ```rust pub fn perform_runtest(runtest_args: &RuntestArgs) -> PathBuf ``` -------------------------------- ### Execute installation test Source: https://docs.rs/axoupdater/0.10.0/src/axoupdater/test/helpers.rs.html Performs an installation of the application to the user's home directory and runs the updater. This function is intended for CI environments as it modifies the local filesystem. ```rust pub fn perform_runtest(runtest_args: &RuntestArgs) -> PathBuf { let RuntestArgs { app_name, package, owner, bin, binaries, args, release_type, } = runtest_args; let basename = bin.file_name().unwrap(); let home = homedir::my_home().unwrap().unwrap(); let app_home = &home.join(".cargo").join("bin"); let app_path = &app_home.join(basename); let config_path = get_config_paths(app_name) .unwrap() // Accept whichever path comes first; it doesn't matter to us. .first() .expect("no possible legal config paths found!?") .to_owned() .into_std_path_buf(); // Ensure we delete any previous copy that may exist // at this path before we copy in our version. if app_path.exists() { std::fs::remove_file(app_path).unwrap(); } assert!(!app_path.exists()); // Install to the home directory std::fs::copy(bin, app_path).unwrap(); // Create a fake install receipt // We lie about being a very old version so we always ``` -------------------------------- ### Installer Output Control Source: https://docs.rs/axoupdater/0.10.0/axoupdater/struct.AxoUpdater.html Methods for controlling the output of the underlying installer process. ```APIDOC ## Installer Output Control ### `enable_installer_stdout()` Enables printing the underlying installer’s stdout. ### `disable_installer_stdout()` Disables printing the underlying installer’s stdout. ### `enable_installer_stderr()` Enables printing the underlying installer’s stderr. ### `disable_installer_stderr()` Disables printing the underlying installer’s stderr. ### `enable_installer_output()` Enables all output for the underlying installer. ### `disable_installer_output()` Disables all output for the underlying installer. ``` -------------------------------- ### Use Release Installer Source: https://docs.rs/axoupdater/0.10.0/axoupdater/struct.AxoUpdater.html Configures AxoUpdater to use the installer provided within the release package. This is the default behavior. ```rust pub fn use_release_installer(&mut self) -> &mut AxoUpdater ``` -------------------------------- ### Load Install Receipt for AxoUpdater Source: https://docs.rs/axoupdater/0.10.0/src/axoupdater/receipt.rs.html Attempts to load an install receipt to prepare for an update. If present and valid, it populates the `source` and `current_version` fields. Shell and Powershell installers produced by cargo-dist since 0.9.0 will have created an install receipt. ```rust pub fn load_receipt(&mut self) -> AxoupdateResult<&mut AxoUpdater> { let Some(app_name) = self.name.clone() else { return Err(AxoupdateError::NoAppNamePassed {}); }; self.load_receipt_as(&app_name) } ``` -------------------------------- ### GET /repos/{owner}/{name}/releases/latest Source: https://docs.rs/axoupdater/0.10.0/src/axoupdater/release/github.rs.html Fetches the latest GitHub release for a specific repository, ensuring it contains an installer asset. ```APIDOC ## GET /repos/{owner}/{name}/releases/latest ### Description Retrieves the latest release metadata for a repository. It validates that the release contains an installer asset starting with the application name. ### Method GET ### Endpoint {api}/repos/{owner}/{name}/releases/latest ### Parameters #### Path Parameters - **owner** (string) - Required - The owner of the repository - **name** (string) - Required - The repository name ### Response #### Success Response (200) - **tag_name** (string) - The tag this release represents - **name** (string) - The name of the release - **url** (string) - The URL at which this release lists - **assets** (array) - List of assets associated with the release - **prerelease** (boolean) - Whether or not this release is a prerelease ``` -------------------------------- ### Configure Custom Installer Path Source: https://docs.rs/axoupdater/0.10.0/axoupdater/struct.AxoUpdater.html Specifies a custom path for the installer executable to be used for the new release. ```rust pub fn configure_installer_path( &mut self, path: impl Into, ) -> &mut AxoUpdater ``` -------------------------------- ### Enable Installer Stderr Source: https://docs.rs/axoupdater/0.10.0/src/axoupdater/lib.rs.html Use `enable_installer_stderr` to ensure that the standard error of the underlying installer process is printed. This is enabled by default. ```rust pub fn enable_installer_stderr(&mut self) -> &mut AxoUpdater { self.print_installer_stderr = true; self } ``` -------------------------------- ### Load Install Receipt for Specific App Source: https://docs.rs/axoupdater/0.10.0/axoupdater/struct.AxoUpdater.html Loads an install receipt for a specified application name, useful if the receipt might exist under different names. ```rust pub fn load_receipt_as( &mut self, app_name: &str, ) -> AxoupdateResult<&mut AxoUpdater> ``` -------------------------------- ### Test Installation Directory Configuration Source: https://docs.rs/axoupdater/0.10.0/src/axoupdater/lib.rs.html Unit tests verifying that set_install_dir accepts various path types including &str, String, and PathBuf. ```rust #[test] fn test_install_dir_path_str() { let mut updater = AxoUpdater::new(); updater.set_install_dir("/tmp"); } #[test] fn test_install_dir_path_string() { let mut updater = AxoUpdater::new(); updater.set_install_dir("/tmp".to_string()); } #[test] fn test_install_dir_path() { let mut updater = AxoUpdater::new(); let path = Path::new("/tmp"); updater.set_install_dir(&path.to_string_lossy()); } #[test] fn test_install_dir_pathbuf() { let mut updater = AxoUpdater::new(); let mut path = PathBuf::new(); path.push("/tmp"); updater.set_install_dir(&path.to_string_lossy()); } ``` -------------------------------- ### Execute update process Source: https://docs.rs/axoupdater/0.10.0/src/axoupdater/lib.rs.html Performs the update by checking if needed, fetching the release, downloading the appropriate installer, and handling Windows-specific file locking. ```rust pub async fn run(&mut self) -> AxoupdateResult> { if !self.is_update_needed().await? { return Ok(None); } let release = match &self.requested_release { Some(r) => r, None => { self.fetch_release().await?; self.requested_release.as_ref().unwrap() } }; let tempdir = TempDir::new()?; // If we've been given an installer path to use, skip downloading and // install from that. let installer_path = if let Some(path) = &self.installer_path { path.to_owned() // Otherwise, proceed with downloading the installer from the release // we just looked up. } else { let app_name = self.name.clone().unwrap_or_default(); let installer_url = match env::consts::OS { "macos" | "linux" => release .assets .iter() .find(|asset| asset.name == format!("{app_name}-installer.sh")), "windows" => release .assets .iter() .find(|asset| asset.name == format!("{app_name}-installer.ps1")), _ => unreachable!(), }; let installer_url = if let Some(installer_url) = installer_url { installer_url } else { return Err(AxoupdateError::NoInstallerForPackage {}); }; let extension = if cfg!(windows) { ".ps1" } else { ".sh" }; let installer_path = Utf8PathBuf::try_from(tempdir.path().join(format!("installer{extension}")))?; #[cfg(unix)] { let installer_file = File::create(&installer_path)?; let mut perms = installer_file.metadata()?.permissions(); perms.set_mode(0o744); installer_file.set_permissions(perms)?; } let download = self .client .get(&installer_url.browser_download_url) .header(reqwest::header::ACCEPT, "application/octet-stream") .send() .await? .text() .await?; LocalAsset::write_new_all(&download, &installer_path)?; installer_path }; // Before we update, rename ourselves to a temporary name. // This is necessary because Windows won't let an actively-running // executable be overwritten. // If the update fails, we'll move it back to where it was before // we began the update process. let to_restore = if cfg!(target_family = "windows") { let old_filename = std::env::current_exe()?; let mut new_filename = old_filename.as_os_str().to_os_string(); // Filename follows the pattern set here: https://docs.rs/self-replace/1.5.0/self_replace/#implementation new_filename.push(OsStr::new(".previous.exe")); std::fs::rename(&old_filename, &new_filename)?; ``` -------------------------------- ### GET /repos/{owner}/{name}/releases Source: https://docs.rs/axoupdater/0.10.0/src/axoupdater/release/github.rs.html Fetches all releases for a specific GitHub repository, handles pagination via Link headers, and filters for installer assets. ```APIDOC ## GET /repos/{owner}/{name}/releases ### Description Retrieves a list of releases from a GitHub repository. It automatically follows pagination links provided in the response headers and filters the results to include only those containing installer assets for the specified application. ### Method GET ### Endpoint {api}/repos/{owner}/{name}/releases ### Parameters #### Path Parameters - **owner** (string) - Required - The GitHub organization or user name. - **name** (string) - Required - The repository name. ### Request Example GET /repos/axodotdev/axoupdater/releases ### Response #### Success Response (200) - **data** (Array) - A list of filtered release objects. ``` -------------------------------- ### Load Install Receipt Source: https://docs.rs/axoupdater/0.10.0/axoupdater/struct.AxoUpdater.html Attempts to load an install receipt to prepare for an update. Requires the `axoupdater` crate. ```rust pub fn load_receipt(&mut self) -> AxoupdateResult<&mut AxoUpdater> ``` -------------------------------- ### Enable Installer Stderr Source: https://docs.rs/axoupdater/0.10.0/axoupdater/struct.AxoUpdater.html Enables the display of the underlying installer's standard error. ```rust pub fn enable_installer_stderr(&mut self) -> &mut AxoUpdater ``` -------------------------------- ### Provider Struct Source: https://docs.rs/axoupdater/0.10.0/src/axoupdater/lib.rs.html Information about the tool that produced an install receipt. ```APIDOC ## Provider Struct ### Description Represents the tool used to create an install receipt. ### Fields - **source** (String) - The name of the tool used to create this receipt. - **version** (Version) - The version of the tool specified in the `source` field. ``` -------------------------------- ### install_prefix_root Source: https://docs.rs/axoupdater/0.10.0/src/axoupdater/lib.rs.html Retrieves the root of the install prefix. ```APIDOC ## install_prefix_root ### Description Returns the root of the install prefix, stripping the final `/bin` component if necessary to handle inconsistencies in install receipts. ### Response - **AxoupdateResult** - The root path or an error if the install prefix is not configured. ``` -------------------------------- ### Test Installer Path Configuration Source: https://docs.rs/axoupdater/0.10.0/src/axoupdater/lib.rs.html Unit tests verifying that configure_installer_path accepts various path types including &str, String, and PathBuf. ```rust #[test] fn test_installer_path_str() { let mut updater = AxoUpdater::new(); updater.configure_installer_path("/tmp"); } #[test] fn test_installer_path_string() { let mut updater = AxoUpdater::new(); updater.configure_installer_path("/tmp".to_string()); } #[test] fn test_installer_path() { let mut updater = AxoUpdater::new(); let path = Path::new("/tmp"); updater.configure_installer_path(&path.to_string_lossy()); } #[test] fn test_installer_pathbuf() { let mut updater = AxoUpdater::new(); let mut path = PathBuf::new(); path.push("/tmp"); updater.configure_installer_path(&path.to_string_lossy()); } ``` -------------------------------- ### Handle Installation Result Source: https://docs.rs/axoupdater/0.10.0/src/axoupdater/lib.rs.html Processes the result of an installer command, determining if it failed and extracting stdout/stderr. It handles potential cleanup of temporary files on Windows. ```rust let failed; let stdout; let stderr; let statuscode; if let Ok(output) = &result { failed = !output.status.success(); stdout = if output.stdout.is_empty() { None } else { Some(String::from_utf8_lossy(&output.stdout).to_string()) }; stderr = if output.stderr.is_empty() { None } else { Some(String::from_utf8_lossy(&output.stderr).to_string()) }; statuscode = output.status.code(); } else { failed = true; stdout = None; stderr = None; statuscode = None; } if let Some((ourselves, old_path)) = to_restore { if failed { std::fs::rename(ourselves, old_path)?; } else { #[cfg(windows)] self_replace::self_delete_at(&ourselves) .map_err(|_| AxoupdateError::CleanupFailed {{ }})?; } } // Return the original AxoprocessError if we failed to launch // the command at all result?; // Otherwise return a more specific error with status code and // stdout/err. Note that this stdout/stderr will be None if the // caller requested us to print stdout/stderr to the terminal. if failed { return Err(AxoupdateError::InstallFailed { status: statuscode, stdout, stderr, }); } let result = UpdateResult { old_version: self.current_version.clone(), new_version: release.version.clone(), new_version_tag: release.tag_name.to_owned(), install_prefix, }; Ok(Some(result)) ``` -------------------------------- ### Receipt Handling Source: https://docs.rs/axoupdater/0.10.0/axoupdater/struct.AxoUpdater.html Methods for loading and checking installation receipts. ```APIDOC ## Receipt Handling ### `load_receipt()` Attempts to load an install receipt in order to prepare for an update. If present and valid, the install receipt is used to populate the `source` and `current_version` fields. Shell and Powershell installers produced by cargo-dist since 0.9.0 will have created an install receipt. ### `load_receipt_as(app_name: &str)` Similar to `AxoUpdater::load_receipt`, but loads a receipt for the app with the name `app_name` instead of the auto-detected name. This can be useful if the receipt may exist under several different names, for example if an app has been renamed. ### `check_receipt_is_for_this_executable()` Checks to see if the loaded install receipt is for this executable. Used to guard against cases where the running EXE is from a package manager, but a receipt from a shell installed-copy is present on the system. Returns an error if the receipt hasn’t been loaded yet. ``` -------------------------------- ### Generate Install Receipt Source: https://docs.rs/axoupdater/0.10.0/src/axoupdater/test/helpers.rs.html Generates an installation receipt JSON string. This function is used in tests to verify receipt generation with different parameters. ```rust let expected = r#"{"binaries":["cargo-dist"],"install_prefix":"/tmp/prefix","provider":{"source":"cargo-dist","version":"0.10.0-prerelease.1"},"source":{"app_name":"cargo-dist","name":"cargo-dist","owner":"axodotdev","release_type":"github"},"version":"0.5.0"}"#; let actual = install_receipt( "cargo-dist", "cargo-dist", "axodotdev", &["cargo-dist".to_owned()], "0.5.0", "/tmp/prefix", &ReleaseSourceType::GitHub, ); assert_eq!(expected, actual); ``` ```rust let expected = r#"{"binaries":["axolotlsay"],"install_prefix":"/tmp/prefix","provider":{"source":"cargo-dist","version":"0.10.0-prerelease.1"},"source":{"app_name":"axolotlsay","name":"cargodisttest","owner":"mistydemeo","release_type":"github"},"version":"0.5.0"}"#; let actual = install_receipt( "axolotlsay", "cargodisttest", "mistydemeo", &["axolotlsay".to_owned()], "0.5.0", "/tmp/prefix", &ReleaseSourceType::GitHub, ); assert_eq!(expected, actual); ``` ```rust let expected = r#"{"binaries":["bin1", "bin2"],"install_prefix":"/tmp/prefix","provider":{"source":"cargo-dist","version":"0.10.0-prerelease.1"},"source":{"app_name":"axolotlsay","name":"cargodisttest","owner":"mistydemeo","release_type":"github"},"version":"0.5.0"}"#; let actual = install_receipt( "axolotlsay", "cargodisttest", "mistydemeo", &["bin1".to_owned(), "bin2".to_owned()], "0.5.0", "/tmp/prefix", &ReleaseSourceType::GitHub, ); assert_eq!(expected, actual); ``` ```rust let expected = r#"{"binaries":["axolotlsay"],"install_prefix":"/tmp/prefix","provider":{"source":"cargo-dist","version":"0.10.0-prerelease.1"},"source":{"app_name":"axolotlsay","name":"cargodisttest","owner":"mistydemeo","release_type":"axodotdev"},"version":"0.5.0"}"#; let actual = install_receipt( "axolotlsay", "cargodisttest", "mistydemeo", &["axolotlsay".to_owned()], "0.5.0", "/tmp/prefix", &ReleaseSourceType::Axo, ); assert_eq!(expected, actual); ``` -------------------------------- ### Load Install Receipt with Specific App Name Source: https://docs.rs/axoupdater/0.10.0/src/axoupdater/receipt.rs.html Loads an install receipt for a specified app name, useful if the receipt might exist under different names, such as after an app rename. Populates `source`, `current_version`, `current_version_installed_by`, `install_prefix`, and `modify_path`. ```rust pub fn load_receipt_as(&mut self, app_name: &str) -> AxoupdateResult<&mut AxoUpdater> { let receipt = load_receipt_for(app_name)?; self.source = Some(receipt.source); self.current_version = Some(receipt.version.parse::()?); let provider = crate::Provider { source: receipt.provider.source, version: receipt.provider.version.parse::()?, }; self.current_version_installed_by = Some(provider); self.install_prefix = Some(receipt.install_prefix); self.modify_path = receipt.modify_path; Ok(self) } ``` -------------------------------- ### Struct Provider Source: https://docs.rs/axoupdater/0.10.0/axoupdater/struct.Provider.html Represents a tool used to produce an install receipt. ```APIDOC ## Struct Provider ### Description Tool used to produce this install receipt ### Fields - **source** (String) - The name of the tool used to create this receipt - **version** (Version) - The version of the above tool ``` -------------------------------- ### AxoUpdater Information API Source: https://docs.rs/axoupdater/0.10.0/axoupdater/struct.AxoUpdater.html API endpoints for retrieving information about the installation. ```APIDOC ## GET /axoupdater/info/install_prefix_root ### Description Retrieves the root of the installation prefix. It intelligently strips the trailing `/bin` component if present, addressing inconsistencies in older `cargo-dist` versions. ### Method GET ### Endpoint /axoupdater/info/install_prefix_root ### Response #### Success Response (200) - **install_prefix_root** (string) - The path to the root of the installation prefix. #### Response Example { "install_prefix_root": "/usr/local" } ``` -------------------------------- ### Normalize install prefix root Source: https://docs.rs/axoupdater/0.10.0/src/axoupdater/lib.rs.html Normalizes the install prefix root path by canonicalizing it and converting it to a Utf8PathBuf. Handles potential errors during path conversion. ```rust fn install_prefix_root_normalized(&self) -> AxoupdateResult { let raw_root = self.install_prefix_root()?; // The canonicalize path could fail if the path doesn't exist anymore; // catch that specific error here and return the original path. // (We want to leave the UTF8 conversion to the next step so we handle // those errors separately.) let canonicalized = if let Ok(path) = raw_root.canonicalize() { path } else { raw_root.into_std_path_buf() }; let normalized = Utf8PathBuf::from_path_buf(canonicalized) .map_err(|path| AxoupdateError::CaminoConversionFailed { path })?; Ok(normalized) } ``` -------------------------------- ### Check if Receipt Matches Executable Source: https://docs.rs/axoupdater/0.10.0/axoupdater/struct.AxoUpdater.html Verifies if the loaded install receipt corresponds to the current executable, preventing issues with package manager installations. ```rust pub fn check_receipt_is_for_this_executable(&self) -> AxoupdateResult ``` -------------------------------- ### perform_runtest Function Source: https://docs.rs/axoupdater/0.10.0/axoupdater/test/helpers/index.html Executes an installation and updater run test using the provided RuntestArgs. ```APIDOC ## perform_runtest ### Description Actually installs your app and runs its updater. For detailed information on the arguments, see `RuntestArgs`. ### Parameters #### Request Body - **RuntestArgs** (struct) - Required - The arguments used for `perform_runtest`. ``` -------------------------------- ### Generate and write install receipts Source: https://docs.rs/axoupdater/0.10.0/src/axoupdater/test/helpers.rs.html Functions to create a JSON receipt string and persist it to the filesystem. The write_receipt function handles directory creation and file writing. ```rust fn install_receipt( app_name: &str, package: &str, owner: &str, binaries: &[String], version: &str, prefix: &str, release_type: &ReleaseSourceType, ) -> String { let binaries = binaries .iter() .map(|name| format!(r#""{name}""#)) .collect::>() .join(", "); RECEIPT_TEMPLATE .replace("BINARIES", &binaries) .replace("PACKAGE", package) .replace("OWNER", owner) .replace("APP_NAME", app_name) .replace("INSTALL_PREFIX", &prefix.replace('\\', "\\\\")) .replace("VERSION", version) .replace("RELEASE_TYPE", &release_type.to_string()) } ``` ```rust fn write_receipt( app_name: &str, package: &str, owner: &str, binaries: &[String], version: &str, prefix: &Path, config_path: &PathBuf, release_type: &ReleaseSourceType, ) -> std::io::Result { let contents = install_receipt( app_name, package, owner, binaries, version, &prefix.to_string_lossy(), release_type, ); let receipt_name = config_path.join(format!("{package}-receipt.json")); std::fs::create_dir_all(config_path)?; std::fs::write(&receipt_name, contents)?; Ok(receipt_name) } ``` -------------------------------- ### AxoUpdater::load_receipt Source: https://docs.rs/axoupdater/0.10.0/src/axoupdater/receipt.rs.html Attempts to load an install receipt to prepare for an update. If a receipt is present and valid, it populates the `source` and `current_version` fields of the AxoUpdater instance. This method is suitable for installers created by cargo-dist since version 0.9.0. ```APIDOC ## POST /api/axoupdater/load_receipt ### Description Attempts to load an install receipt for the current application to prepare for an update. If a receipt is present and valid, it populates the `source` and `current_version` fields of the AxoUpdater instance. This method is suitable for installers created by cargo-dist since version 0.9.0. ### Method POST ### Endpoint /api/axoupdater/load_receipt ### Parameters #### Query Parameters - **appName** (string) - Optional - The name of the application to load the receipt for. If not provided, the auto-detected name is used. ### Request Example ```json { "appName": "my_app" } ``` ### Response #### Success Response (200) - **AxoUpdater** (object) - The updated AxoUpdater instance with receipt information. #### Response Example ```json { "source": { "kind": "github", "repo": "owner/repo" }, "current_version": "1.2.3", "current_version_installed_by": { "source": "cargo-dist", "version": "0.9.0" }, "install_prefix": "/usr/local/bin/my_app", "modify_path": true } ``` ``` -------------------------------- ### perform_runtest Function Source: https://docs.rs/axoupdater/0.10.0/axoupdater/test/helpers/fn.perform_runtest.html Installs and runs the application's updater. It's recommended to use this function only within CI builds due to its file system interactions. ```APIDOC ## perform_runtest ### Description Actually installs your app and runs its updater. For detailed information on the arguments, see `RuntestArgs`. This function performs several assertions of its own, then returns the path to which the binary was expected to have been installed in order to allow the caller to perform additional tests or assertions. Because it writes to real files outside a temporary directory, it’s highly recommended that this only becalled within CI builds. Note that, at the moment, this always attempts to install to CARGO_HOME (~/.cargo/bin). ### Method (Not specified, likely a function call within Rust code) ### Endpoint (Not applicable, this is a Rust function) ### Parameters #### Path Parameters (None) #### Query Parameters (None) #### Request Body - **runtest_args** (RuntestArgs) - Required - Arguments for running the test, including details for the updater. ### Request Example (Not applicable, this is a Rust function call) ### Response #### Success Response (200) - **PathBuf** - The path to which the binary was expected to have been installed. #### Response Example (Not applicable, this is a Rust function call) ``` -------------------------------- ### GET /repos/{owner}/{name}/releases/tags/{tag} Source: https://docs.rs/axoupdater/0.10.0/src/axoupdater/release/github.rs.html Fetches a specific GitHub release by its tag name. ```APIDOC ## GET /repos/{owner}/{name}/releases/tags/{tag} ### Description Retrieves metadata for a specific release identified by a tag. ### Method GET ### Endpoint {api}/repos/{owner}/{name}/releases/tags/{tag} ### Parameters #### Path Parameters - **owner** (string) - Required - The owner of the repository - **name** (string) - Required - The repository name - **tag** (string) - Required - The specific tag to fetch ### Response #### Success Response (200) - **tag_name** (string) - The tag this release represents - **name** (string) - The name of the release - **url** (string) - The URL at which this release lists - **assets** (array) - List of assets associated with the release - **prerelease** (boolean) - Whether or not this release is a prerelease ``` -------------------------------- ### Get Install Prefix Root Source: https://docs.rs/axoupdater/0.10.0/src/axoupdater/lib.rs.html Retrieves the root directory of the installation prefix, removing a trailing `/bin` component if present. This function includes a workaround for a bug in older versions of `cargo-dist`. ```rust pub fn install_prefix_root(&self) -> AxoupdateResult { let Some(install_prefix) = &self.install_prefix else { return Err(AxoupdateError::NotConfigured { missing_field: "install_prefix".to_owned(), }); }; let mut install_root = install_prefix.to_owned(); if let Some(provider) = &self.current_version_installed_by { ``` -------------------------------- ### Disable All Installer Output Source: https://docs.rs/axoupdater/0.10.0/src/axoupdater/lib.rs.html Use `disable_installer_output` to disable printing of both standard output and standard error for the underlying installer. This is useful for suppressing all installer logs. ```rust pub fn disable_installer_output(&mut self) -> &mut AxoUpdater { self.print_installer_stdout = false; self.print_installer_stderr = false; self } ``` -------------------------------- ### AxoUpdater::new() Source: https://docs.rs/axoupdater/0.10.0/src/axoupdater/lib.rs.html Initializes a new AxoUpdater instance with default settings. Requires further configuration before use. ```APIDOC ## AxoUpdater::new() ### Description Creates a new, empty AxoUpdater struct. This struct lacks information necessary to perform the update, so at least the `name` and `source` fields will need to be filled in before the update can run. ### Method `new()` ### Returns - `AxoUpdater` - A new instance of the AxoUpdater struct with default values. ``` -------------------------------- ### Disable All Installer Output Source: https://docs.rs/axoupdater/0.10.0/axoupdater/struct.AxoUpdater.html Disables all output streams (stdout and stderr) for the underlying installer. ```rust pub fn disable_installer_output(&mut self) -> &mut AxoUpdater ``` -------------------------------- ### Configuration Methods Source: https://docs.rs/axoupdater/0.10.0/axoupdater/struct.AxoUpdater.html Methods for configuring the AxoUpdater instance. ```APIDOC ## Configuration Methods ### `set_github_token(token: &str)` Configures AxoUpdater to use a specific GitHub token when performing requests. This is useful in circumstances where the user may encounter rate limits, and is necessary to access private repositories. This must have the `repo` scope enabled. ### `set_axo_token(token: &str)` Configures AxoUpdater to use a specific Axo Releases token when performing requests. ### `set_client(client: Client)` Configures the `reqwest::Client` to use for network requests. ### `set_release_source(source: ReleaseSource)` Explicitly configures the release source as an alternative to reading it from the install receipt. This can be useful for tasks which want to query the new version without actually performing an upgrade. ### `set_current_version(version: Version)` Explicitly specifies the current version. ### `set_name(app_name: &str)` Changes this updater’s name to `app_name`, regardless of what it was initialized as and regardless of what was read from the receipt. ### `configure_installer_path(path: impl Into)` Configures AxoUpdater to use a specific installer for the new release instead of downloading it from the release source. ### `use_release_installer()` Configures AxoUpdater to use the installer from the new release. This is the default setting. ``` -------------------------------- ### Disable Installer Stderr Source: https://docs.rs/axoupdater/0.10.0/axoupdater/struct.AxoUpdater.html Disables the display of the underlying installer's standard error. ```rust pub fn disable_installer_stderr(&mut self) -> &mut AxoUpdater ``` -------------------------------- ### Disable Installer Stdout Source: https://docs.rs/axoupdater/0.10.0/axoupdater/struct.AxoUpdater.html Disables the display of the underlying installer's standard output. ```rust pub fn disable_installer_stdout(&mut self) -> &mut AxoUpdater ``` -------------------------------- ### Create Version with Default Metadata Source: https://docs.rs/axoupdater/0.10.0/axoupdater/struct.Version.html Constructs a Version instance with specified major, minor, and patch numbers, initializing pre-release and build metadata to empty. ```rust Version { major, minor, patch, pre: Prerelease::EMPTY, build: BuildMetadata::EMPTY, } ``` -------------------------------- ### Sort Versions by Precedence and Build Metadata Source: https://docs.rs/axoupdater/0.10.0/axoupdater/struct.Version.html Demonstrates sorting an array of Version objects first by precedence (major, minor, patch, pre-release) and then by build metadata for a total ordering. ```rust use semver::Version; let mut versions = [ "1.20.0+c144a98".parse::().unwrap(), "1.20.0".parse().unwrap(), "1.0.0".parse().unwrap(), "1.0.0-alpha".parse().unwrap(), "1.20.0+bc17664".parse().unwrap(), ]; // This is a stable sort, so it preserves the relative order of equal // elements. The three 1.20.0 versions differ only in build metadata so // they are not reordered relative to one another. versions.sort_by(Version::cmp_precedence); assert_eq!(versions, [ "1.0.0-alpha".parse().unwrap(), "1.0.0".parse().unwrap(), "1.20.0+c144a98".parse().unwrap(), "1.20.0".parse().unwrap(), "1.20.0+bc17664".parse().unwrap(), ]); // Totally order the versions, including comparing the build metadata. versions.sort(); assert_eq!(versions, [ "1.0.0-alpha".parse().unwrap(), "1.0.0".parse().unwrap(), "1.20.0".parse().unwrap(), "1.20.0+bc17664".parse().unwrap(), "1.20.0+c144a98".parse().unwrap(), ]); ``` -------------------------------- ### Disable Installer Stderr Source: https://docs.rs/axoupdater/0.10.0/src/axoupdater/lib.rs.html Use `disable_installer_stderr` to prevent the standard error of the underlying installer process from being printed. This can be useful for cleaner logs. ```rust pub fn disable_installer_stderr(&mut self) -> &mut AxoUpdater { self.print_installer_stderr = false; self } ``` -------------------------------- ### AxoUpdater Initialization Source: https://docs.rs/axoupdater/0.10.0/axoupdater/struct.AxoUpdater.html Methods for creating new instances of AxoUpdater. ```APIDOC ## AxoUpdater Initialization ### `new()` Creates a new, empty AxoUpdater struct. This struct lacks information necessary to perform the update, so at least the name and source fields will need to be filled in before the update can run. ### `new_for(app_name: &str)` Creates a new AxoUpdater struct with an explicitly-specified name. ### `new_for_updater_executable()` Creates a new AxoUpdater struct by attempting to autodetect the name of the current executable. This is only meant to be used by standalone updaters, not when this crate is used as a library in another program. ``` -------------------------------- ### Configure Reqwest Client Source: https://docs.rs/axoupdater/0.10.0/src/axoupdater/lib.rs.html Use `set_client` to provide a custom `reqwest::Client` for network requests. This allows for advanced client configurations like custom timeouts or proxies. ```rust pub fn set_client(&mut self, client: reqwest::Client) -> &mut AxoUpdater { self.client = client; self } ``` -------------------------------- ### AxoUpdater::check_receipt_is_for_this_executable Source: https://docs.rs/axoupdater/0.10.0/src/axoupdater/receipt.rs.html Checks if the currently loaded install receipt belongs to the executable that is currently running. This prevents issues where a receipt from a shell-installed copy might be present alongside an executable installed via a package manager. ```APIDOC ## GET /api/axoupdater/check_receipt_is_for_this_executable ### Description Verifies if the install receipt that has been loaded into the AxoUpdater instance corresponds to the currently executing executable. This is a safety check to ensure that updates are applied to the correct installation, especially in environments where multiple installation methods might coexist. ### Method GET ### Endpoint /api/axoupdater/check_receipt_is_for_this_executable ### Parameters None ### Response #### Success Response (200) - **is_for_this_executable** (boolean) - `true` if the receipt matches the current executable, `false` otherwise. #### Response Example ```json { "is_for_this_executable": true } ``` ``` -------------------------------- ### Retrieve release list Source: https://docs.rs/axoupdater/0.10.0/src/axoupdater/release/mod.rs.html Fetches a list of all releases available for the specified application and source type. ```rust pub(crate) async fn get_release_list( client: &reqwest::Client, name: &str, owner: &str, app_name: &str, release_type: &ReleaseSourceType, tokens: &AuthorizationTokens, ) -> AxoupdateResult> { let releases = match release_type { #[cfg(feature = "github_releases")] ReleaseSourceType::GitHub => { github::get_github_releases(name, owner, app_name, client, &tokens.github).await? } #[cfg(not(feature = "github_releases"))] ReleaseSourceType::GitHub => { return Err(AxoupdateError::BackendDisabled { backend: "github".to_owned(), }) } ReleaseSourceType::Axo => { return Err(AxoupdateError::BackendDisabled { backend: "axodotdev".to_owned(), }) } }; Ok(releases) } ``` -------------------------------- ### Fetch Latest GitHub Release Source: https://docs.rs/axoupdater/0.10.0/src/axoupdater/release/github.rs.html Retrieves the latest release for a given repository and application. It checks if the release has an installer asset and returns an `AxoupdateResult>`. If no stable releases are found or the latest release lacks an installer, it returns `Ok(None)`. ```rust pub(crate) async fn get_latest_github_release( name: &str, owner: &str, app_name: &str, client: &reqwest::Client, token: &Option, ) -> AxoupdateResult> { let api: String = github_api(app_name)?; let mut request = client .get(format!("{api}/repos/{owner}/{name}/releases/latest")) .header(ACCEPT, "application/json") .header( USER_AGENT, format!("axoupdate/{}", env!("CARGO_PKG_VERSION")), ); if let Some(token) = token { request = request.bearer_auth(token); } let gh_release: GithubRelease = request .send() .await?; .error_for_status() .map_err(|_| AxoupdateError::NoStableReleases { app_name: app_name.to_owned(), })?; .json() .await?; if !gh_release .assets .iter() .any(|asset| asset.name.starts_with(&format!("{app_name}-installer"))) { return Ok(None); } match Release::try_from_github(app_name, gh_release) { Ok(release) => Ok(Some(release)), Err(e) => Err(e), } } ``` -------------------------------- ### Configuration Methods Source: https://docs.rs/axoupdater/0.10.0/src/axoupdater/lib.rs.html Methods to configure the behavior of the updater, including network clients, release sources, and output settings. ```APIDOC ## Configuration Methods ### Description Methods to modify the internal state of the AxoUpdater instance. ### Methods - `set_client(client: reqwest::Client) -> &mut AxoUpdater`: Configures the network client. - `set_release_source(source: ReleaseSource) -> &mut AxoUpdater`: Sets the release source explicitly. - `set_current_version(version: Version) -> AxoupdateResult<&mut AxoUpdater>`: Sets the current version. - `set_name(app_name: &str) -> &mut AxoUpdater`: Updates the application name. - `enable_installer_stdout() / disable_installer_stdout()`: Toggles stdout for the installer. - `enable_installer_stderr() / disable_installer_stderr()`: Toggles stderr for the installer. - `enable_installer_output() / disable_installer_output()`: Toggles all installer output. ``` -------------------------------- ### Function app_name_to_env_var Source: https://docs.rs/axoupdater/0.10.0/axoupdater/fn.app_name_to_env_var.html Converts an application name into a string suitable for environment variables. ```APIDOC ## Function app_name_to_env_var ### Description Returns an environment variable-compatible version of the app name. ### Signature ```rust pub fn app_name_to_env_var(app_name: &str) -> String ``` ### Parameters #### Path Parameters - **app_name** (str) - Required - The name of the application. ### Returns - **String** - An environment variable-compatible string. ``` -------------------------------- ### Query New Version Source: https://docs.rs/axoupdater/0.10.0/src/axoupdater/lib.rs.html Fetches the latest release information and returns a reference to the version of the new release if available. This method requires the release information to be fetched first. ```rust /// Queries for new releases and then returns the detected version. pub async fn query_new_version(&mut self) -> AxoupdateResult> { self.fetch_release().await?; if let Some(release) = &self.requested_release { Ok(Some(&release.version)) } } ``` -------------------------------- ### Execute GitHub API request Source: https://docs.rs/axoupdater/0.10.0/src/axoupdater/release/github.rs.html Performs an authenticated GET request to the GitHub API with required headers. ```rust pub(crate) async fn get_releases( client: &reqwest::Client, url: &str, token: &Option, ) -> AxoupdateResult { let mut request = client .get(url) .header(ACCEPT, "application/json") .header( USER_AGENT, format!("axoupdate/{}", env!("CARGO_PKG_VERSION")), ) .header("X-GitHub-Api-Version", "2022-11-28"); if let Some(token) = token { request = request.bearer_auth(token); } Ok(request.send().await?.error_for_status()?) } ``` -------------------------------- ### unwrap_err() - Get Err value Source: https://docs.rs/axoupdater/0.10.0/axoupdater/errors/type.AxoupdateResult.html Returns the contained `Err` value, consuming the `self` value. Panics if the `Result` is an `Ok`. ```APIDOC ## PUT /api/users/{userId} ### Description Updates an existing user's information. Requires the user ID in the path and the updated fields in the request body. ### Method PUT ### Endpoint /api/users/{userId} ### Parameters #### Path Parameters - **userId** (string) - Required - The ID of the user to update. #### Request Body - **username** (string) - Optional - The new username. - **email** (string) - Optional - The new email address. ### Response #### Success Response (200) - **userId** (string) - The unique identifier for the user. - **username** (string) - The updated username. - **email** (string) - The updated email address. #### Response Example ```json { "userId": "123e4567-e89b-12d3-a456-426614174000", "username": "johndoe_updated", "email": "john.doe.updated@example.com" } ``` ```