From d13294611e210f391f50c6aa5590b9cf73aec081 Mon Sep 17 00:00:00 2001 From: Ivan Ogasawara Date: Wed, 3 Apr 2024 22:43:52 -0400 Subject: [PATCH] docs: Add tutorials (#101) * add tutorials * improve the documentation configuration * add a workflow dispatch for publishing documentation --- .github/workflows/docs.yaml | 42 + .makim.yaml | 19 - docs/scripts/clean-output.py | 21 + docs/tutorials/introduction/.makim.yaml | 12 + docs/tutorials/introduction/index.ipynb | 991 ++++++++++++++++++ .../tutorials/makim-for-nox-users/.makim.yaml | 33 + .../tutorials/makim-for-nox-users/index.ipynb | 759 ++++++++++++++ docs/tutorials/makim-for-nox-users/noxfile.py | 15 + mkdocs.yaml | 38 +- 9 files changed, 1900 insertions(+), 30 deletions(-) create mode 100644 .github/workflows/docs.yaml create mode 100644 docs/scripts/clean-output.py create mode 100644 docs/tutorials/introduction/.makim.yaml create mode 100644 docs/tutorials/introduction/index.ipynb create mode 100644 docs/tutorials/makim-for-nox-users/.makim.yaml create mode 100644 docs/tutorials/makim-for-nox-users/index.ipynb create mode 100644 docs/tutorials/makim-for-nox-users/noxfile.py diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml new file mode 100644 index 0000000..710310b --- /dev/null +++ b/.github/workflows/docs.yaml @@ -0,0 +1,42 @@ +name: Documentation + +on: + workflow_dispatch: + +env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + +jobs: + release: + runs-on: ubuntu-latest + timeout-minutes: 15 + + defaults: + run: + shell: bash -l {0} + + steps: + - uses: actions/checkout@v3 + + - uses: conda-incubator/setup-miniconda@v3 + with: + miniforge-version: latest + environment-file: conda/dev.yaml + channels: conda-forge,nodefaults + activate-environment: makim + auto-update-conda: true + conda-solver: libmamba + + - name: Install deps + run: | + poetry config virtualenvs.create false + poetry install + + - name: Generate documentation with changes from semantic-release + run: makim --verbose docs.build + + - name: GitHub Pages action + uses: peaceiris/actions-gh-pages@v3.5.9 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./build/ diff --git a/.makim.yaml b/.makim.yaml index 125e708..4596d3c 100644 --- a/.makim.yaml +++ b/.makim.yaml @@ -21,25 +21,6 @@ groups: docs: targets: - pre-build: - help: pre-build step - shell: bash - run: | - mkdir -p build - # Directory to search for .ipynb files - export SEARCH_DIR="docs/tutorials" - - # Find all .ipynb files, excluding .ipynb_checkpoints, - # and convert them to Markdown named 'index.md' - find "$SEARCH_DIR" -path "*/.ipynb_checkpoints/*" -prune -o -name \ - "*.ipynb" -exec sh -c \ - 'jupyter nbconvert --to markdown --output-dir "$(dirname "$0")" "$0"' {} \; - - # remove console colors from md files - find "$SEARCH_DIR" -name \ - "*.md" -exec sh -c \ - 'cat "$0" | python docs/scripts/clean-output.py > "$(dirname "$0")/temp_index.md" && mv "$(dirname "$0")/temp_index.md" "$0"' {} \; - build: help: Build documentation run: | diff --git a/docs/scripts/clean-output.py b/docs/scripts/clean-output.py new file mode 100644 index 0000000..b81fb86 --- /dev/null +++ b/docs/scripts/clean-output.py @@ -0,0 +1,21 @@ +import re +import sys + +def remove_ansi_escape_sequences(text: str) -> str: + """ + Remove ANSI escape sequences from a string. + + Parameters: + - text: A string that may contain ANSI escape codes. + + Returns: + - A string with ANSI escape codes removed. + """ + # ANSI escape code regex pattern + ansi_escape_pattern = re.compile(r'(?:\x1B[@-_]|[\x80-\x9F])[0-?]*[ -/]*[@-~]') + return ansi_escape_pattern.sub('', text) + +if __name__ == "__main__": + input_text = sys.stdin.read() + cleaned_text = remove_ansi_escape_sequences(input_text) + print("{% raw %}" + cleaned_text + "{% endraw %}", end='') diff --git a/docs/tutorials/introduction/.makim.yaml b/docs/tutorials/introduction/.makim.yaml new file mode 100644 index 0000000..eb8c737 --- /dev/null +++ b/docs/tutorials/introduction/.makim.yaml @@ -0,0 +1,12 @@ +version: 1.0 +working-directory: "/tmp" + +groups: + check-wd: + targets: + is-tmp: + help: Test if working directory is `tmp` + run: | + import os + print(os.getcwd()) + assert os.getcwd() == "/tmp" diff --git a/docs/tutorials/introduction/index.ipynb b/docs/tutorials/introduction/index.ipynb new file mode 100644 index 0000000..955fe49 --- /dev/null +++ b/docs/tutorials/introduction/index.ipynb @@ -0,0 +1,991 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "232d0e08-2248-40d7-a1f9-c52bff1b357a", + "metadata": {}, + "source": [ + "# Get Started\n", + "\n", + "In software development, where efficiency, consistency, and reliability are paramount, automation tools play a crucial role. Makim, an innovative open-source tool, steps into the spotlight to improve automation workflows. It simplifies script execution, environment management, and task dependencies, positioning itself as a great asset in modern development environments.\n", + "\n", + "## Introducing Makim\n", + "\n", + "`Makim` elevates project automation by offering a structured, yet flexible approach to manage routine tasks, complex task dependencies, and environment configurations. Its design is centered around the `.makim.yaml` configuration file, allowing developers to orchestrate their workflows with precision and ease. Unlike traditional script execution tools, Makim's Python-based architecture and support for multiple programming languages and shells enhance its versatility and applicability across diverse projects.\n", + "\n", + "Especially suited for DevOps Engineers and Software Developers, Makim eliminates redundancy in automation tasks. Its core functionality extends beyond simple script execution, encompassing:\n", + "\n", + "- Argument definition for scripts\n", + "- Organization of tasks into groups\n", + "- Advanced dependency management between tasks\n", + "- Utilization of environment variables and custom variables\n", + "- Dynamic content generation with Jinja2 templates\n", + "- Specification of working directories for tasks\n", + "- Execution flexibility through support for multiple interpreters or shells\n", + "\n", + "Despite its broad capabilities, Makim currently lacks support for Windows but plans to extend its compatibility in future versions.\n", + "\n", + "## Getting Started with Makim\n", + "\n", + "### Installation\n", + "\n", + "Makim can be installed via `pip` or `conda`, catering to different setup preferences:\n", + "\n", + "- To install `Makim` using `pip`, run:" + ] + }, + { + "cell_type": "markdown", + "id": "1fe3269a-a947-4b45-9d5e-0dcdd8e0f60d", + "metadata": {}, + "source": [ + "```bash\n", + "pip install -q \"makim==1.15.0\"\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "b0af5f25-4807-4637-9036-62fa6f894bef", + "metadata": {}, + "source": [ + "- For those who prefer `conda`, execute:\n", + "\n", + " ```bash\n", + " conda install \"makim==1.15.0\"\n", + " ```\n", + "\n", + "Given Makim's active development, pinning to a specific version is recommended to ensure consistency.\n", + "\n", + "For this tutorial, we will disable the output color feature provided by typer, the command-line interface engine used by **Makim**." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "e6f6a633-79e3-4690-928b-4e74b725c83c", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "os.environ[\"NO_COLOR\"] = \"1\"" + ] + }, + { + "cell_type": "markdown", + "id": "4ff221f5-e18b-4b0b-bbb5-4cd8547bf35a", + "metadata": {}, + "source": [ + "### Configuring `.makim.yaml`\n", + "\n", + "The `.makim.yaml` file is the foundation of your Makim configuration. Here's how to start:\n", + "\n", + "1. **Create the `.makim.yaml` File**: Place this file at the root of your project directory.\n", + " \n", + "2. **Define Your Automation Tasks**: Configure your tasks, specifying actions, arguments, and dependencies. For example:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "dd79bbd0-73db-4d25-ae06-a143aef3b8e1", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Overwriting .makim.yaml\n" + ] + } + ], + "source": [ + "%%writefile .makim.yaml\n", + "version: 1.0.0\n", + "groups:\n", + " clean:\n", + " env-file: .env\n", + " targets:\n", + " tmp:\n", + " help: Use this target to clean up temporary files\n", + " run: |\n", + " echo \"Cleaning up...\"\n", + " tests:\n", + " targets:\n", + " unit:\n", + " help: Build the program\n", + " args:\n", + " clean:\n", + " type: bool\n", + " action: store_true\n", + " help: if not set, the clean dependency will not be triggered.\n", + " dependencies:\n", + " - target: clean.tmp\n", + " if: ${{ args.clean == true }}\n", + " run: |\n", + " echo \"Runnint unit tests...\"" + ] + }, + { + "cell_type": "markdown", + "id": "7bb49d00-0f25-4679-97ce-2bd2ecfa6e3c", + "metadata": {}, + "source": [ + "This setup demonstrates Makim's ability to manage tasks with conditional logic and dependencies.\n", + "\n", + "### Exploring Makim's CLI\n", + "\n", + "Makim's CLI provides insights into available commands, arguments, and configurations through the auto-generated help menu:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "5e17c7ab-a183-40d9-bc1a-96ff8be6a91b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[1m \u001b[0m\n", + "\u001b[1m \u001b[0m\u001b[1mUsage: \u001b[0m\u001b[1mmakim [OPTIONS] COMMAND [ARGS]...\u001b[0m\u001b[1m \u001b[0m\u001b[1m \u001b[0m\n", + "\u001b[1m \u001b[0m\n", + " Makim is a tool that helps you to organize and simplify your helper commands. \n", + " \n", + "\u001b[2m╭─\u001b[0m\u001b[2m Options \u001b[0m\u001b[2m───────────────────────────────────────────────────────────────────\u001b[0m\u001b[2m─╮\u001b[0m\n", + "\u001b[2m│\u001b[0m \u001b[1m-\u001b[0m\u001b[1m-version\u001b[0m \u001b[1m-v\u001b[0m \u001b[1m \u001b[0m Show the version and exit \u001b[2m│\u001b[0m\n", + "\u001b[2m│\u001b[0m \u001b[1m-\u001b[0m\u001b[1m-file\u001b[0m \u001b[1mTEXT\u001b[0m Makim config file \u001b[2m[default: .makim.yaml]\u001b[0m \u001b[2m│\u001b[0m\n", + "\u001b[2m│\u001b[0m \u001b[1m-\u001b[0m\u001b[1m-dry\u001b[0m\u001b[1m-run\u001b[0m \u001b[1m \u001b[0m Execute the command in dry mode \u001b[2m│\u001b[0m\n", + "\u001b[2m│\u001b[0m \u001b[1m-\u001b[0m\u001b[1m-verbose\u001b[0m \u001b[1m \u001b[0m Execute the command in verbose mode \u001b[2m│\u001b[0m\n", + "\u001b[2m│\u001b[0m \u001b[1m-\u001b[0m\u001b[1m-install\u001b[0m\u001b[1m-completion\u001b[0m \u001b[1m \u001b[0m Install completion for the current \u001b[2m│\u001b[0m\n", + "\u001b[2m│\u001b[0m shell. \u001b[2m│\u001b[0m\n", + "\u001b[2m│\u001b[0m \u001b[1m-\u001b[0m\u001b[1m-show\u001b[0m\u001b[1m-completion\u001b[0m \u001b[1m \u001b[0m Show completion for the current shell, \u001b[2m│\u001b[0m\n", + "\u001b[2m│\u001b[0m to copy it or customize the \u001b[2m│\u001b[0m\n", + "\u001b[2m│\u001b[0m installation. \u001b[2m│\u001b[0m\n", + "\u001b[2m│\u001b[0m \u001b[1m-\u001b[0m\u001b[1m-help\u001b[0m \u001b[1m \u001b[0m Show this message and exit. \u001b[2m│\u001b[0m\n", + "\u001b[2m╰──────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n", + "\u001b[2m╭─\u001b[0m\u001b[2m Commands \u001b[0m\u001b[2m──────────────────────────────────────────────────────────────────\u001b[0m\u001b[2m─╮\u001b[0m\n", + "\u001b[2m│\u001b[0m \u001b[1mclean.tmp \u001b[0m\u001b[1m \u001b[0m Use this target to clean up temporary files \u001b[2m│\u001b[0m\n", + "\u001b[2m│\u001b[0m \u001b[1mtests.unit \u001b[0m\u001b[1m \u001b[0m Build the program \u001b[2m│\u001b[0m\n", + "\u001b[2m╰──────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n", + " \n", + " If you have any problem, open an issue at: \n", + " https://github.com/osl-incubator/makim \n", + " \n", + "\n" + ] + } + ], + "source": [ + "!makim --help" + ] + }, + { + "cell_type": "markdown", + "id": "be6b96d3-79f8-48e2-8e9e-edeb38a4dc58", + "metadata": {}, + "source": [ + "This feature facilitates easy access to Makim's functionalities, enhancing usability and understanding of the tool.\n", + "\n", + "### Executing Your First Commands\n", + "\n", + "With your `.makim.yaml` file set up, you can begin to use `makim`:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "535b89a1-cb6c-48ce-b4d3-2a9296c97f2b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Makim file: .makim.yaml\n", + "Cleaning up...\n" + ] + } + ], + "source": [ + "!makim clean.tmp" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "6c997aeb-eed5-4801-8bfb-dad26bb72dcb", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Makim file: .makim.yaml\n", + "Runnint unit tests...\n" + ] + } + ], + "source": [ + "!makim tests.unit" + ] + }, + { + "cell_type": "markdown", + "id": "48ed3970-3854-49cb-8109-53a38a72d8d4", + "metadata": {}, + "source": [ + "In the case you type your command wrong, **Makim** will suggest you some alternative:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "800ad2a4-0c45-4b1a-b4ef-927ab1230e60", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Usage: makim [OPTIONS] COMMAND [ARGS]...\n", + "\u001b[2mTry \u001b[0m\u001b[2m'makim \u001b[0m\u001b[1;2m-\u001b[0m\u001b[1;2m-help\u001b[0m\u001b[2m'\u001b[0m\u001b[2m for help.\u001b[0m\n", + "╭─ Error ──────────────────────────────────────────────────────────────────────╮\n", + "│ No such command 'tests.unittest'. │\n", + "╰──────────────────────────────────────────────────────────────────────────────╯\n", + "\u001b[31mCommand tests.unittest not found. Did you mean tests.unit'?\u001b[0m\n" + ] + } + ], + "source": [ + "!makim tests.unittest" + ] + }, + { + "cell_type": "markdown", + "id": "aae58d63-d028-47b1-a57e-fb21fc3f9216", + "metadata": {}, + "source": [ + "**Makim** CLI is empowered by **Typer**, and it allows us to have auto-completion for Makim groups and targets! If you want to install, you can run the following command:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "5839d8fb-0a4c-43bf-8b11-1a1ab36cc178", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[32mbash completion installed in /home/xmn/.bash_completions/makim.sh\u001b[0m\n", + "Completion will take effect once you restart the terminal\n" + ] + } + ], + "source": [ + "!makim --install-completion " + ] + }, + { + "cell_type": "markdown", + "id": "962a1698-31b4-4223-b08d-e065d5463bd9", + "metadata": {}, + "source": [ + "After this command you will need to restart the terminal in order to use this auto-completion feature." + ] + }, + { + "cell_type": "markdown", + "id": "2cc6ebb1-304b-4aab-b5f8-ca72289e1815", + "metadata": {}, + "source": [ + "## Advanced Features and Examples\n", + "\n", + "Makim's adaptability is showcased through various features and practical examples:\n", + "\n", + "- **Conditional Dependencies and Arguments**: Define complex task dependencies with conditional execution based on passed arguments.\n", + "- **Dynamic Configuration with Jinja2**: Leverage Jinja2 templates for advanced scripting and dynamic content generation.\n", + "- **Environment and Custom Variable Management**: Organize and utilize variables effectively across different scopes of your project.\n", + "- **Specifying Working Directories**: Control the execution context of your tasks by setting working directories.\n", + "\n", + "These examples underscore Makim's capability to accommodate intricate automation scenarios, streamlining development workflows.\n", + "\n", + "## Exploring Makim Through Examples\n", + "\n", + "### Utilizing Various Interpreters\n", + "\n", + "Makim extends its functionality beyond conventional script execution by supporting various interpreters and shell languages, facilitating a versatile development environment. While **xonsh** is the default interpreter - blending the capabilities of Bash and Python for an enriched command-line experience - Makim's architecture allows for seamless integration with other environments. For developers seeking to leverage this feature, a foundational understanding of **xonsh** can be beneficial. Comprehensive details and usage guidelines are available in the [official xonsh documentation](https://xon.sh/).\n", + "\n", + "This section demonstrates executing straightforward commands across multiple interpreters, showcasing Makim's adaptability to diverse programming contexts." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "0d942c28-d13a-4131-b5e4-113667a69c3e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Overwriting .env\n" + ] + } + ], + "source": [ + "%%writefile .env\n", + "MSG_PREFIX=\"Running Makim: Hello, World,\"" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "f68e8008-f0f1-4ead-a42e-4e524fc03c22", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Overwriting .makim.yaml\n" + ] + } + ], + "source": [ + "%%writefile .makim.yaml\n", + "version: 1.0\n", + "env-file: .env\n", + "groups:\n", + " tests:\n", + " targets:\n", + " node:\n", + " help: Test using nodejs\n", + " shell: node\n", + " run: console.log(\"${{ env.MSG_PREFIX }} from NodeJS!\");\n", + " perl:\n", + " help: Test using perl\n", + " shell: perl\n", + " run: print \"${{ env.MSG_PREFIX }} from Perl!\\n\";\n", + "\n", + " python:\n", + " help: Test using php\n", + " shell: python\n", + " run: print(\"${{ env.MSG_PREFIX }} from Python!\")\n", + "\n", + " r:\n", + " help: Test using R\n", + " shell: Rscript\n", + " run: print(\"${{ env.MSG_PREFIX }} from R!\")\n", + "\n", + " sh:\n", + " help: Test using sh\n", + " shell: sh\n", + " run: echo \"${{ env.MSG_PREFIX }} from sh!\"\n", + "\n", + " run-all:\n", + " help: Run tests for all the other targets\n", + " dependencies:\n", + " - target: node\n", + " - target: perl\n", + " - target: python\n", + " - target: r\n", + " - target: sh" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "ce809dd8-7db4-4c56-8622-ec3411bad4cf", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[1m \u001b[0m\n", + "\u001b[1m \u001b[0m\u001b[1mUsage: \u001b[0m\u001b[1mmakim [OPTIONS] COMMAND [ARGS]...\u001b[0m\u001b[1m \u001b[0m\u001b[1m \u001b[0m\n", + "\u001b[1m \u001b[0m\n", + " Makim is a tool that helps you to organize and simplify your helper commands. \n", + " \n", + "\u001b[2m╭─\u001b[0m\u001b[2m Options \u001b[0m\u001b[2m───────────────────────────────────────────────────────────────────\u001b[0m\u001b[2m─╮\u001b[0m\n", + "\u001b[2m│\u001b[0m \u001b[1m-\u001b[0m\u001b[1m-version\u001b[0m \u001b[1m-v\u001b[0m \u001b[1m \u001b[0m Show the version and exit \u001b[2m│\u001b[0m\n", + "\u001b[2m│\u001b[0m \u001b[1m-\u001b[0m\u001b[1m-file\u001b[0m \u001b[1mTEXT\u001b[0m Makim config file \u001b[2m[default: .makim.yaml]\u001b[0m \u001b[2m│\u001b[0m\n", + "\u001b[2m│\u001b[0m \u001b[1m-\u001b[0m\u001b[1m-dry\u001b[0m\u001b[1m-run\u001b[0m \u001b[1m \u001b[0m Execute the command in dry mode \u001b[2m│\u001b[0m\n", + "\u001b[2m│\u001b[0m \u001b[1m-\u001b[0m\u001b[1m-verbose\u001b[0m \u001b[1m \u001b[0m Execute the command in verbose mode \u001b[2m│\u001b[0m\n", + "\u001b[2m│\u001b[0m \u001b[1m-\u001b[0m\u001b[1m-install\u001b[0m\u001b[1m-completion\u001b[0m \u001b[1m \u001b[0m Install completion for the current \u001b[2m│\u001b[0m\n", + "\u001b[2m│\u001b[0m shell. \u001b[2m│\u001b[0m\n", + "\u001b[2m│\u001b[0m \u001b[1m-\u001b[0m\u001b[1m-show\u001b[0m\u001b[1m-completion\u001b[0m \u001b[1m \u001b[0m Show completion for the current shell, \u001b[2m│\u001b[0m\n", + "\u001b[2m│\u001b[0m to copy it or customize the \u001b[2m│\u001b[0m\n", + "\u001b[2m│\u001b[0m installation. \u001b[2m│\u001b[0m\n", + "\u001b[2m│\u001b[0m \u001b[1m-\u001b[0m\u001b[1m-help\u001b[0m \u001b[1m \u001b[0m Show this message and exit. \u001b[2m│\u001b[0m\n", + "\u001b[2m╰──────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n", + "\u001b[2m╭─\u001b[0m\u001b[2m Commands \u001b[0m\u001b[2m──────────────────────────────────────────────────────────────────\u001b[0m\u001b[2m─╮\u001b[0m\n", + "\u001b[2m│\u001b[0m \u001b[1mtests.node \u001b[0m\u001b[1m \u001b[0m Test using nodejs \u001b[2m│\u001b[0m\n", + "\u001b[2m│\u001b[0m \u001b[1mtests.perl \u001b[0m\u001b[1m \u001b[0m Test using perl \u001b[2m│\u001b[0m\n", + "\u001b[2m│\u001b[0m \u001b[1mtests.python \u001b[0m\u001b[1m \u001b[0m Test using php \u001b[2m│\u001b[0m\n", + "\u001b[2m│\u001b[0m \u001b[1mtests.r \u001b[0m\u001b[1m \u001b[0m Test using R \u001b[2m│\u001b[0m\n", + "\u001b[2m│\u001b[0m \u001b[1mtests.run-all \u001b[0m\u001b[1m \u001b[0m Run tests for all the other targets \u001b[2m│\u001b[0m\n", + "\u001b[2m│\u001b[0m \u001b[1mtests.sh \u001b[0m\u001b[1m \u001b[0m Test using sh \u001b[2m│\u001b[0m\n", + "\u001b[2m╰──────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n", + " \n", + " If you have any problem, open an issue at: \n", + " https://github.com/osl-incubator/makim \n", + " \n", + "\n" + ] + } + ], + "source": [ + "!makim --help" + ] + }, + { + "cell_type": "markdown", + "id": "14ed7f09-9bea-490d-ad3d-629ea4ee971f", + "metadata": {}, + "source": [ + "Prior to executing these targets, it is necessary to install the required dependencies:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "defb03d3-404d-489b-9990-ed66552aa341", + "metadata": {}, + "outputs": [], + "source": [ + "!mamba install -q -y perl nodejs r-base sh " + ] + }, + { + "cell_type": "markdown", + "id": "402bf345-9a18-403f-be99-e428e7c78b97", + "metadata": {}, + "source": [ + "Proceed to execute all defined targets by invoking the run-all target, which encapsulates all other targets as its dependencies for a sequential execution process:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "8f4e23ef-0238-4393-9747-8f945de40f79", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Makim file: .makim.yaml\n", + "Running Makim: Hello, World, from NodeJS!\n", + "(node:1634785) Warning: The 'NO_COLOR' env is ignored due to the 'FORCE_COLOR' env being set.\n", + "(Use `node --trace-warnings ...` to show where the warning was created)\n", + "Running Makim: Hello, World, from Perl!\n", + "Running Makim: Hello, World, from Python!\n", + "[1] \"Running Makim: Hello, World, from R!\"\n", + "Running Makim: Hello, World, from sh!\n" + ] + } + ], + "source": [ + "!makim tests.run-all" + ] + }, + { + "cell_type": "markdown", + "id": "d57e524f-9ddd-4e1e-9d90-e47154c0950d", + "metadata": {}, + "source": [ + "In scenarios where your chosen interpreter supports debugging - such as Python or Xonsh through the use of `breakpoint()` - you can introduce a breakpoint within your code. This enables the debugging of your **Makim** target, allowing for an interactive examination of the execution flow and variable states." + ] + }, + { + "cell_type": "markdown", + "id": "43d8808a-6b75-4e54-a193-4ba148de913a", + "metadata": {}, + "source": [ + "### Using Variables (vars)\n", + "\n", + "**Makim** facilitates the definition of variables within the `.makim.yaml` configuration, supporting all the **YAML** data types, including strings, lists, and dictionaries. This feature enhances script configurability and reusability across different tasks and environments.\n", + "\n", + "Consider reviewing the provided example to understand how to effectively leverage variables in your **Makim** configurations:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "ff7b4903-8caf-454b-828f-4ab6cf57d8fa", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Overwriting .makim.yaml\n" + ] + } + ], + "source": [ + "%%writefile .makim.yaml\n", + "version: 1.0\n", + "\n", + "vars:\n", + " project-name: \"my-project\"\n", + " dependencies:\n", + " \"dep1\": \"v1\"\n", + " \"dep2\": \"v1.1\"\n", + " \"dep3\": \"v2.3\"\n", + " authorized-users:\n", + " - admin1\n", + " - admin2\n", + " - admin3\n", + "\n", + "groups:\n", + " staging:\n", + " vars:\n", + " env-name: \"staging\"\n", + " staging-dependencies:\n", + " \"dep4\": \"v4.3\"\n", + " \"dep5\": \"v1.1.1\"\n", + " staging-authorized-users:\n", + " - staging1\n", + " - staging2\n", + " - staging3\n", + " targets:\n", + " create-users:\n", + " help: Create users for staging, this example uses jinja2 for loop.\n", + " # each target can also specify their `vars`, but it will not be used in this example\n", + " run: |\n", + " def create_user(username):\n", + " print(f\">>> creating user: {username} ... DONE!\")\n", + " \n", + " print(\"create admin users:\")\n", + " {% for user in vars.authorized_users %}\n", + " create_user(\"${{ user }}\")\n", + " {% endfor %}\n", + "\n", + " print(\"\\ncreate staging users:\")\n", + " {% for user in vars.staging_authorized_users %}\n", + " create_user(\"${{ user }}\")\n", + " {% endfor %}\n", + "\n", + " install:\n", + " help: install deps for staging using native xonsh `for` loop (it could work with Python as well)\n", + " # each target can also specify their `vars`, but it will not be used in this example\n", + " run: |\n", + " def install(package, version):\n", + " print(f\">>> installing: {package}@{version} ... DONE!\")\n", + " \n", + " print(\"install global dependencies:\")\n", + " for package, version in ${{ vars.dependencies | safe }}.items():\n", + " install(package, version)\n", + "\n", + " print(\"\\ninstall staging dependencies:\")\n", + " for package, version in ${{ vars.staging_dependencies | safe }}.items():\n", + " install(package, version)" + ] + }, + { + "cell_type": "markdown", + "id": "2b67905e-2e5b-4d54-bee8-eadcfe12cd66", + "metadata": {}, + "source": [ + "Now, let's proceed to create users within the staging environment:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "89f4ea8e-b58e-4da3-9097-61deaf5e6c70", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Makim file: .makim.yaml\n", + "create admin users:\n", + ">>> creating user: admin1 ... DONE!\n", + ">>> creating user: admin2 ... DONE!\n", + ">>> creating user: admin3 ... DONE!\n", + "\n", + "create staging users:\n", + ">>> creating user: staging1 ... DONE!\n", + ">>> creating user: staging2 ... DONE!\n", + ">>> creating user: staging3 ... DONE!\n" + ] + } + ], + "source": [ + "!makim staging.create-users" + ] + }, + { + "cell_type": "markdown", + "id": "cd07e3af-4527-4530-952e-01848701e185", + "metadata": {}, + "source": [ + "Last but not least, let's run the install target:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "2eb7291c-610a-427c-a970-bb923b17678e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Makim file: .makim.yaml\n", + "install global dependencies:\n", + ">>> installing: dep1@v1 ... DONE!\n", + ">>> installing: dep2@v1.1 ... DONE!\n", + ">>> installing: dep3@v2.3 ... DONE!\n", + "\n", + "install staging dependencies:\n", + ">>> installing: dep4@v4.3 ... DONE!\n", + ">>> installing: dep5@v1.1.1 ... DONE!\n" + ] + } + ], + "source": [ + "!makim staging.install" + ] + }, + { + "cell_type": "markdown", + "id": "fcfc9258-a97d-4378-9cbb-e1be2678c801", + "metadata": {}, + "source": [ + "### Defining Arguments\n", + "\n", + "**Makim** enhances script flexibility by allowing the use of arguments. It enables not only the definition of arguments for tasks but also the passing of arguments to dependencies and the specification of conditions for those dependencies.\n", + "\n", + "Explore this functionality through this example:" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "cb5c198b-4644-4e92-b1a4-cc66c55fc29d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Overwriting .makim.yaml\n" + ] + } + ], + "source": [ + "%%writefile .makim.yaml\n", + "version: 1.0.0\n", + "groups:\n", + " print:\n", + " env-file: .env\n", + " targets:\n", + " name:\n", + " help: Print given name\n", + " args:\n", + " name:\n", + " type: str\n", + " required: true\n", + " run: print(\"${{ args.name }}\")\n", + " list:\n", + " help: Build the program\n", + " args:\n", + " i-am-sure:\n", + " type: bool\n", + " dependencies:\n", + " - target: print.name\n", + " if: ${{ args.i_am_sure == true }}\n", + " args:\n", + " name: Mary\n", + " - target: print.name\n", + " if: ${{ args.i_am_sure == true }}\n", + " args:\n", + " name: John\n", + " - target: print.name\n", + " if: ${{ args.i_am_sure == true }}\n", + " args:\n", + " name: Ellen\n", + " - target: print.name\n", + " if: ${{ args.i_am_sure == true }}\n", + " args:\n", + " name: Marc" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "551d69e9-d074-4b70-b868-f7e9fa6faba6", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Makim file: .makim.yaml\n" + ] + } + ], + "source": [ + "!makim print.list" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "dfe7b8ba-f438-4f62-88fc-e99e11a15bee", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Makim file: .makim.yaml\n", + "Mary\n", + "John\n", + "Ellen\n", + "Marc\n" + ] + } + ], + "source": [ + "!makim print.list --i-am-sure" + ] + }, + { + "cell_type": "markdown", + "id": "5f7c72db-31d6-47f5-a8aa-932f3e5bf2a7", + "metadata": {}, + "source": [ + "### Utilizing Environment Variables\n", + "\n", + "The previous sections demonstrated the use of environment variables. Here, we'll delve into their application in more detail.\n", + "\n", + "**Makim** permits the incorporation of environment variables from `.env` files or directly within the `.makim.yaml` file, applicable at global, group, and target levels.\n", + "\n", + "Examine an example to understand the implementation:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "6e0c4c5a-ef21-43e0-ac18-40672850b93a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Overwriting .env\n" + ] + } + ], + "source": [ + "%%writefile .env\n", + "ENV=dev" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "678192e5-7af3-4862-bc76-4beecf030bd2", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Overwriting .makim.yaml\n" + ] + } + ], + "source": [ + "%%writefile .makim.yaml\n", + "version: 1.0\n", + "env-file: .env\n", + "env:\n", + " GLOBAL_VAR: \"1\"\n", + "groups:\n", + " global-scope:\n", + " env:\n", + " GROUP_VAR: \"2\"\n", + " targets:\n", + " test-var-env-file:\n", + " help: Test env variable defined in the global scope from env-file\n", + " run: |\n", + " import os\n", + " assert str(os.getenv(\"ENV\")) == \"dev\"\n", + "\n", + " test-var-env:\n", + " help: Test env variable defined in the global scope in `env` section\n", + " env:\n", + " TARGET_VAR: \"3\"\n", + " run: |\n", + " import os\n", + " # you can get an environment variable directly with xonsh/python\n", + " assert str(os.getenv(\"GLOBAL_VAR\")) == \"1\"\n", + " # or you can get an environment variable using jinja2 tag\n", + " assert \"${{ env.GROUP_VAR }}\" == \"2\"\n", + " assert \"${{ env.get(\"TARGET_VAR\") }}\" == \"3\"\n", + " assert \"${{ env.get(\"UNKNOWN_TARGET_VAR\", \"4\") }}\" == \"4\"" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "6221cfec-19b5-450e-853e-737ce0ed024f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Makim file: .makim.yaml\n" + ] + } + ], + "source": [ + "!makim global-scope.test-var-env-file" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "548a68cf-b597-4eb9-8438-eb97729dcb46", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Makim file: .makim.yaml\n" + ] + } + ], + "source": [ + "!makim global-scope.test-var-env" + ] + }, + { + "cell_type": "markdown", + "id": "ce5e09d7-bf8b-4b0e-9127-48958ee79601", + "metadata": {}, + "source": [ + "### Specifying the Working Directory\n", + "\n", + "Makim provides the capability to set a specific working directory for tasks at any scope: global, group, or target.\n", + "\n", + "Review a straightforward example to learn how to apply this feature:" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "65335daf-ac06-497c-a0f8-6dbb9f5a570b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Overwriting .makim.yaml\n" + ] + } + ], + "source": [ + "%%writefile .makim.yaml\n", + "version: 1.0\n", + "working-directory: \"/tmp\"\n", + "\n", + "groups:\n", + " check-wd:\n", + " targets:\n", + " is-tmp:\n", + " help: Test if working directory is `tmp`\n", + " run: |\n", + " import os\n", + " print(os.getcwd())\n", + " assert os.getcwd() == \"/tmp\"" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "0938bcee-26fb-4028-82f6-bbed8453eba7", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Makim file: .makim.yaml\n", + "/tmp\n" + ] + } + ], + "source": [ + "!makim check-wd.is-tmp" + ] + }, + { + "cell_type": "markdown", + "id": "ae987426-9ead-4375-bddf-b5ded48aeb1a", + "metadata": {}, + "source": [ + "This tutorial concludes with a showcase of Makim's key features. While this overview covers the essentials, diving deeper into **Makim** will reveal more advanced and intriguing ways to leverage its capabilities." + ] + }, + { + "cell_type": "markdown", + "id": "a5f5fb97-503f-4a3b-92a7-8ecef4d9687c", + "metadata": {}, + "source": [ + "## Contributing to Makim\n", + "\n", + "Makim's growth is propelled by its community. Contributions, whether through code, documentation, or feedback, are welcome. Explore the [GitHub repository](https://github.com/osl-incubator/makim) and consider contributing to foster Makim's development." + ] + }, + { + "cell_type": "markdown", + "id": "822a5ed4-6941-4761-9a7b-9910dd075849", + "metadata": {}, + "source": [ + "## Conclusion\n", + "\n", + "Makim stands out as a transformative tool in project automation, bridging the gap between simplicity and complexity. Its comprehensive feature set, coupled with the flexibility of its configuration, makes Makim a quintessential tool for developers and DevOps engineers alike. As you incorporate Makim into your projects, its impact on enhancing productivity and consistency will become evident, marking it as an indispensable part of your development toolkit.\n", + "\n", + "Dive deeper into Makim's functionalities by visiting the [official documentation](https://osl-incubator.github.io/makim). Try it and let us know your thoughts about it!" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.1" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/tutorials/makim-for-nox-users/.makim.yaml b/docs/tutorials/makim-for-nox-users/.makim.yaml new file mode 100644 index 0000000..154bf2c --- /dev/null +++ b/docs/tutorials/makim-for-nox-users/.makim.yaml @@ -0,0 +1,33 @@ +version: 1.0 +groups: + nox: + help: A set of functionality ported from noxfile.py + targets: + tests: + help: Run nox tests + shell: nox + run: | + import nox + + @nox.session(name="custom-name") + def tests(session: nox.Session) -> None: + """Run tests with pytest.""" + session.install("pytest") + session.run("pytest", "--version") + lint: + help: Run nox tests + shell: nox + run: | + import nox + + @nox.session + def lint(session: nox.Session): + """Run linters on the codebase.""" + session.install('flake8') + session.run('flake8', '--version') + + all: + help: Run nox tests + dependencies: + - target: nox.tests + - target: nox.lint diff --git a/docs/tutorials/makim-for-nox-users/index.ipynb b/docs/tutorials/makim-for-nox-users/index.ipynb new file mode 100644 index 0000000..b2ef810 --- /dev/null +++ b/docs/tutorials/makim-for-nox-users/index.ipynb @@ -0,0 +1,759 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "d90d4221-b1e8-4d69-bfd9-78acb2eae418", + "metadata": {}, + "source": [ + "# Makim for Nox Users" + ] + }, + { + "cell_type": "markdown", + "id": "37f74f2c-964d-424f-bc23-4d12930ad1f0", + "metadata": {}, + "source": [ + "For those familiar with Nox, a command-line automation tool designed for testing across multiple Python environments, Makim presents a flexible alternative. While both tools serve automation purposes, they differ in configuration approach and scope." + ] + }, + { + "cell_type": "markdown", + "id": "0840e02a-6cd3-463a-a793-32263d6fce3f", + "metadata": {}, + "source": [ + "Makim is not designed to supersede Nox or facilitate direct integration with it. The purpose of this guide is to highlight both the similarities and differences between the two tools, and to explore possible ways to integrate Nox tasks (sessions) within the Makim." + ] + }, + { + "cell_type": "markdown", + "id": "804b54d3-5518-44af-bdb8-284caf4e0f3a", + "metadata": {}, + "source": [ + "## Initial Setup" + ] + }, + { + "cell_type": "markdown", + "id": "7e1194e6-a774-4c01-ab6e-460d4669822b", + "metadata": {}, + "source": [ + "To begin, ensure Nox is installed in your environment:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "e348f105-6471-44e1-8a7e-3323825d0e20", + "metadata": {}, + "outputs": [], + "source": [ + "!pip install -q nox" + ] + }, + { + "cell_type": "markdown", + "id": "f27b56f8-06a6-41a2-9c98-b2c25dbc609c", + "metadata": {}, + "source": [ + "## Transitioning from Nox to Makim" + ] + }, + { + "cell_type": "markdown", + "id": "3b60cb09-a540-49b7-a6b7-236ae6f0afa9", + "metadata": {}, + "source": [ + "Though Makim is not a direct replacement for Nox, understanding their similarities and differences can streamline the transition process for specific tasks or workflows. Consider the following Nox configuration:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "5b323b60-0d51-4386-8b6c-3fab40692147", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Overwriting noxfile.py\n" + ] + } + ], + "source": [ + "%%writefile noxfile.py\n", + "import nox\n", + "\n", + "@nox.session(name=\"custom-name\")\n", + "def tests(session: nox.Session) -> None:\n", + " \"\"\"Run tests with pytest.\"\"\"\n", + " session.install(\"pytest\")\n", + " session.run(\"pytest\", \"--version\")\n", + "\n", + "@nox.session\n", + "def lint(session: nox.Session):\n", + " \"\"\"Run linters on the codebase.\"\"\"\n", + " session.install('flake8')\n", + " # Example of using session.posargs for ad-hoc arguments\n", + " additional_args = session.posargs or []\n", + " session.run('flake8', '--version', *additional_args)" + ] + }, + { + "cell_type": "markdown", + "id": "8981f1fe-8f61-4947-8086-c2fde7c870de", + "metadata": {}, + "source": [ + "In this example, we are using `--version` with `pytest` and `flake8` just to check if everything is working properly. In a real code, it should execute directly `pytest` and `flake8`." + ] + }, + { + "cell_type": "markdown", + "id": "04a718cf-4f1a-43d3-96df-66d259e2418e", + "metadata": {}, + "source": [ + "Let's check how the **nox** list output (similar to a help output) would look like:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "03f594bb-6723-451c-a518-8cfa9751f543", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Sessions defined in /mnt/sda1/storage/dev/opensciencelabs-projects/osl-incubator/makim/docs/tutorials/noxfile.py:\n", + "\n", + "* \u001b[36mcustom-name\u001b[0m -> Run tests with pytest.\n", + "* \u001b[36mlint\u001b[0m -> Run linters on the codebase.\n", + "\n", + "sessions marked with \u001b[36m*\u001b[0m are selected, sessions marked with \u001b[37m-\u001b[0m are skipped.\n" + ] + } + ], + "source": [ + "!nox --list" + ] + }, + { + "cell_type": "markdown", + "id": "c5440c86-20e0-4099-90ea-df9b9176f609", + "metadata": {}, + "source": [ + "**NOTE:** It appears that Nox does not offer a built-in, first-class method for displaying the arguments used by each Nox session." + ] + }, + { + "cell_type": "markdown", + "id": "fc86d486-8446-4bfc-9291-5d939fde8b47", + "metadata": {}, + "source": [ + "We can also verify that the command functions as expected:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "31e16c49-0158-4ecb-875b-46662e0cfc2d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[36mnox > \u001b[33mRunning session custom-name\u001b[0m\n", + "\u001b[36mnox > \u001b[34mCreating virtual environment (virtualenv) using python3.8 in .nox/custom-name\u001b[0m\n", + "\u001b[36mnox > \u001b[34mpython -m pip install pytest\u001b[0m\n", + "\u001b[36mnox > \u001b[34mpytest --version\u001b[0m\n", + "pytest 8.1.1\n", + "\u001b[36mnox > \u001b[32mSession custom-name was successful.\u001b[0m\n", + "\u001b[36mnox > \u001b[33mRunning session lint\u001b[0m\n", + "\u001b[36mnox > \u001b[34mCreating virtual environment (virtualenv) using python3.8 in .nox/lint\u001b[0m\n", + "\u001b[36mnox > \u001b[34mpython -m pip install flake8\u001b[0m\n", + "\u001b[36mnox > \u001b[34mflake8 --version\u001b[0m\n", + "7.0.0 (mccabe: 0.7.0, pycodestyle: 2.11.1, pyflakes: 3.2.0) CPython 3.8.1 on\n", + "Linux\n", + "\u001b[36mnox > \u001b[32mSession lint was successful.\u001b[0m\n", + "\u001b[36mnox > \u001b[33mRan multiple sessions:\u001b[0m\n", + "\u001b[36mnox > \u001b[32m* custom-name: success\u001b[0m\n", + "\u001b[36mnox > \u001b[32m* lint: success\u001b[0m\n" + ] + } + ], + "source": [ + "!nox" + ] + }, + { + "cell_type": "markdown", + "id": "d50d4a71-02e7-4a57-9232-1f82211e4758", + "metadata": {}, + "source": [ + "It is working as expected!" + ] + }, + { + "cell_type": "markdown", + "id": "3dbb0585-390c-442d-98a8-cb95902ad005", + "metadata": {}, + "source": [ + "To replicate this functionality in Makim, you would use a `.makim.yaml` configuration file:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "e9d779b8-9f04-43db-bb61-84ad57f4ce46", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Overwriting .makim.yaml\n" + ] + } + ], + "source": [ + "%%writefile .makim.yaml\n", + "version: 1.0\n", + "groups:\n", + " nox:\n", + " help: A set of functionality ported from noxfile.py\n", + " targets:\n", + " tests:\n", + " help: Run tests with pytest\n", + " run: |\n", + " pytest --version\n", + " lint:\n", + " help: Run lint with flake8\n", + " args:\n", + " extras:\n", + " help: Extra arguments for flake8\n", + " type: string\n", + " default: \"--version\"\n", + " run: |\n", + " flake8 ${{ args.extras }}" + ] + }, + { + "cell_type": "markdown", + "id": "a9ea9d53-9e32-4dcf-827d-a02164b05cc6", + "metadata": {}, + "source": [ + "This example illustrates how to define similar testing and linting tasks within Makim's YAML-based configuration." + ] + }, + { + "cell_type": "markdown", + "id": "26cc514a-2568-494e-8168-99c2a0c0f0aa", + "metadata": {}, + "source": [ + "The default configuration file used by **makim** is `.makim.yaml`, but if you want a different file name, you can run `makim` with the flag `--file`." + ] + }, + { + "cell_type": "markdown", + "id": "524e4342-8e9a-4b05-a786-3c639d888c67", + "metadata": {}, + "source": [ + "As you can see, it didn't install anything, because it assumes you already have all the dependencies there." + ] + }, + { + "cell_type": "markdown", + "id": "65b28996-3e8b-4ecf-918f-ce9cd132ce13", + "metadata": {}, + "source": [ + "Of course, you can install whatever you want inside the Makim `run` block, but it is much better to keep it in your pyproject.toml configuration." + ] + }, + { + "cell_type": "markdown", + "id": "9e2c51ea-89ab-4689-8e8e-e1e4514034d0", + "metadata": {}, + "source": [ + "In the future, **makim** will allow users to define specific virtual environments that could be used in a similar way as **nox**." + ] + }, + { + "cell_type": "markdown", + "id": "c03abb65-a439-48d6-a5dd-2d1bc7c955f3", + "metadata": {}, + "source": [ + "**NOTE**: This tutorial used **makim** version **1.15.0**. The version `1.*` is still a beta version, so you maybe will find differences with future versions." + ] + }, + { + "cell_type": "markdown", + "id": "1e563e09-31fe-4d55-92df-b2ddb02008c1", + "metadata": {}, + "source": [ + "Before running the `makim` command, please install it in your virtual environment: `pip install \"makim==1.15.0\"`." + ] + }, + { + "cell_type": "markdown", + "id": "bb7d6db7-1f05-43b2-90fc-c0a284840af3", + "metadata": {}, + "source": [ + "First, let's check how the **makim** `help` menu looks like:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "7e3ed6c4-81d2-4f83-a0c9-91f5c6133b9f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[1m \u001b[0m\n", + "\u001b[1m \u001b[0m\u001b[1;33mUsage: \u001b[0m\u001b[1mmakim [OPTIONS] COMMAND [ARGS]...\u001b[0m\u001b[1m \u001b[0m\u001b[1m \u001b[0m\n", + "\u001b[1m \u001b[0m\n", + " Makim is a tool that helps you to organize and simplify your helper commands. \n", + " \n", + "\u001b[2m╭─\u001b[0m\u001b[2m Options \u001b[0m\u001b[2m───────────────────────────────────────────────────────────────────\u001b[0m\u001b[2m─╮\u001b[0m\n", + "\u001b[2m│\u001b[0m \u001b[1;36m-\u001b[0m\u001b[1;36m-version\u001b[0m \u001b[1;32m-v\u001b[0m \u001b[1;33m \u001b[0m Show the version and exit \u001b[2m│\u001b[0m\n", + "\u001b[2m│\u001b[0m \u001b[1;36m-\u001b[0m\u001b[1;36m-file\u001b[0m \u001b[1;33mTEXT\u001b[0m Makim config file \u001b[2m[default: .makim.yaml]\u001b[0m \u001b[2m│\u001b[0m\n", + "\u001b[2m│\u001b[0m \u001b[1;36m-\u001b[0m\u001b[1;36m-dry\u001b[0m\u001b[1;36m-run\u001b[0m \u001b[1;33m \u001b[0m Execute the command in dry mode \u001b[2m│\u001b[0m\n", + "\u001b[2m│\u001b[0m \u001b[1;36m-\u001b[0m\u001b[1;36m-verbose\u001b[0m \u001b[1;33m \u001b[0m Execute the command in verbose mode \u001b[2m│\u001b[0m\n", + "\u001b[2m│\u001b[0m \u001b[1;36m-\u001b[0m\u001b[1;36m-install\u001b[0m\u001b[1;36m-completion\u001b[0m \u001b[1;33m \u001b[0m Install completion for the current \u001b[2m│\u001b[0m\n", + "\u001b[2m│\u001b[0m shell. \u001b[2m│\u001b[0m\n", + "\u001b[2m│\u001b[0m \u001b[1;36m-\u001b[0m\u001b[1;36m-show\u001b[0m\u001b[1;36m-completion\u001b[0m \u001b[1;33m \u001b[0m Show completion for the current shell, \u001b[2m│\u001b[0m\n", + "\u001b[2m│\u001b[0m to copy it or customize the \u001b[2m│\u001b[0m\n", + "\u001b[2m│\u001b[0m installation. \u001b[2m│\u001b[0m\n", + "\u001b[2m│\u001b[0m \u001b[1;36m-\u001b[0m\u001b[1;36m-help\u001b[0m \u001b[1;33m \u001b[0m Show this message and exit. \u001b[2m│\u001b[0m\n", + "\u001b[2m╰──────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n", + "\u001b[2m╭─\u001b[0m\u001b[2m Commands \u001b[0m\u001b[2m──────────────────────────────────────────────────────────────────\u001b[0m\u001b[2m─╮\u001b[0m\n", + "\u001b[2m│\u001b[0m \u001b[1;36mnox.lint \u001b[0m\u001b[1;36m \u001b[0m Run lint with flake8 \u001b[2m│\u001b[0m\n", + "\u001b[2m│\u001b[0m \u001b[1;36mnox.tests \u001b[0m\u001b[1;36m \u001b[0m Run tests with pytest \u001b[2m│\u001b[0m\n", + "\u001b[2m╰──────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n", + " \n", + " If you have any problem, open an issue at: \n", + " https://github.com/osl-incubator/makim \n", + " \n", + "\n" + ] + } + ], + "source": [ + "!makim --help" + ] + }, + { + "cell_type": "markdown", + "id": "3c765dac-1916-427f-903d-dda910cdafdf", + "metadata": {}, + "source": [ + "And if you want to check more details about a specific _command_:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "48756fb4-f6d3-4bfe-aba1-a1429bf06d7f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Makim file: .makim.yaml\n", + "\u001b[1m \u001b[0m\n", + "\u001b[1m \u001b[0m\u001b[1;33mUsage: \u001b[0m\u001b[1mmakim nox.lint [OPTIONS]\u001b[0m\u001b[1m \u001b[0m\u001b[1m \u001b[0m\n", + "\u001b[1m \u001b[0m\n", + " Run lint with flake8 \n", + " \n", + "\u001b[2m╭─\u001b[0m\u001b[2m Options \u001b[0m\u001b[2m───────────────────────────────────────────────────────────────────\u001b[0m\u001b[2m─╮\u001b[0m\n", + "\u001b[2m│\u001b[0m \u001b[1;36m-\u001b[0m\u001b[1;36m-extras\u001b[0m \u001b[1;33mTEXT\u001b[0m Extra arguments for flake8 \u001b[2m[default: --version]\u001b[0m \u001b[2m│\u001b[0m\n", + "\u001b[2m│\u001b[0m \u001b[1;36m-\u001b[0m\u001b[1;36m-help\u001b[0m \u001b[1;33m \u001b[0m Show this message and exit. \u001b[2m│\u001b[0m\n", + "\u001b[2m╰──────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n", + "\n" + ] + } + ], + "source": [ + "!makim nox.lint --help" + ] + }, + { + "cell_type": "markdown", + "id": "d31aacde-0402-441c-9c18-db5c4091cea9", + "metadata": {}, + "source": [ + "As you can see, it shows information about all the possible arguments for each _command_." + ] + }, + { + "cell_type": "markdown", + "id": "33ab0158-8495-40f9-81b9-69b74d284622", + "metadata": {}, + "source": [ + "## Understanding Makim's Approach" + ] + }, + { + "cell_type": "markdown", + "id": "cc82d6e4-8fad-47af-ad76-d7101265d61a", + "metadata": {}, + "source": [ + "Makim enhances the automation process by focusing on direct command execution within predefined environments. Unlike Nox, which creates and manages virtual environments, Makim assumes dependencies are already installed, streamlining its operations." + ] + }, + { + "cell_type": "markdown", + "id": "4e3b55cc-82ef-4735-b622-a43bca89db96", + "metadata": {}, + "source": [ + "Future versions of Makim plan to introduce more advanced virtual environment management, potentially aligning closer with Nox's functionality." + ] + }, + { + "cell_type": "markdown", + "id": "0274790f-71bf-4f9e-bdd6-152aa69f8124", + "metadata": {}, + "source": [ + "For more information about **Makim**, please read the [**Introduction**](../introduction/) tutorial." + ] + }, + { + "cell_type": "markdown", + "id": "77bce63e-3726-4dd5-a591-252d6eeef02a", + "metadata": {}, + "source": [ + "## Integrating Nox within Makim" + ] + }, + { + "cell_type": "markdown", + "id": "60c5c2b2-6d51-4d12-82ed-13d678d4d37e", + "metadata": {}, + "source": [ + "While using Nox directly within a `.makim.yaml` file might seem redundant, it demonstrates Makim's flexibility in accommodating various tools and workflows:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "7854491e-79ba-4d83-aefd-59a67f79c1f0", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Overwriting .makim.yaml\n" + ] + } + ], + "source": [ + "%%writefile .makim.yaml\n", + "version: 1.0\n", + "groups:\n", + " nox:\n", + " help: A set of functionality ported from noxfile.py\n", + " targets:\n", + " run:\n", + " help: Run nox\n", + " args:\n", + " \"ex\":\n", + " help: Extra arguments for nox\n", + " type: string\n", + " default: \"\"\n", + " run: |\n", + " nox ${{ args.ex }}" + ] + }, + { + "cell_type": "markdown", + "id": "6d66216e-f35a-4fba-9d50-d3b783e89efe", + "metadata": {}, + "source": [ + "This configuration allows for the execution of Nox sessions through Makim, providing an extra layer of automation convenience." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "5873e33c-4d4a-4d5c-8a3f-f53424542dac", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Makim file: .makim.yaml\n", + "\u001b[36mnox > \u001b[33mRunning session custom-name\u001b[0m\n", + "\u001b[36mnox > \u001b[34mCreating virtual environment (virtualenv) using python3.8 in .nox/custom-name\u001b[0m\n", + "\u001b[36mnox > \u001b[34mpython -m pip install pytest\u001b[0m\n", + "\u001b[36mnox > \u001b[34mpytest --version\u001b[0m\n", + "pytest 8.1.1\n", + "\u001b[36mnox > \u001b[32mSession custom-name was successful.\u001b[0m\n", + "\u001b[36mnox > \u001b[33mRunning session lint\u001b[0m\n", + "\u001b[36mnox > \u001b[34mCreating virtual environment (virtualenv) using python3.8 in .nox/lint\u001b[0m\n", + "\u001b[36mnox > \u001b[34mpython -m pip install flake8\u001b[0m\n", + "\u001b[36mnox > \u001b[34mflake8 --version\u001b[0m\n", + "7.0.0 (mccabe: 0.7.0, pycodestyle: 2.11.1, pyflakes: 3.2.0) CPython 3.8.1 on\n", + "Linux\n", + "\u001b[36mnox > \u001b[32mSession lint was successful.\u001b[0m\n", + "\u001b[36mnox > \u001b[33mRan multiple sessions:\u001b[0m\n", + "\u001b[36mnox > \u001b[32m* custom-name: success\u001b[0m\n", + "\u001b[36mnox > \u001b[32m* lint: success\u001b[0m\n" + ] + } + ], + "source": [ + "!makim nox.run" + ] + }, + { + "cell_type": "markdown", + "id": "a5a44f3f-45f3-4f75-9b32-33fb724e1461", + "metadata": {}, + "source": [ + "You can also run a specific **nox** session:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "7c105693-8e0d-48ee-999d-9542f65e5092", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Makim file: .makim.yaml\n", + "\u001b[36mnox > \u001b[33mRunning session lint\u001b[0m\n", + "\u001b[36mnox > \u001b[34mCreating virtual environment (virtualenv) using python3.8 in .nox/lint\u001b[0m\n", + "\u001b[36mnox > \u001b[34mpython -m pip install flake8\u001b[0m\n", + "\u001b[36mnox > \u001b[34mflake8 --version\u001b[0m\n", + "7.0.0 (mccabe: 0.7.0, pycodestyle: 2.11.1, pyflakes: 3.2.0) CPython 3.8.1 on\n", + "Linux\n", + "\u001b[36mnox > \u001b[32mSession lint was successful.\u001b[0m\n" + ] + } + ], + "source": [ + "!makim nox.run --ex \"-s lint\"" + ] + }, + { + "cell_type": "markdown", + "id": "22d5d5df-e3bc-4f3f-8a4c-48f740d5a53f", + "metadata": {}, + "source": [ + "### Direct Noxfile Integration" + ] + }, + { + "cell_type": "markdown", + "id": "f74614f9-d137-408f-99ba-497e4399effe", + "metadata": {}, + "source": [ + "In scenarios where integrating Nox sessions directly within Makim is preferred, Makim's `shell` command can invoke Nox as the interpreter:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "b4b45167-a1ef-4aef-be56-fab5fd837dab", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Overwriting .makim.yaml\n" + ] + } + ], + "source": [ + "%%writefile .makim.yaml\n", + "version: 1.0\n", + "groups:\n", + " nox:\n", + " help: A set of functionality ported from noxfile.py\n", + " targets:\n", + " tests:\n", + " help: Run nox tests\n", + " shell: nox\n", + " run: |\n", + " import nox\n", + "\n", + " @nox.session(name=\"custom-name\")\n", + " def tests(session: nox.Session) -> None:\n", + " \"\"\"Run tests with pytest.\"\"\"\n", + " session.install(\"pytest\")\n", + " session.run(\"pytest\", \"--version\")\n", + " lint:\n", + " help: Run nox tests\n", + " shell: nox\n", + " run: |\n", + " import nox\n", + "\n", + " @nox.session\n", + " def lint(session: nox.Session):\n", + " \"\"\"Run linters on the codebase.\"\"\"\n", + " session.install('flake8')\n", + " session.run('flake8', '--version')\n", + "\n", + " all:\n", + " help: Run nox tests\n", + " dependencies:\n", + " - target: nox.tests\n", + " - target: nox.lint" + ] + }, + { + "cell_type": "markdown", + "id": "6334550b-6bfd-42fe-89d0-58fce1fad5ca", + "metadata": {}, + "source": [ + "In this example, we created a target (task) for each Nox session. To execute the `tests` target, just run:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "9b918338-9c5e-4682-8ec0-330ed7f6e0ea", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Makim file: .makim.yaml\n", + "\u001b[36mnox > \u001b[33mRunning session custom-name\u001b[0m\n", + "\u001b[36mnox > \u001b[34mCreating virtual environment (virtualenv) using python3.8 in .nox/custom-name\u001b[0m\n", + "\u001b[36mnox > \u001b[34mpython -m pip install pytest\u001b[0m\n", + "\u001b[36mnox > \u001b[34mpytest --version\u001b[0m\n", + "pytest 8.1.1\n", + "\u001b[36mnox > \u001b[32mSession custom-name was successful.\u001b[0m\n" + ] + } + ], + "source": [ + "!makim nox.tests" + ] + }, + { + "cell_type": "markdown", + "id": "92755c57-27a4-4d56-a81a-7d23113c34ba", + "metadata": {}, + "source": [ + "To execute the `lint` target, run:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "929bce74-5efc-474b-9acd-fb07e65ffa78", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Makim file: .makim.yaml\n", + "\u001b[36mnox > \u001b[33mRunning session lint\u001b[0m\n", + "\u001b[36mnox > \u001b[34mCreating virtual environment (virtualenv) using python3.8 in .nox/lint\u001b[0m\n", + "\u001b[36mnox > \u001b[34mpython -m pip install flake8\u001b[0m\n", + "\u001b[36mnox > \u001b[34mflake8 --version\u001b[0m\n", + "7.0.0 (mccabe: 0.7.0, pycodestyle: 2.11.1, pyflakes: 3.2.0) CPython 3.8.1 on\n", + "Linux\n", + "\u001b[36mnox > \u001b[32mSession lint was successful.\u001b[0m\n" + ] + } + ], + "source": [ + "!makim nox.lint" + ] + }, + { + "cell_type": "markdown", + "id": "e72f61de-20b3-427f-a868-a012d8ef5e18", + "metadata": {}, + "source": [ + "As we also created a target that has both `tests` and `lint` targets as dependencies, so we can run both just running the `all` target:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "b710f60a-8d30-4f5a-83f3-1412953d8e78", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Makim file: .makim.yaml\n", + "\u001b[36mnox > \u001b[33mRunning session custom-name\u001b[0m\n", + "\u001b[36mnox > \u001b[34mCreating virtual environment (virtualenv) using python3.8 in .nox/custom-name\u001b[0m\n", + "\u001b[36mnox > \u001b[34mpython -m pip install pytest\u001b[0m\n", + "\u001b[36mnox > \u001b[34mpytest --version\u001b[0m\n", + "pytest 8.1.1\n", + "\u001b[36mnox > \u001b[32mSession custom-name was successful.\u001b[0m\n", + "\u001b[36mnox > \u001b[33mRunning session lint\u001b[0m\n", + "\u001b[36mnox > \u001b[34mCreating virtual environment (virtualenv) using python3.8 in .nox/lint\u001b[0m\n", + "\u001b[36mnox > \u001b[34mpython -m pip install flake8\u001b[0m\n", + "\u001b[36mnox > \u001b[34mflake8 --version\u001b[0m\n", + "7.0.0 (mccabe: 0.7.0, pycodestyle: 2.11.1, pyflakes: 3.2.0) CPython 3.8.1 on\n", + "Linux\n", + "\u001b[36mnox > \u001b[32mSession lint was successful.\u001b[0m\n" + ] + } + ], + "source": [ + "!makim nox.all" + ] + }, + { + "cell_type": "markdown", + "id": "e7731545-2457-4802-b41d-1bed686c5b95", + "metadata": {}, + "source": [ + "## Concluding Thoughts" + ] + }, + { + "cell_type": "markdown", + "id": "9102d041-e403-44dd-a039-3b376bef46a8", + "metadata": {}, + "source": [ + "Integrating Nox within a Makim configuration might not always offer tangible benefits, and potentially introducing unnecessary complexity.\n", + "\n", + "Although Nox offers robust automation capabilities, especially for testing across multiple Python environments, for projects where CI workflows are already optimized for environment-specific jobs, transitioning to Makim could simplify and streamline development processes." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.1" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/tutorials/makim-for-nox-users/noxfile.py b/docs/tutorials/makim-for-nox-users/noxfile.py new file mode 100644 index 0000000..c40d7b3 --- /dev/null +++ b/docs/tutorials/makim-for-nox-users/noxfile.py @@ -0,0 +1,15 @@ +import nox + +@nox.session(name="custom-name") +def tests(session: nox.Session) -> None: + """Run tests with pytest.""" + session.install("pytest") + session.run("pytest", "--version") + +@nox.session +def lint(session: nox.Session): + """Run linters on the codebase.""" + session.install('flake8') + # Example of using session.posargs for ad-hoc arguments + additional_args = session.posargs or [] + session.run('flake8', '--version', *additional_args) diff --git a/mkdocs.yaml b/mkdocs.yaml index 2b1788a..a607966 100644 --- a/mkdocs.yaml +++ b/mkdocs.yaml @@ -9,6 +9,7 @@ theme: name: material features: - content.code.annotate + - content.code.copy - content.tabs.link - header.autohide - navigation.indexes @@ -21,10 +22,21 @@ theme: logo: ./images/logo.png favicon: ./images/favicon.ico palette: - scheme: slate - primary: white - accent: lime - # custom_dir: docs/overrides + # Palette toggle for light mode + - scheme: default + primary: white + accent: lime + toggle: + icon: material/weather-night + name: Switch to dark mode + + # Palette toggle for dark mode + - scheme: slate + primary: white + accent: lime + toggle: + icon: material/weather-sunny + name: Switch to light mode plugins: - search - macros @@ -78,12 +90,14 @@ plugins: show_root_toc_entry: true show_source: false - mkdocs-jupyter: - execute: true + execute: false + include: ["*.ipynb"] ignore: - "*.py" + - ".ipynb_checkpoints/*" # execute_ignore: "tutorial/*Geospatial*.ipynb" include_source: true - theme: dark + include_requirejs: true - literate-nav markdown_extensions: - admonition @@ -100,18 +114,20 @@ markdown_extensions: custom_icons: - docs/static/icons - pymdownx.details - - pymdownx.highlight + - pymdownx.highlight: + anchor_linenums: true - pymdownx.inlinehilite - pymdownx.magiclink: provider: github repo_url_shortener: true - pymdownx.saneheaders - - pymdownx.snippets + - pymdownx.snippets: + check_paths: true - pymdownx.superfences - - pymdownx.tabbed: - alternate_style: true + - pymdownx.tabbed - tables - - toc + - toc: + permalink: true extra: project_name: "Makim" team: