From bc6abbd2ca33c3ea316428a09fd9fb6bc707dd53 Mon Sep 17 00:00:00 2001 From: drorganvidez Date: Sun, 24 Mar 2024 13:23:04 +0100 Subject: [PATCH] feat: Implement Rosemary CLI --- .gitignore | 4 ++- Dockerfile.dev | 10 +++++-- README.md | 50 ++++++++++++++++++++++++++--------- requirements.txt | 3 ++- rosemary/__init__.py | 0 rosemary/cli.py | 19 +++++++++++++ rosemary/commands/__init__.py | 0 rosemary/commands/env.py | 15 +++++++++++ rosemary/commands/info.py | 31 ++++++++++++++++++++++ rosemary/commands/update.py | 29 ++++++++++++++++++++ setup.py | 21 +++++++++++++++ 11 files changed, 166 insertions(+), 16 deletions(-) create mode 100644 rosemary/__init__.py create mode 100644 rosemary/cli.py create mode 100644 rosemary/commands/__init__.py create mode 100644 rosemary/commands/env.py create mode 100644 rosemary/commands/info.py create mode 100644 rosemary/commands/update.py create mode 100644 setup.py diff --git a/.gitignore b/.gitignore index 556db4840..8522fcf08 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,6 @@ __pycache__/ .idea uploads/ app.log -.DS_Store \ No newline at end of file +.DS_Store +rosemary.egg-info/ +build/ \ No newline at end of file diff --git a/Dockerfile.dev b/Dockerfile.dev index 0c9327e84..2e0426cad 100644 --- a/Dockerfile.dev +++ b/Dockerfile.dev @@ -1,14 +1,17 @@ # Use an official Python runtime as a parent image FROM python:3.11-alpine +# Set this environment variable to suppress the "Running as root" warning from pip +ENV PIP_ROOT_USER_ACTION=ignore + # Install the MySQL client to be able to use it in the standby script. RUN apk add --no-cache mysql-client # Set the working directory in the container to /app WORKDIR /app -# Copy the contents of the local app/ directory to the /app directory in the container -COPY app/ ./app +# Copy the entire project into the container +COPY . . # Copy requirements.txt at the /app working directory COPY requirements.txt . @@ -19,6 +22,9 @@ COPY --chmod=+x scripts/wait-for-db.sh ./scripts/ # Install any needed packages specified in requirements.txt RUN pip install --no-cache-dir -r requirements.txt +# Install rosemary CLI tool +RUN pip install --no-cache-dir . + # Update pip RUN pip install --no-cache-dir --upgrade pip diff --git a/README.md b/README.md index e9264a44a..b78815a60 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,44 @@ To run unit test, please enter inside `web` container: pytest app/tests/units.py ``` +## Using Rosemary CLI + +`Rosemary` is a CLI tool developed to facilitate project management and development tasks. + +To use the Rosemary CLI, you need to be inside the `web_app_container` Docker container. This ensures that Rosemary operates in the correct environment and has access to all necessary files and settings. + +First, make sure your Docker environment is running. Then, access the `web_app_container` using the following command: + +``` +docker exec -it web_app_container /bin/sh +``` + +In the terminal, you should see the prefix `/app #`. You are now ready to use Rosemary's commands. + +### Update Project Dependencies + +To update all project dependencies, run: + +``` +rosemary update +``` + +Note: it is the responsibility of the developer to check that the update of the dependencies has not broken any +functionality and each dependency maintains backwards compatibility. Use the script with care! + +### Viewing Environment Variables + +To view the current `.env` file settings, use: + +``` +rosemary env +``` +### Available Commands + +- `rosemary update`: Updates all project dependencies and the `requirements.txt` file. +- `rosemary info`: Displays information about the Rosemary CLI, including version and author. +- `rosemary env`: Displays the current environment variables from the `.env` file. + ## Deploy in production (Docker Compose) ``` @@ -107,15 +145,3 @@ To renew a certificate that is less than 60 days from expiry, execute: cd scripts chmod +x ssl_renew.sh && ./ssl_renew.sh ``` - -## Update dependencies - -To update all project dependencies automatically, run: - -``` -cd scripts -chmod +x update_dependencies.sh && ./update_dependencies.sh -``` - -Note: it is the responsibility of the developer to check that the update of the dependencies has not broken any functionality and each dependency maintains backwards compatibility. Use the script with care! - diff --git a/requirements.txt b/requirements.txt index 09d69c4b7..a8754311f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -31,7 +31,8 @@ PyMySQL==1.1.0 pytest==8.1.1 python-dotenv==1.0.1 requests==2.31.0 -SQLAlchemy==2.0.28 +rosemary @ file:///app +SQLAlchemy==2.0.29 typing_extensions==4.10.0 Unidecode==1.3.8 urllib3==2.2.1 diff --git a/rosemary/__init__.py b/rosemary/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/rosemary/cli.py b/rosemary/cli.py new file mode 100644 index 000000000..b803b50f7 --- /dev/null +++ b/rosemary/cli.py @@ -0,0 +1,19 @@ +# rosemary/cli.py + +import click +from rosemary.commands.update import update +from rosemary.commands.info import info +from rosemary.commands.env import env + + +@click.group() +def cli(): + pass + + +cli.add_command(update) +cli.add_command(info) +cli.add_command(env) + +if __name__ == '__main__': + cli() diff --git a/rosemary/commands/__init__.py b/rosemary/commands/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/rosemary/commands/env.py b/rosemary/commands/env.py new file mode 100644 index 000000000..b6e4d62a6 --- /dev/null +++ b/rosemary/commands/env.py @@ -0,0 +1,15 @@ +# rosemary/commands/env.py + +import click +from dotenv import dotenv_values + + +@click.command() +def env(): + """Displays the current .env file values.""" + # Load the .env file + env_values = dotenv_values(".env") + + # Display keys and values + for key, value in env_values.items(): + click.echo(f"{key}={value}") diff --git a/rosemary/commands/info.py b/rosemary/commands/info.py new file mode 100644 index 000000000..7ff7f8843 --- /dev/null +++ b/rosemary/commands/info.py @@ -0,0 +1,31 @@ +import click +import pkg_resources + + +def get_metadata_value(metadata_lines, key): + default_value = f"{key}: Unknown" + line = next((line for line in metadata_lines if line.startswith(key)), default_value) + return line.split(':', 1)[1].strip() if line != default_value else default_value.split(':', 1)[1].strip() + + +@click.command() +def info(): + """Displays information about the Rosemary CLI.""" + distribution = pkg_resources.get_distribution("rosemary") + + try: + metadata = distribution.get_metadata_lines('METADATA') + author = get_metadata_value(metadata, 'Author') + author_email = get_metadata_value(metadata, 'Author-email') + description = get_metadata_value(metadata, 'Summary') + except FileNotFoundError: + author, author_email, description = "Unknown", "Unknown", "Not available" + + name = distribution.project_name + version = distribution.version + + click.echo(f"Name: {name}") + click.echo(f"Version: {version}") + click.echo(f"Author: {author}") + click.echo(f"Author-email: {author_email}") + click.echo(f"Description: {description}") diff --git a/rosemary/commands/update.py b/rosemary/commands/update.py new file mode 100644 index 000000000..9ca4af556 --- /dev/null +++ b/rosemary/commands/update.py @@ -0,0 +1,29 @@ +# rosemary/commands/update.py + +import click +import subprocess +import os + + +@click.command() +def update(): + """This command updates pip, all packages, and updates requirements.txt.""" + try: + # Update pip + subprocess.check_call(['pip', 'install', '--upgrade', 'pip']) + + # Get the list of installed packages and update them + packages = subprocess.check_output(['pip', 'freeze']).decode('utf-8').split('\n') + for package in packages: + package_name = package.split('==')[0] + if package_name: # Check if the package name is not empty + subprocess.check_call(['pip', 'install', '--upgrade', package_name]) + + # Update requirements.txt + requirements_path = os.path.join(os.getcwd(), 'requirements.txt') + with open(requirements_path, 'w') as f: + subprocess.check_call(['pip', 'freeze'], stdout=f) + + click.echo('Update completed!') + except subprocess.CalledProcessError as e: + click.echo(f'Error during the update: {e}') diff --git a/setup.py b/setup.py new file mode 100644 index 000000000..45cddb146 --- /dev/null +++ b/setup.py @@ -0,0 +1,21 @@ +# setup.py + +from setuptools import setup, find_packages + +setup( + name='rosemary', + version='0.1.0', + packages=find_packages(), + include_package_data=True, + install_requires=[ + 'click', + 'python-dotenv', + ], + author='David Romero', + author_email='drorganvidez@us.es', + description="Rosemary is a CLI to be able to work on UVLHub development more easily.", + entry_points=''' + [console_scripts] + rosemary=rosemary.cli:cli + ''', +)