From f281062060c181904c1ee7c36a1504749e99aab2 Mon Sep 17 00:00:00 2001 From: ronny abraham Date: Wed, 10 Jan 2024 04:56:59 +0200 Subject: [PATCH] updated all docstrings, moved some files around, fixed a TODO in the coverage task so now it will check if coverage exists --- modules/django.py | 295 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 235 insertions(+), 60 deletions(-) diff --git a/modules/django.py b/modules/django.py index dcb36c4..5af031b 100644 --- a/modules/django.py +++ b/modules/django.py @@ -15,6 +15,7 @@ dir_parent = pathlib.Path(os.path.abspath(__file__)).parents[2] sys.path.append(str(dir_parent)) try: + import customfabric.modules.pip as pip import customfabric.modules.utils as modules_utils from customfabric.modules.utils import virtualenv @@ -55,13 +56,79 @@ def generate_secret_key(): @task -def test(args=None): +def admin(args="help"): """ - the purpose of this method is just to use as a placeholder for any kind of - testing of methods + Executes a Django admin command within a specified virtual environment and + Django project directory. + + This method uses Fabric's context managers to change the current directory + to the Django project root and then executes the 'django-admin' command + with the given arguments. The Django project settings and python path are + set according to the configuration defined in 'env.config'. It's important + to note that this method is designed to be run within a Fabric task + context. + + :param args: The arguments to pass to the 'django-admin' command. Defaults + to "help", which displays the help message for 'django-admin'. + :type args: str + + :raises ImportError: If required packages like 'fabric' or 'django' are not + installed. + + :raises OSError: If there is an issue with changing directories or + executing the command. + + Note: + The method assumes that 'env.config' is properly set with necessary + paths and settings. + + It's crucial to ensure that 'shell' is set to '/bin/bash' for the + command execution environment. """ - print("debug - testing checkapp(sorl.thumbnail): %s" % - check_app("sorl.thumbnail")) + configuration = env.config + + from fabric.context_managers import cd + + with virtualenv(): + with cd(configuration.paths.django.root): + fabric_ops.run( + "django-admin {args} --pythonpath='{djangoroot}' " + "--settings={djangosettings}".format( + djangoroot=configuration.paths.django.root, + args=args, + djangosettings=configuration.imports.settings, + ), + # MAKE SURE THIS IS ALWAYS HERE! + shell='/bin/bash' + ) + + +@task +def collectstatic(): + """ + Collects static media files for a Django project. + + This method ensures that the static and dynamic media directories, as + defined in `configuration.paths.server.media`, exist before executing the + `collectstatic` command via Django's manage.py. It's a crucial step in + deploying or running a Django project, ensuring that all static assets are + gathered in the locations specified in the Django settings. + + Note: + - This method assumes the existence of `env.config` with the correct + configuration paths. + + - The `--noinput` flag is used with `manage("collectstatic --noinput")` + to run the command without interactive prompts, suitable for + automated deployment scripts. + """ + + configuration = env.config + + exists(configuration.paths.server.media.static) + exists(configuration.paths.server.media.dynamic) + + manage("collectstatic --noinput") @task @@ -185,7 +252,7 @@ def manage(args="help", workingdir=None, prefix="", suffix=""): # shell='/bin/bash' in all uses of local! -def coverage_test(): +def _coverage_test(): """ helper method to determine if coverage config exists and if not print out an error message @@ -247,6 +314,8 @@ def coverage(application=None, args="test", workingdir=None, outputdir=None, report, defaults to True. :type html: bool, optional + :raises ImportError: If the 'coverage' package is not installed. + :raises TypeError: If the types of the parameters provided do not match the expected types. @@ -272,6 +341,11 @@ def coverage(application=None, args="test", workingdir=None, outputdir=None, method to specifically ask for the applications being used """ + if not pip.check_package_installed('coverage'): + raise ImportError( + "The 'coverage' package is required but not installed. Install it" + " via pip with 'pip install coverage'.") + # Check if 'workingdir' is provided and exists if workingdir and not os.path.isdir(workingdir): raise FileNotFoundError( @@ -295,7 +369,7 @@ def coverage(application=None, args="test", workingdir=None, outputdir=None, configuration = env.config - coverage_test() + _coverage_test() prefix = "coverage run" @@ -325,42 +399,29 @@ def coverage(application=None, args="test", workingdir=None, outputdir=None, manage(args=args, workingdir=workingdir, prefix=prefix, suffix=suffix) -@task -def admin(args="help"): - configuration = env.config - - from fabric.context_managers import cd - - with virtualenv(): - with cd(configuration.paths.django.root): - fabric_ops.run( - "django-admin {args} --pythonpath='{djangoroot}' " - "--settings={djangosettings}".format( - djangoroot=configuration.paths.django.root, - args=args, - djangosettings=configuration.imports.settings, - ), - # MAKE SURE THIS IS ALWAYS HERE! - shell='/bin/bash' - ) - - -@task -def collectstatic(): - """ - makes sure the static media directories exist - """ - - configuration = env.config - - exists(configuration.paths.server.media.static) - exists(configuration.paths.server.media.dynamic) - - manage("collectstatic --noinput") - - @task def run(args=None): + """ + Starts the Django development server with the specified arguments. + + This method constructs and executes a `runserver` command using Django's + manage.py. The host and port for the server are taken from + `configuration.server.django`. This method is primarily used for local + development purposes. + + :param args: Additional arguments to pass to the `runserver` command. + Defaults to None. + + :type args: str, optional + + :return: The output from the `manage` command execution. + :rtype: str + + Note: + - The `configuration` object must be properly set up in `env.config` + with the server host and port. + """ + configuration = env.config command = "runserver {host}:{port}".format( @@ -374,11 +435,23 @@ def run(args=None): @task def startapp(appname='help'): """ - wrapper for the django.startapp + Creates a new Django app with the specified name within the project. - takes name of app and creates in in code/apps + This method serves as a wrapper for Django's `startapp` command. It takes + the name of the app and creates it in the `code/apps` directory of the + Django project. If 'help' or no app name is provided, it displays a help + message and exits. - appname - name of app + :param appname: The name of the new Django app to create. Defaults to + 'help' which triggers a help message. + :type appname: str + + Note: + - The `configuration.paths.django.apps` path in `env.config` is used as + the working directory for app creation. + + - Exiting with `sys.exit()` on receiving 'help' as input is a part of + its functionality. """ configuration = env.config @@ -529,16 +602,30 @@ def create_project(): def generate_scripts(template_name, make_copy=False): """ - this is a function meant to generate django settings files + Generates Django settings files based on a specified template. - There are a number of different types of django settings files so instead - of generating all of them at the same time (sometimes I want the local, - sometimes I want the main, etc), I decided to create a function that can - look up the type of scripts I want and generate those. + This function is designed to generate different types of Django settings + files (like local or main settings) based on the provided template name. + It's meant to be used within another function that specifies the type of + script required. - The function is meant to be wrapped up in another funciton that will call - the type of script I want + :param template_name: The name of the template to use for generating the + script. + :type template_name: str + + :param make_copy: Flag to determine whether to make a copy of the generated + script, defaults to False. + :type make_copy: bool + + Note: + - The function relies on `env.config` for various paths and settings. + - `make_copy` parameter should be booleanized before use. + - the function is meant to be called privately + + TODO: + privatize the function """ + configuration = env.config # make sure to booleanize ALL boolean values! @@ -714,8 +801,27 @@ def generate_scripts(template_name, make_copy=False): @task def generate(param="help", make_copy=False): """ - param can be one of settings, local, local.generated, wsgi - make_copy must be set to True if you want it to actually do anthing + Generates scripts for Django settings, local settings, or WSGI based on the + specified parameter. + + This method acts as a wrapper for generating various Django-related + scripts. It supports generating settings, local settings, local.generated, + and WSGI scripts. A specific script type is selected through the 'param' + argument. + + :param param: The type of script to generate. Can be 'settings', 'local', + 'local.generated', 'wsgi', or 'gunicorn', defaults to "help". + :type param: str + + :param make_copy: Determines whether to copy the generated file to its + practical location, defaults to False. + :type make_copy: bool + + Note: + - 'make_copy' must be set to True for the function to perform any + copying. + - If 'param' is not specified, the function will attempt to generate + all scripts. """ SCRIPT_LIST = ['settings', 'local', 'local.generated', 'wsgi'] @@ -775,9 +881,22 @@ def generate(param="help", make_copy=False): def generate_gunicorn(make_link=True): """ - create the gunicorn configuration script - put it in the build folder and link it to the scripts directory + Creates and links the Gunicorn configuration script. + + This function generates the Gunicorn configuration script and places it in + the build folder. It optionally creates a symbolic link to the script in + the scripts directory. + + :param make_link: Flag to determine whether to create a symbolic link to + the generated script, defaults to True. + :type make_link: bool + + Note: + - The function relies on `env.config` for configuration paths and + settings. + - `make_link` parameter should be booleanized before use. """ + configuration = env.config make_link = booleanize(make_link) @@ -867,7 +986,21 @@ def generate_gunicorn(make_link=True): @task def edit(param='help'): """ - calls up mvim on the gunicorn and django conf file + Facilitates editing of Django and Gunicorn configuration files. + + This method provides a convenient way to open various configuration files + related to Django and Gunicorn for editing, using the 'mvim' editor. The + specific file to be edited is determined by the 'param' argument. + + :param param: Specifies the configuration file to edit. Options include + paths to gunicorn.conf, Django settings files, log files, etc., + defaults to 'help'. + :type param: str + + Note: + - The configuration paths are taken from `env.config`. + - If 'param' is 'help', the function displays a list of editable + locations and their descriptions. """ from .maintenance import edit as maintenance_edit @@ -965,7 +1098,7 @@ def edit(param='help'): # and add a coverage entry to locations if param == 'coverage': - coverage_test() + _coverage_test() locations['coverage'] = { 'path': configuration.coverage.config, @@ -1057,8 +1190,27 @@ def makemigrations_empty(param="help"): @task def fixtures(appname=None, backup=False): """ - @appname django app name for this fixture - @backup default False, store in server backup dir? + Generates a JSON fixture for the specified Django app and optionally backs + it up. + + This method dumps the data of a specified Django app into a JSON fixture. + If the `backup` parameter is set to True, the fixture is stored in the + server's backup directory. If no app name is specified, it generates a + fixture for all apps. + + :param appname: Name of the Django app for which to generate a fixture. If + None, fixtures for all apps are generated, defaults to None. + :type appname: str, optional + + :param backup: Flag to determine whether to store the fixture in the + server's backup directory, defaults to False. + :type backup: bool + + Note: + - The fixture file is named as '.json' or 'all.json' if no + appname is specified. + - The paths for fixtures and backups are retrieved from + `configuration.paths`. """ configuration = env.config @@ -1138,7 +1290,20 @@ def fixtures(appname=None, backup=False): @task def loaddata(param=None): """ - loads fixture data to the specified app from extras/data + Loads fixture data into the specified Django app. + + This method imports data from a JSON fixture file into a specified Django + app. The fixture file should be located in the 'extras/data' directory. If + no app name is provided, the method exits without performing any action. + + :param param: Name of the Django app to which the fixture data will be + loaded, defaults to None. + :type param: str, optional + + Note: + - The fixture file is expected to be named as '.json'. + - The path for fixtures is retrieved from + `configuration.paths.django.fixtures`. """ configuration = env.config @@ -1182,3 +1347,13 @@ def check_app(appname): return True else: return False + + +@task +def test(args=None): + """ + the purpose of this method is just to use as a placeholder for any kind of + testing of methods + """ + print("debug - testing checkapp(sorl.thumbnail): %s" % + check_app("sorl.thumbnail"))