Skip to content

main

girsh

elevate_privileges()

Elevate the privileges of the current process to root using sudo. If the current process is not running as the root user, this function will re-run the script with elevated privileges by invoking sudo. Raises: OSError: If there is an error executing the sudo command.

main()

The main entry point for the application.

This function processes command-line arguments, manages configurations, and orchestrates the execution of various operations such as editing configurations, cleaning the downloads folder, showing installed items, uninstalling repositories, and processing repositories for installation.

Returns:

Name Type Description
int int

Exit code indicating the result of the operation. - 0: Success - 1: Uninstall operation failed - 3: No repositories installed - Other non-zero values indicate errors or specific conditions

set_logger_level(verbosity)

Set the logger level based on the verbosity argument.

Parameters:

Name Type Description Default
verbosity int

The verbosity level (0-3).

required

show_summary(install_summary, uninstall_summary)

Display a summary of the repository processing results.

Parameters:

Name Type Description Default
install_summary dict[RepoResult, int]

A dictionary where the keys are RepoResult instances and the values are counts of occurrences.

required
uninstall_summary dict[RepoResult, int]

A dictionary where the keys are RepoResult instances and the values are counts of occurrences.

required

core

core.config

edit_config(config_path)

Open the specified config file in the user's default terminal editor.

Parameters:

Name Type Description Default
config_path Path

Path to the configuration file to edit.

required

Returns:

Name Type Description
int int

error code

get_arguments()

Parse the command line arguments

Returns:

Type Description
Namespace

argparse.Namespace: Parsed command line arguments

load_yaml_config(file_path)

Load and parse the YAML configuration file and update the general and repositories config.

Parameters:

Name Type Description Default
file_path str

Path to the YAML configuration file.

required

Returns:

Type Description
tuple[General, dict[str, Repository]]

tuple[General, dict[str, Repository]]: A tuple containing the updated General instance and a dictionary mapping repository names to Repository instances.

update_general_config(general_config, data)

Update a General dataclass instance with values from a dictionary.

This function looks for a 'general' key in the provided data and updates the configuration fields if they exist, triggering any type conversions defined in setattr.

Parameters:

Name Type Description Default
general_config General

The current configuration instance.

required
data dict

Dictionary containing configuration data, e.g., from a YAML file.

required

Returns:

Name Type Description
General General

The updated configuration instance.

update_repositories_config(repo_config, data, default_pattern)

Update repository configurations using YAML data.

This function extracts repository configurations from the "repositories" key in the provided YAML data. For each repository, it creates a new Repository instance (or a default one if the configuration is None) and ensures that a default package pattern is set if missing.

Parameters:

Name Type Description Default
repo_config dict[str, Repository]

Existing repository configuration mapping.

required
data dict

Loaded configuration data from a YAML file.

required
default_pattern str

Default package pattern to use when not specified.

required

Returns:

Type Description
dict[str, Repository]

dict[str, Repository]: The updated repository configuration mapping.

core.files

clean_downloads_folder(download_dir)

Remove the downloads folder and exit.

Parameters:

Name Type Description Default
download_dir Path

The download folder path

required

Returns:

Name Type Description
int int

error code

copy_to_bin(binary_path, bin_base_folder, binary_name=None)

Copy the binary file to the system or user binary directory.

Parameters:

Name Type Description Default
binary_path Path

Path to the binary file to be copied.

required
bin_base_folder Path

The binaries base folder path.

required
binary_name str | None

Optional binary name, defaults to the name from binary path

None

Returns:

Name Type Description
Path Path

Path to installed binary file

download_github_release(url, package_pattern, output_dir, release_info=None, download_url=None)

Download a matching release asset from a GitHub repository.

Parameters:

Name Type Description Default
url str

GitHub API release URL.

required
package_pattern str

Regex pattern to match the desired asset.

required
output_dir Path

Directory to save the downloaded asset.

required
release_info dict[Any, Any] | None

Optionally provide release JSON to avoid duplicate API calls.

None
download_url str | None

Optional download URL template

None

Returns:

Type Description
tuple[Path, str] | None

tuple[Path, str] | None: Tuple of path to the downloaded file and the release tag, or None if no match.

download_package(download_url, output_dir, filename=None)

Downloads a file from the given URL and saves it to the specified output directory.

Parameters:

Name Type Description Default
download_url str

The URL to download the file from.

required
output_dir Path

The directory where the downloaded file will be saved.

required
filename str | None

The name to save the file as. If not provided, the filename will be extracted from the Content-Disposition header or the URL.

None

Returns:

Type Description
Path | None

Path | None: The path to the downloaded file, or None if the download failed.

extract_archive(file_path, extract_to, package_name)

