aedev.commands
software development operation commands helpers
Hint
this module is designed to provide a comprehensive set of constants, types, and helper functions for executing and managing DevOps on your Python projects, like e.g. the Git and Pip command-line interfaces and Python virtual environments.
fundamental shell execution helpers
the helper functions sh_exit_if_git_err() provides fundamental Git command tracing for in-depth logging/debugging.
the logging of executed command lines and their console output is highly useful for debugging and protocolling purposes. this portion provides the following helper functions to implement logging for external commands. logging gets automatically enabled, if the corresponding log file exists.
sh_log(): writes a single command execution log entry.sh_logs(): determines the file paths of the currently existing/enabled log files.SHELL_LOG_FILE_NAME_SUFFIX: the default filename suffix for shell command log files.
Hint
this feature is implemented in sh_exit_if_git_err() for all the git command execution helpers (git_*())
of this portion. to enable logging of all executed git commands simply create a log file with the name
git_sh.log, situated in the current working directory and/or in the users home directory (~).
git command helpers
this portion is providing helper functions for lots of git commands, most of them allow to activate git trace for debugging or intensive testing.
git commands will be executed in repo root folder of a project. the current working directory will be changed accordingly before a git command get executed (and restored to the old working directory after the execution).
to support GIT HOOKS that execute Python code, the Python virtual environment of a project will be activated before the git command get executed, and restored to the old value after the git command has finished.
extensive debugging using the GIT TRACE feature of the git commands
will be activating if your app based on ConsoleApp got executed with
the –debug_level/-D option specified.
bytes_file_diff(): returns the differences between a byte buffer and a file, using the git diff command.check_commit_msg_file(): checks for the existence of a Git commit message file.git_add(): executes the git add command to stage changes.git_any(): executes any generic Git command.git_branches(): determines branch names in a Git repository.git_branch_files(): finds added, changed, or deleted files on a specified branch.git_branch_is_dirty(): checks if a Git branch has uncommitted or unstaged changes.git_checkout(): executes the git checkout command to switch branches.git_clean(): executes the git clean command to remove untracked files.git_commit(): executes the git commit command.git_commit_files_count(): determines the number of changed files in the last commit.git_config(): executes the git config command.git_conflicts(): lists any merge conflicts in the repository.git_describe(): executes the git describe command.git_fetch(): executes the git fetch command.git_init_branch(): initializes a new Git branch.git_is_clean(): checks if the repository has a clean working directory (no untracked or uncommitted files).git_log_last_commit_date(): determines the date of the last commit.git_pull(): executes the git pull command.git_push(): executes the git push command.git_remotes(): retrieves the remote URLs of the repository.git_repo_is_init(): checks if a project directory contains a Git repository.git_tags(): lists the Git tags.git_uncommitted(): lists all uncommitted files.git_user_email(): retrieves the Git user’s email.git_user_name(): retrieves the Git user’s name.git_version_tag(): determines the current version tag of the repository.
git command constants and types
EXEC_GIT_ERR_PREFIX: the prefix used to mark Git execution errors.GIT_CLONE_CACHE_CONTEXT: the temporary folder context identifier used for Git clone downloads.GIT_FOLDER_NAME: the default name of the Git-internal subfolder.GIT_REMOTE_ORIGIN: the default name for the origin remote.GIT_REMOTE_UPSTREAM: the default name for the upstream remote.GIT_RELEASE_REF_PREFIX: the default prefix, used for release branches.GIT_VERSION_TAG_PREFIX: the default prefix, used for version tags.GitRemotesType: the type hint for a dictionary of Git remotes.
pip command helpers
this section groups the helpers for executing Pip commands within a project’s virtual environment.
pip_freeze(): executes pip freeze to list all installed packages.pip_install(): executes pip install to install packages.pip_show(): executes pip show to get detailed information about a package.pip_versions(): determines the available versions of a package from PyPI.
virtual environment helpers
these helper functions are provided to assist with the management of Python virtual environments.
activate_venv(): ensures that a virtual environment is activated if it’s different from the current one.active_venv(): determines the name of the currently active virtual environment.in_prj_dir_venv(): a context manager that temporarily changes the working directory and activates the project’s virtual environment.venv_bin_path(): determines the bin/scripts path of a virtual environment.venv_project_path(): finds the project root path associated with a virtual environment.
the following example installs the required packages of a project into its local virtual environment by
using the in_prj_dir_venv() context manager together with the shell execution function sh_exec()
and the constant PIP_INSTALL_CMD:
with in_prj_dir_venv(project_root_path):
sh_err = sh_exec(PIP_INSTALL_CMD + "-r requirements.txt")
Module Attributes
used by sh_exit_if_exec_err to mark error in 1st output line |
|
temp directory context for git clone downloads |
|
git subfolder in project path root of local repository |
|
git origin remote name of (fork) repository in user account |
|
git upstream remote name of original/forked repository |
|
git repository release branch name prefix |
|
git repository version tag prefix |
|
caption/field-name of the console output of the pip show command. |
|
default file name (suffix) of the shell log file |
|
git remote urls dict with keys like 'origin'/'upstream' |
Functions
|
ensure to activate a virtual environment if it is different to the current one (the one on Python/app start). |
determine the virtual environment that is currently active. |
|
|
return the differences between the content of a file against the specified file content buffer. |
|
check if the commit message file exists and if yes return the path of it. |
|
determine the project path of a project package installed as editable. |
|
execute the git add command. |
|
execute any git command. |
|
find all added/changed/deleted/renamed/unstaged worktree files that are not merged into the main branch. |
|
return the remote names where the specified branch name exists. |
|
determine all branch names with the git branch command. |
|
checkout git branch. |
|
clone a git remote repository from a repository hoster onto your local machine. |
|
execute the command 'git commit' for the specified project. |
|
determine the currently checked-out branch of the specified git repository. |
|
determine the uncommited/unstaged changes of a git project- |
|
fetch repository from remotes. |
|
check if a git repository already exists in the specified project root folder, and create it if not. |
|
merge current worktree with the specified [remote/]branch (exit app if an error occurred). |
|
push the repo of the specified project with the specified branch/tags to the specified remote. |
|
check if branch/tag/ref is in the specified branch. |
|
determine the domain and the repository owner group-/user-name from the git remote configuration (.git/config). |
|
get mapping of hte project repository remotes. |
|
renew the origin remote and optionally (if repo is forked) also the upstream remote. |
|
get the status of the project repository. |
|
add a new tag onto the project in the specified project root path |
|
determine a list of matching tags of a local or remote git repository. |
|
return the remote names where the specified tag name exists. |
|
determine the changed/untracked/uncommitted files of a git repository/project. |
|
ensure the current working directory and the specified or .python-version-configured Python Virtual Environment. |
|
ensure the virtual environment gets activated within the context. |
|
determine the owner and project name path from the specified git remote repository url. |
|
execute git command with optional git trace output, returning the stdout lines cleaned from any trace messages. |
|
append a log entry to each existing/enabled shell command log file. |
|
determine paths of the existing/enabled shell command log files, optionally enabling/creating a new log file. |
|
determine the absolute bin/executables folder path of a virtual pyenv environment. |
- EXEC_GIT_ERR_PREFIX = 'sh_exec() returned error '
used by sh_exit_if_exec_err to mark error in 1st output line
- GIT_CLONE_CACHE_CONTEXT = 'shell.git_clone'
temp directory context for git clone downloads
- GIT_FOLDER_NAME = '.git'
git subfolder in project path root of local repository
- GIT_REMOTE_ORIGIN = 'origin'
git origin remote name of (fork) repository in user account
- GIT_REMOTE_UPSTREAM = 'upstream'
git upstream remote name of original/forked repository
- GIT_RELEASE_REF_PREFIX = 'release'
git repository release branch name prefix
- GIT_VERSION_TAG_PREFIX = 'v'
git repository version tag prefix
- PIP_EDITABLE_PROJECT_PATH_PREFIX = 'Editable project location: '
caption/field-name of the console output of the pip show command.
- SHELL_LOG_FILE_NAME_SUFFIX = '_sh.log'
default file name (suffix) of the shell log file
- activate_venv(name='', app_obj=None)[source]
ensure to activate a virtual environment if it is different to the current one (the one on Python/app start).
- Parameters:
- Return type:
- Returns:
the name of the previously active venv or an empty string if the requested or no venv was active, or if venv is not supported.
- active_venv()[source]
determine the virtual environment that is currently active.
Note
the current venv gets set via data:`os.environ on start of this Python app or by
activate_venv().- Return type:
- Returns:
the name of the currently active venv.
- bytes_file_diff(file_content, file_path, line_sep='\\n')[source]
return the differences between the content of a file against the specified file content buffer.
- Parameters:
file_content¶ (
bytes) – older file bytes to be compared against the file content of the file specified by thefile_pathargument.file_path¶ (
str) – path to the file of which newer content gets compared against the file bytes specified by thefile_contentargument.line_sep¶ (
str) – string used to prefix, separate and indent the lines in the returned output string.
- Return type:
- Returns:
differences between the two file contents, compiled with the git diff command.
- check_commit_msg_file(project_path, *hint_args, commit_msg_file='.commit_msg.txt')[source]
check if the commit message file exists and if yes return the path of it.
- Parameters:
- Return type:
- Returns:
the path of the git commit message file of this project.
- Raises:
FileNotFoundError|shutdown if the commit message file is not readable or does not exist.
- editable_project_root_path(project_name)[source]
determine the project path of a project package installed as editable.
- git_any(project_path, *args)[source]
execute any git command.
- Parameters:
- Return type:
- Returns:
list of console output lines of the git command optionally including the exit error code (marked with
EXEC_GIT_ERR_PREFIXin the first returned list item), like returned bysh_exit_if_git_err().
- git_branches(project_path, *extra_args)[source]
determine all branch names with the git branch command.
- git_branch_files(project_path, branch_or_tag='develop', untracked=False, skip_file_path=<function <lambda>>)[source]
find all added/changed/deleted/renamed/unstaged worktree files that are not merged into the main branch.
- Parameters:
project_path¶ (
str) – path of the project root folder. pass empty string to use the current working directory.branch_or_tag¶ (
str) – branch(es)/tag(s)/commit(s) passed to git diff to specify the changed files between version(s).skip_file_path¶ (
Callable[[str],bool]) – called for each found file passing the file path relative to the project root folder (specified by theproject_pathargument), returning True to exclude/skip the file with passed file path.untracked¶ (
bool) – pass True to include untracked files from the returned result set.
- Return type:
- Returns:
set of file paths relative to worktree root specified by the project root path specified by the
project_pathargument.
Hint
see also func:git_uncommitted and the unit tests for the differences between them.
- git_branch_remotes(project_path, branch_pattern, remote_names=())[source]
return the remote names where the specified branch name exists.
- Parameters:
- Return type:
- Returns:
list of remote names where the branch exists.
- git_checkout(project_path, *extra_args, new_branch='', exit_on_err=True, force=False, remote_names=())[source]
checkout git branch.
- Parameters:
extra_args¶ (
str) – additional arguments passed onto git checkout command.new_branch¶ (
str) – new branch name to create and check out.exit_on_err¶ (
bool) – specify False to not exit the Python app on any git checkout error.force¶ (
bool) – pass True to ignore uncommitted files and if undefined branch.remote_names¶ (
Iterable[str]) – iterable with the remote names. determined withgit_remotes()if not specified.
- Return type:
- Returns:
error message or empty string if no error occurred.
- git_clone(repo_parent_url, project_name, *extra_args, branch_or_tag='', parent_path='', enable_log=False)[source]
clone a git remote repository from a repository hoster onto your local machine.
- Parameters:
repo_parent_url¶ (
str) – repository parent/group url (without the project name to clone).extra_args¶ (
str) – extra arguments passed onto the git clone command.branch_or_tag¶ (
str) – repo branch to clone. if not specified then the main branch will be cloned.parent_path¶ (
str) – destination path on the local machine to clone onto. if not specified a temporary folder will be used.enable_log¶ (
bool) – pass True to enable git shell command logging.
- Return type:
- Returns:
path to the cloned repository folder or empty string if an error occurred.
Hint
there could occur a user/password prompt if repo is private/invalid!
- git_commit(project_path, project_version, *extra_args, commit_msg_text='', commit_msg_file='.commit_msg.txt')[source]
execute the command ‘git commit’ for the specified project.
- Parameters:
project_path¶ (
str) – path of the project root folder, in which this git command gets executed.extra_args¶ (
str) – additional options or args passed to the git commit command line, e.g., [”–patch”, “–dry-run”]. except from the –file option, which will be added by this function with the name of the git commit message file.commit_msg_text¶ (
str) – used commit message. if specified then the argument incommit_msg_filewill be ignored.commit_msg_file¶ (
str) – name of the git commit message file (def=:data:COMMIT_MSG_FILE_NAME).
- git_current_branch(project_path)[source]
determine the currently checked-out branch of the specified git repository.
- git_diff(project_path, *extra_args)[source]
determine the uncommited/unstaged changes of a git project-
- Parameters:
- Return type:
- Returns:
list of console output lines of the git diff command, optionally including the exit error code (marked with
EXEC_GIT_ERR_PREFIXin the first returned list item), like returned bysh_exit_if_git_err().
- git_fetch(project_path, *extra_args, exit_on_err=False)[source]
fetch repository from remotes.
- Parameters:
- Return type:
- Returns:
list of lines from the console output that record an error (e.g. if no .git folder).
- git_init_if_needed(project_path, author='', email='', main_branch='develop')[source]
check if a git repository already exists in the specified project root folder, and create it if not.
- Parameters:
author¶ (
str) – author of the project/repo added to git config (if specified).email¶ (
str) – email address of the author added to git config (if specified).main_branch¶ (
str) – first main branch name to be checked out if repo did not exist / got created. if not specified then the module constantDEF_MAIN_BRANCHis used. pass empty string to not do the initial checkout on a not existing repository.
- Return type:
- Returns:
boolean True if a new repo got created and initialized, else False.
- git_merge(project_path, from_branch, *extra_options, commit_msg_text='', commit_msg_file='.commit_msg.txt', exit_on_err=False)[source]
merge current worktree with the specified [remote/]branch (exit app if an error occurred).
- Parameters:
project_path¶ (
str) – project root path of worktree to merge.from_branch¶ (
str) – branch (or commit/tag) to merge into current worktree with (optional with a leading upstream/origin remote name, e.g. “upstream/main_branch”).commit_msg_text¶ (
str) – commit message used for the optional merge commit. if specified then the argument incommit_msg_filewill be ignored.commit_msg_file¶ (
str) – name of the git commit message file (def=COMMIT_MSG_FILE_NAME).exit_on_err¶ (
bool) – specify True to exit the Python app on any git push error.
- Return type:
- Returns:
list with output lines of the git merge command (like returned by the function
sh_exit_if_git_err(), used to execute this git command). if the git command returned with an error code and the argument inexit_on_errgot not specified or as a True argument, then the app will quit. ifexit_on_errgot specified as ‘False’ and git push returned an error code, then it will be returned in the first line/list-item (prefixed withEXEC_GIT_ERR_PREFIX).
- git_push(project_path, remote_repo_url, *options_and_refs, exit_on_err=True)[source]
push the repo of the specified project with the specified branch/tags to the specified remote.
- Parameters:
remote_repo_url¶ (
str) – remote repo url. if git credentials are not configured on the local system, then a user token or password has to be included for the authentication against remote.options_and_refs¶ (
str) – extra arguments for the git command. pass additional options, e.g. “–delete” or “–set-upstream” or “-u”, and any references like branch/tag names to be pushed.exit_on_err¶ (
bool) – specify False to not exit the Python app on any git push error.
- Return type:
- Returns:
list with output lines of the git push command (like returned by the function
sh_exit_if_git_err(), used to execute this git push command). if git push returned with an error code and the argument inexit_on_errgot not specified or as a True argument, then the app will quit. ifexit_on_errgot specified as ‘False’ and git push returned an error code, then it will be returned in the first line/list-item (prefixed withEXEC_GIT_ERR_PREFIX).
- git_ref_in_branch(project_path, ref, branch='origin/develop')[source]
check if branch/tag/ref is in the specified branch.
- Parameters:
- Return type:
- Returns:
boolean True if the ref got found in the branch, else False.
- git_remote_domain_group(project_path, origin_name='origin', upstream_name='upstream', remote_urls=None)[source]
determine the domain and the repository owner group-/user-name from the git remote configuration (.git/config).
- Parameters:
project_path¶ (
str) – path to the project root folder of the repository.origin_name¶ (
str) – name of the origin git remote (to push to).upstream_name¶ (
str) – name of the upstream git remote (to request a merge from).remote_urls¶ (
Optional[dict[str,str]]) – remote urls. defaults togit_remotes()if not provided.
- Return type:
- Returns:
tuple with the domain and the user/group of the upstream repository url. if no upstream url is set/configured (not forked) then the origin url is used. if there is no remote configured at all, then the returned tuple contains two empty strings.
- git_renew_remotes(project_path, origin_url, upstream_url='', origin_name='origin', upstream_name='upstream', remotes=None)[source]
renew the origin remote and optionally (if repo is forked) also the upstream remote.
- Parameters:
origin_url¶ (
str) – new url of the origin repo. will append a missing .git extension to the specified url.upstream_url¶ (
str) – new url of the upstream repo if forked. if specified and differs to the actual upstream url and to the specified origin url, then it will be automatically added. appends a missing .git extension to the specified url.origin_name¶ (
str) – name of the origin git remote (to push to). if not specified defaults toGIT_REMOTE_ORIGIN.upstream_name¶ (
str) – name of the upstream git remote (to request a merge from). if not specified defaults toGIT_REMOTE_UPSTREAM.remotes¶ (
Optional[dict[str,str]]) – pass the actual git remotes to prevent multiple execution of the git remote command. determined viagit_remotes()if not specified.
- Return type:
- Returns:
list of console output lines of the executed git remote commands. an empty list no errors/warnings got outputted by the git remote command.
- git_tag_add(project_path, tag, commit_msg_text='', commit_msg_file='.commit_msg.txt')[source]
add a new tag onto the project in the specified project root path
- Parameters:
- Return type:
- Returns:
console output of the git tag –annotate command.
- git_tag_list(project_path, remote='', tag_pattern='*')[source]
determine a list of matching tags of a local or remote git repository.
- Parameters:
- Return type:
- Returns:
list of matching repo tags, ordered via the git ls-remote option –sort=version:refname. an empty list will be returned if no tag is matching the specified tag pattern or an error occurred or if the project has no .git folder.
- git_tag_remotes(project_path, tag_pattern, remote_names=())[source]
return the remote names where the specified tag name exists.
- Parameters:
- Return type:
- Returns:
list of remote names where the tag exists.
- git_uncommitted(project_path)[source]
determine the changed/untracked/uncommitted files of a git repository/project.
- Parameters:
- Return type:
- Returns:
set of changed/untracked/uncommitted file names. an empty set will be returned if the git repo is not initialized or if there are no uncommitted files in the git repo specified by project_path.
Hint
see also func:git_branch_files and the unit tests for the differences between them.
- in_prj_dir_venv(project_path, venv_name='')[source]
ensure the current working directory and the specified or .python-version-configured Python Virtual Environment.
- Parameters:
project_path¶ (
str) – path to the project root folder to switch the current working directory in this context.venv_name¶ (
str) – name of the Python Virtual Environment to activate in this context. if not specified (or as empty string), then the venv configured via the file .python-version will be activated.
- Return type:
- Returns:
- owner_project_from_url(remote_url)[source]
determine the owner and project name path from the specified git remote repository url.
- sh_exit_if_git_err(err_code, command_line, extra_args=(), lines_output=None, exit_on_err=False, app_obj=None, log_enable_dir='')[source]
execute git command with optional git trace output, returning the stdout lines cleaned from any trace messages.
- Parameters:
err_code¶ (
int) – error code to pass to the console as exit code ifexit_on_erris True.command_line¶ (
str) – command line string to execute on the console/shell. could contain command line args separated by whitespace characters (alternatively useextra_args).extra_args¶ (
Iterable[str]) – optional iterable of extra command line arguments.lines_output¶ (
Optional[list[str]]) – optional list to return the lines printed to stdout/stderr on execution. by passing an empty list, the stdout and stderr streams/pipes will be separated, resulting in having the stderr output lines at the end of the list. specify at least on list item to merge-in the stderr output (into the stdout output and return).app_obj¶ (
Optional[ConsoleApp]) – optionalConsoleAppinstance, used for logging. if not specified or None then the Pythonprint()function is used. specifyUNSETto suppress any printing/logging output.app_obj¶ –
ConsoleAppinstance, for logging and ignorable-error-checks.log_enable_dir¶ (
str) – pass the path of the directory in which git shell command logging have to get enabled.
- Return type:
- Returns:
output lines of git command - cleaned from GIT_TRACE messages, if
exit_on_errgot specified as ‘False’ and the executed git command returned an error code, then the error code will be returned in the first line/list-item (prefixed withEXEC_GIT_ERR_PREFIX).
- sh_log(comment_or_command, extra_args=(), cl_err=0, lines_output=(), log_file_paths=(), log_name_prefix='')[source]
append a log entry to each existing/enabled shell command log file.
- Parameters:
comment_or_command¶ (
str) – command line or comment line (if starts with the # character).extra_args¶ (
Iterable[str]) – extra arguments (added to the command line).log_file_paths¶ (
Iterable[str]) – log file paths - if specified then the search of the default locations for log files will be skipped and thereforelog_name_prefixwill be ignored.log_name_prefix¶ (
str) – log file name prefix. extended with theSHELL_LOG_FILE_NAME_SUFFIXresults in the file name to search for (and to log into if exists).
- sh_logs(log_enable_dir='', log_name_prefix='')[source]
determine paths of the existing/enabled shell command log files, optionally enabling/creating a new log file.
- Parameters:
log_enable_dir¶ (
str) – specify the directory/folder path in which to enable shell command logging, by creating a new log file (and the folder) if they not exist. valid folder paths are either the CWD where the shell command get executed (e.g. the project root folder) or the users home directory (~).log_name_prefix¶ (
str) – log file name prefix. extended with theSHELL_LOG_FILE_NAME_SUFFIXresults in the file name to search for (and to log into if exists).
- Return type:
- Returns:
list of existing/enabled shell log file name paths.
- venv_bin_path(name='')[source]
determine the absolute bin/executables folder path of a virtual pyenv environment.
- Parameters:
name¶ (
str) – the name of the venv. if not specified, then the venv name will be determined from the first found.python-versionfile, starting in the current working directory (cwd) and up to 5 parent directories above. if no.python-versionfile could be found then the name of the currently active venv will be used (via the functionactive_venv()respectively theVIRTUAL_ENVshell environment variable).- Return type:
- Returns:
absolute path of the “bin” folder in the specified/determined virtual environment or an empty string if pyenv is not installed or no venv name or bin folder could be found.
Note
under Windows/win32 the base name of the returned path is ‘Scripts’ (not ‘bin’), and the executables have a file extension (e.g., pip.exe, activate.bat, python.exe).