Skip to content

Utility functions for plugins

The file django_simple_deploy/management/commands/utils/plugin_utils.py contains utility functions for tasks that many plugins need to carry out. Before writing your own code to modify or inspect the user's project, take a look at the functions available in this file. Using them should make your work easier, and should make your plugin behave in a manner consistent with other plugins as well.

plugin_utils.py

Utilities for django-simple-deploy, to be used by platform-specific plugins.

Note: Some of these utilities are used by django-simple-deploy internally as well.

_check_poetry_deploy_group()

Make sure a deploy group exists in pyproject.toml.

_strip_secret_key(line)

Strip secret key value from log file lines.

add_dir(path)

Write a new directory to the file.

This function is meant to be used when adding new directories that don't typically exist in a Django project. For example, a platform-specific directory such as .platform/ for Platform.sh.

Only adds the directory; does nothing if the directory already exists.

Returns: - None

add_file(path, contents)

Add a new file to the project.

This function is meant to be used when adding new files that don't typically exist in a Django project that runs locally. For example, a platform-specific Dockerfile. See the add_dockerfile() method in Fly.io's deployer module.

If the file does not exist, it is written to the project. If the file already exists, the user is prompted for permission to overwrite the file.

Returns: - None

Raises: - DSDCommandError: If file exists, and user does not give permission to overwrite file.

add_package(package_name, version='')

Add a package to the project's requirements, if not already present.

Handles calls with version information with pip formatting

add_package("psycopg2", version="<2.9")

The utility helpers handle this version information correctly for the dependency management system in use.

Returns:

Type Description

None

add_packages(package_list)

Add a set of packages to the project's requirements.

This is a simple wrapper for add_package(), to make it easier to add multiple requirements at once. If you need to specify a version for a particular package, use add_package().

Returns:

Type Description

None

add_pipenv_pkg(pipfile_path, package, version)

Add a package to Pipfile.

add_poetry_pkg(pptoml_path, package, version)

Add a package to poetry deploy group of pyproject.toml.

add_req_txt_pkg(req_txt_path, package, version)

Add a package to requirements.txt.

check_settings(platform_name, start_line, msg_found, msg_cant_overwrite)

Check if a platform-specific settings block already exists.

If so, ask if we can overwrite that block. This is much simpler than trying to keep track of individual settings.

Returns:

Type Description

None

Raises:

Type Description
DSDCommandError

If we can't overwrite existing platform-specific

commit_changes()

Commit changes that have been made to the project.

This should only be called when automate_all is being used.

create_poetry_deploy_group(pptoml_path)

Create a deploy group for Poetry in pyproject.toml.

get_confirmation(msg='Are you sure you want to do this?', skip_logging=False)

Get confirmation for an action.

Assumes an appropriate message has already been displayed about what is to be done. Shows a yes|no prompt. You can pass a different message for the prompt; it should be phrased to elicit a yes/no response.

Returns:

Name Type Description
bool

True if confirmation granted, False if not granted.

get_numbered_choice(prompt, valid_choices, quit_message)

Select from a numbered list of choices.

This is used, for example, to select from a number of apps that the user has created on a platform.

get_string_from_output(output)

Convert output to string.

Output may be a string, or an instance of subprocess.CompletedProcess.

This function assumes that output is either stdout or stderr, but not both. If we need to display both, consider redirecting stderr to stdout: subprocess.run(cmd_parts, stderr=subprocess.STDOUT, ...) This has not been necessary yet; if it becomes necessary we'll probably need to modify run_quick_command() to accommodate the necessary args.

get_template_string(template_path, context)

Given a template and context, return contents as a string.

Contents can then be written to a file.

Returns: - Str: single string representing contents of the rendered template.

get_user_info(prompt, strip_response=True)

Ask the user for some information.

If you want to preserve whitespace, pass strip_response=False.

The main benefit to using this function is consistent logging. Returns: - Str: User's response, after calling strip().

log_info(output)

Log output, which may be a string or CompletedProcess instance.

log_output_string(output)

Log output as a series of single lines, for better log parsing.

Returns:

Type Description

None

logs_to_console(logger=None)

Check if logging is configured to stream to stdout or stderr.

modify_file(path, contents)

Modify an existing file.

This function is meant for modifying a file that should already exist, such as settings.py. We're not getting permission; if unwanted changes are somehow made, the user can use Git to restore the file to its original state.

Returns: - None

Raises: - DSDCommandError: If file does not exist.

modify_settings_file(template_path, context=None)

Add a platform-specific settings block to settings.py.

Provide a path to a template including current settings and the platform-specific settings block, and a context dictionary.

read_log()

Get the contents of the current log file.

remove_doubled_blank_lines(contents)

Remove doubled blank lines from a content string.

Template tags often render as blank lines. Dealing with this in the template usually makes the template much less readable.

Let plugin authors call this explicitly. If we put this in get_template_string(), you could never have intentional double blank lines in rendered templates.

run_quick_command(cmd, check=False, skip_logging=False)

Run a command that should finish quickly.

Commands that should finish quickly can be run more simply than commands that will take a long time. For quick commands, we can capture output and then deal with it however we like, and the user won't notice that we first captured the output.

The check parameter is included because some callers will need to handle exceptions. For example, see prep_automate_all() in dsd-upsun. Most callers will only check stderr, or maybe the returncode; they won't need to involve exception handling.

Returns:

Type Description

CompletedProcess

Raises:

Type Description
CalledProcessError

If check=True is passed, will raise CalledProcessError

run_slow_command(cmd, skip_logging=False)

Run a command that may take some time.

For commands that may take a while, we need to stream output to the user, rather than just capturing it. Otherwise, the command will appear to hang.

write_output(output, write_to_console=True, skip_logging=False)

Write output to the appropriate places.

Typically, this is used for writing output to the console as the configuration and deployment work is carried out. Output may be a string, or an instance of subprocess.CompletedProcess.

Output that's passed to this method typically needs to be logged as well, unless skip_logging has been passed. This is useful, for example, when writing sensitive information to the console.

Returns:

Type Description

None