Extract the archive based on its extension and return the common top-level folder name if one is detected. For pure bz2 files, extraction is done directly.

Parameters:

Name Type Description Default
file_path Path

The path to the archive.

required
extract_to Path

The base extraction directory.

required
package_name str

The package folder name used when a common folder is not found.

required

Returns:

Type Description
str | None

str | None: The common top-level folder name if detected; otherwise, None.

extract_bz2_archive(file_path, extract_to, package_name)

Extract a pure bz2 compressed file (non-tar archive) into a subfolder.

The function decompresses a .bz2 file and writes the output into a folder named after package_name within extract_to.

Parameters:

Name Type Description Default
file_path Path

The path to the .bz2 file.

required
extract_to Path

The base directory where the file should be extracted.

required
package_name str

The name for the package folder.

required

extract_package(file_path, extract_to, package_name)

Extract a compressed package file into a controlled folder structure. This function now delegates the extraction process to extract_archive to reduce complexity.

Parameters:

Name Type Description Default
file_path Path

The path to the compressed package file.

required
extract_to Path

The base directory where the package should be extracted.

required
package_name str

The name for the package folder.

required

Returns:

Type Description
None

None

extract_tar_archive(archive, base)

Extract members from a tar archive into the given base directory, skipping unsafe paths.

Parameters:

Name Type Description Default
archive TarFile

The tar archive to extract.

required
base Path

The base directory where files will be extracted.

required

Returns:

Type Description
None

None

extract_zip_archive(archive, base)

Extract members from a zip archive into the given base directory, skipping unsafe paths.

Parameters:

Name Type Description Default
archive ZipFile

The zip archive to extract.

required
base Path

The base directory where files will be extracted.

required

Returns:

Type Description
None

None

find_binary(extract_dir, filter_pattern)

Search for the binary in the extracted directory and rename it if necessary.

Parameters:

Name Type Description Default
extract_dir Path

The directory where the package was extracted.

required
filter_pattern str | None

A pattern to filter and match the binary file.

required

Returns:

Type Description
Path | None

Path | None: The path to the binary if found, or None if no binary is found.

get_common_prefix(names)

Determine the common top-level folder from a list of archive member names.

Parameters:

Name Type Description Default
names list[str]

List of member paths (as strings) from the archive.

required

Returns:

Type Description
str | None

str | None: The common top-level folder if all names share one; otherwise, None.

get_filename_from_cd(content_disposition)

Extract filename from Content-Disposition header.

Parameters:

Name Type Description Default
content_disposition str

The Content-Disposition header value.

required

Returns:

Name Type Description
str str | None

The filename if found, otherwise None.

is_safe_path(base, target)

Check if the resolved target path is within the resolved base directory to prevent path traversal.

Parameters:

Name Type Description Default
base Path

The intended base directory.

required
target Path

The target path to be validated.

required

Returns:

Name Type Description
bool bool

True if the target is within the base directory; False otherwise.

move_to_packages(package_source, package_base_folder, bin_base_folder, binary_path, binary_name=None)

Move the extracted package to the packages base folder and symlink the binary file to the system or user binary directory.

Parameters:

Name Type Description Default
package_source Path

Path to the extracted package

required
package_base_folder Path

The base package folder path.

required
bin_base_folder Path

The binaries base folder path.

required
binary_path Path

Path to the binary file to be linked.

required
binary_name str | None

Optional symlink name, defaults to the name from binary path

None

Returns:

Name Type Description
Path Path

Path to installed binary file

core.installed

get_comment(repo, repositories)

Get the comment from the repository config. If the repository is not found, return a default message.

Args repo (str): Name of the repository

Returns:

Name Type Description
str str

Comment from repository config

load_installed(installed_file)

Load the version installed from a YAML file.

Parameters:

Name Type Description Default
installed_file Path

Path to the installed file.

required

Returns:

Type Description
dict[str, dict]

dict[str, str]: Dict of installed software details.

save_installed(installed_file, data)

Save the version installed to a YAML file.

Parameters:

Name Type Description Default
installed_file Path

Path to the installed file.

required
data dict[Any, Any]

Version installed data to save.

required

Returns:

Name Type Description
int int

error code

show_installed(data, repositories)

Display installed binaries in a table format with auto-fitted column widths.

Parameters:

Name Type Description Default
data dict[Any, Any]

Dictionary containing installed binaries with metadata.

required

Returns:

Name Type Description
int int

Error code (0 for success).

core.repos

check_repo_release(repo, target_version, current_version, reinstall)

Check the release information of a repository and determine the appropriate action.

This function fetches release information for a given repository from GitHub, checks if a new version is available, and determines whether to skip, reinstall, or proceed with the release.

Parameters:

Name Type Description Default
repo str

The name of the repository to check.

required
target_version str | None

The target version to check for. If None, the latest version is used.

required
current_version str | None

The currently installed version. If None, it assumes no version is installed.

required
reinstall bool

Whether to force reinstallation even if the current version matches the target version.

required

Returns:

Type Description
tuple[RepoResult, dict[Any, Any]]

RepoResult | dict[Any, Any]: - A dictionary containing release information if a new version is available or reinstall is forced. - A RepoResult enum value indicating the action taken (e.g., skipped or install_failed).

fetch_release_info(repo, version, reinstall)

Fetch the release information for a given repository from GitHub.

Parameters:

Name Type Description Default
repo str

The repository identifier, in the format 'owner/repo'.

required
version str | None

The repository version

required
reinstall bool

A flag to force reinstall even if no new version is detected.

required

Returns:

Type Description
dict[Any, Any] | None

dict | None: The release information in JSON format, or None if an error occurs.

is_new_version(installed_tag, tag, reinstall)

Determine if the current version is different from the installed version or if a reinstall is forced.

Parameters:

Name Type Description Default
installed_tag str | None

The installed version of the repository.

required
tag str

The new version's tag name from the release info.

required
reinstall bool

A flag to force reinstall even if no new version is detected.

required

Returns:

Name Type Description
RepoResult RepoResult

Target action based on version info and reinstall flag

process_repositories(repositories, general, installed, reinstall, dry_run=False)

Processes a list of repositories, installs or updates them if necessary, and saves the updated installation data.

Parameters:

Name Type Description Default
repositories Mapping[str, RepositoryConfig]

A dictionary of repository names and their corresponding Repository objects.

required
general GeneralConfig

General configuration settings.

required
installed dict[str, dict]

A dictionary containing the current installation data of the repositories.

required
reinstall list[str]

List of repositories to reinstall.

required
dry_run bool

A flag to perform a dry run (no changes are actually made). Defaults to False.

False

Returns:

Type Description
dict[str, dict]

dict[str, dict] | None: Updated install data or None

dict[RepoResult, int]

dict[RepoResult, int]: Summary of the installation process

Logs: - Warnings and errors related to repository processing. - A summary of the installation or update process, including the number of repositories processed for each result type.

process_repository(repo, repo_config, general, installed_tag, reinstall=False, dry_run=False)

Process a single repository by checking for updates, downloading the latest release, extracting, optionally renaming the binary, and installing it. Updates the installed with the latest version information if a new version is installed.

Parameters:

Name Type Description Default
repo str

The repository identifier, in the format 'owner/repo'.

required
repo_config RepositoryConfig

The repository configuration, containing version info and other settings.

required
general GeneralConfig

General configuration settings.

required
installed_tag str | None

Tag of installed version.

required
reinstall bool

A flag to force reinstall even if the current version is up-to-date (default: False).

False
dry_run bool

A flag to simulate the process without installing the binary (default: False).

False

Returns:

Type Description
tuple[RepoResult, dict[str, str]]

tuple[RepoResult, dict[str, str]]: Result of repo installation, Repo installation data

remove_binary(repo, info, dry_run)

Remove the binary file associated with a repository.

Parameters:

Name Type Description Default
repo str

Repository name.

required
info dict[Any, Any]

Installation info containing 'path' and 'binary'.

required
dry_run bool

Simulate removal if True.

required

remove_package(repo, info, dry_run)

Remove the package directory if it exists.

Parameters:

Name Type Description Default
repo str

Repository name.

required
info dict[Any, Any]

Installation info that may contain 'package_path'.

required
dry_run bool

Simulate removal if True.

required

uninstall(repositories, installed, dry_run=False)

Uninstall binaries which are not present in the repositories config anymore. If repositories is empty, all binaries will be uninstalled. This function will also remove the package folder if it exists.

Parameters:

Name Type Description Default
repositories list[str]

A list of repository names.

required
installed dict[Any, Any]

installed tracking installed versions and binaries.

required
dry_run bool

A flag to simulate the process without removing the binary (default: False).

False

uninstall_binary(repo, install_data, dry_run)

Uninstalls a binary file associated with a given repository.

Parameters:

Name Type Description Default
repo str

The name of the repository associated with the binary.

required
install_data dict

A dictionary containing install information about the binary.

required
dry_run bool

If True, simulates the uninstallation process without making any changes.

required

Returns:

Name Type Description
RepoResult RepoResult

An enumeration indicating the result of the uninstallation process. Possible values: - RepoResult.dry_run_uninstall: Indicates a successful dry-run. - RepoResult.uninstalled: Indicates the binary was successfully uninstalled. - RepoResult.uninstall_failed: Indicates the uninstallation failed due to permission issues.