From c76c7207eba782e65cbfb52e1c37574a501b8c00 Mon Sep 17 00:00:00 2001 From: Sina Atalay Date: Wed, 19 Jun 2024 14:34:05 +0300 Subject: [PATCH] use Hatch as the project manager (#92) --- .github/workflows/deploy-docs.yaml | 4 +- .github/workflows/publish.yaml | 4 +- .github/workflows/test.yaml | 21 +-- docs/developer_guide/index.md | 107 +++++++++--- docs/developer_guide/testing.md | 12 +- docs/developer_guide/writing_documentation.md | 14 +- ...dercv_files.py => update_entry_figures.py} | 86 +--------- docs/update_examples.py | 83 +++++++++ docs/update_schema.py | 18 ++ mkdocs.yaml | 2 +- pyproject.toml | 159 +++++++++++++----- schema.json | 79 +++++++-- 12 files changed, 407 insertions(+), 182 deletions(-) rename docs/{update_rendercv_files.py => update_entry_figures.py} (75%) create mode 100644 docs/update_examples.py create mode 100644 docs/update_schema.py diff --git a/.github/workflows/deploy-docs.yaml b/.github/workflows/deploy-docs.yaml index e515bb4..c41cbcd 100644 --- a/.github/workflows/deploy-docs.yaml +++ b/.github/workflows/deploy-docs.yaml @@ -31,5 +31,5 @@ jobs: - name: Deploy documentation run: | - pip install .[docs] - mkdocs gh-deploy --force + pip install hatch + hatch run docs:deploy diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index ac997d2..0a81944 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -36,8 +36,8 @@ jobs: - name: Build run: | - pip install -U build - python -m build + pip install hatch + hatch build - name: Upload package to PyPI uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index da10077..f2f85e3 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -27,8 +27,8 @@ jobs: - name: Lint with Ruff run: | - pip install .[dev] - ruff --output-format=github . + pip install hatch + hatch run lint continue-on-error: true test: @@ -51,13 +51,10 @@ jobs: with: python-version: ${{ matrix.python-version }} - - name: Install dependencies + - name: Test run: | - pip install .[tests] - - - name: Test with pytest - run: | - coverage run -m pytest tests/ + pip install hatch + hatch run test:run-with-coverage mv .coverage .coverage.${{ matrix.python-version }}.${{ matrix.os }} - name: Store coverage files @@ -89,10 +86,10 @@ jobs: - name: Combine coverage files run: | - pip install .[tests] - coverage combine coverage - coverage report - coverage html --show-contexts --title "RenderCV coverage for ${{ github.sha }}" + pip install hatch + hatch run test:coverage combine coverage + hatch run test:coverage report + hatch run test:coverage html --show-contexts --title "RenderCV coverage for ${{ github.sha }}" - name: Upload the coverage report to smokeshow run: | diff --git a/docs/developer_guide/index.md b/docs/developer_guide/index.md index 363b453..3181761 100644 --- a/docs/developer_guide/index.md +++ b/docs/developer_guide/index.md @@ -7,37 +7,45 @@ The source code is thoroughly documented and well-commented, making it an enjoya ## Getting Started 1. Ensure that you have Python version 3.10 or higher. +2. Install [Hatch](https://hatch.pypa.io/latest/), as it is the project manager for RenderCV. The installation guide for Hatch can be found [here](https://hatch.pypa.io/latest/install/#installation). +3. Clone the repository recursively (because TinyTeX is being used as a submodule) with the following command. + ```bash + git clone --recursive https://github.com/sinaatalay/rendercv.git + ``` +4. Go to the `rendercv` directory. + ```bash + cd rendercv + ``` +5. RenderCV uses three virtual environments: + - `default`: For the development. It contains packages like [Ruff](https://github.com/astral-sh/ruff), [Black](https://github.com/psf/black), etc. + - `docs`: For building the documentation. + - `test`: For testing RenderCV. + + ```bash + hatch env create default + hatch env create docs + hatch env create test + ``` +6. To use the virtual environments, either -2. Then, clone the repository recursively (because TinyTeX is being used as a submodule) with the following command. -```bash -git clone --recursive https://github.com/sinaatalay/rendercv.git -``` - -3. Go to the `rendercv` directory. -```bash -cd rendercv -``` - -4. Create a virtual environment. -```bash -python -m venv .venv -``` - -5. Activate the virtual environment. - - === "Windows (PowerShell)" - ```powershell - .venv\Scripts\Activate.ps1 - ``` - === "MacOS/Linux" + - Activate one of the virtual environments with the following command. ```bash - source .venv/bin/activate + hatch shell default ``` + + - Select one of the virtual environments in your Integrated Development Environment (IDE). + + === "Visual Studio Code" + + - Press `Ctrl+Shift+P`. + - Type `Python: Select Interpreter`. + - Select one of the virtual environments created by Hatch. + + === "Other" + + To be added. + -6. Install the dependencies. -```bash -pip install --editable ".[docs,tests,dev]" -``` ## How RenderCV works? @@ -56,6 +64,51 @@ flowchart TD AA[(Jinja2 Templates)] --> E ``` +## Available Commands + +These commands are defined in the [`pyproject.toml`](https://github.com/sinaatalay/rendercv/blob/main/pyproject.toml) file. + +- Format the code with [Black](https://github.com/psf/black): + ```bash + hatch run format + ``` +- Lint the code with [Ruff](https://github.com/astral-sh/ruff): + ```bash + hatch run lint + ``` +- Run the tests: + ```bash + hatch run test:run + ``` +- Run the tests and generate a coverage report: + ```bash + hatch run test:run-and-report + ``` +- Start the development server for the documentation: + ```bash + hatch run docs:serve + ``` +- Build the documentation: + ```bash + hatch run docs:build + ``` +- Deploy the documentation to GitHub Pages: + ```bash + hatch run docs:deploy + ``` +- Update [schema.json](https://github.com/sinaatalay/rendercv/blob/main/schema.json): + ```bash + hatch run docs:update-schema + ``` +- Update [`examples`](https://github.com/sinaatalay/rendercv/tree/main/examples) folder: + ```bash + hatch run docs:update-examples + ``` +- Update figures of the entry types in the "[Structure of the YAML Input File](https://docs.rendercv.com/user_guide/structure_of_the_yaml_input_file/)": + ```bash + hatch run docs:update-entry-figures + ``` + ## About [`pyproject.toml`](https://github.com/sinaatalay/rendercv/blob/main/pyproject.toml) [`pyproject.toml`](https://github.com/sinaatalay/rendercv/blob/main/pyproject.toml) contains all the metadata, dependencies, and tools required for the project. Please read through the file to understand the project's technical details. \ No newline at end of file diff --git a/docs/developer_guide/testing.md b/docs/developer_guide/testing.md index 11231ee..68253a6 100644 --- a/docs/developer_guide/testing.md +++ b/docs/developer_guide/testing.md @@ -3,12 +3,20 @@ After updating the code, ensure that all tests pass. To run the tests, use the following command. ```bash -pytest +hatch run test:run +``` + +If you would like to run the tests in your IDE, use the `test` virtual environment. + +To generate a coverage report with the tests, run the following command. + +```bash +hatch run test:run-and-report ``` Once new commits are pushed to the `main` branch, the [`test.yaml`](https://github.com/sinaatalay/rendercv/blob/main/.github/workflows/test.yaml) workflow will be automatically triggered, and the tests will run. -## [`testdata`](https://github.com/sinaatalay/rendercv/tree/main/tests/testdata) folder +## About [`testdata`](https://github.com/sinaatalay/rendercv/tree/main/tests/testdata) folder In some of the tests: diff --git a/docs/developer_guide/writing_documentation.md b/docs/developer_guide/writing_documentation.md index 43cd3b5..4596719 100644 --- a/docs/developer_guide/writing_documentation.md +++ b/docs/developer_guide/writing_documentation.md @@ -3,7 +3,7 @@ The documentation's source files are located in the [`docs`](https://github.com/sinaatalay/rendercv/tree/main/docs) directory and it is built using the [MkDocs](https://github.com/mkdocs/mkdocs) package. To work on the documentation and see the changes in real-time, run the following command. ```bash -mkdocs serve +hatch run docs:serve ``` Once the changes are pushed to the `main` branch, the [`deploy-docs`](https://github.com/sinaatalay/rendercv/blob/main/.github/workflows/deploy-docs.yaml) workflow will be automatically triggered, and [docs.rendercv.com](https://docs.rendercv.com/) will be updated to the most recent version. @@ -12,34 +12,34 @@ Once the changes are pushed to the `main` branch, the [`deploy-docs`](https://gi The `examples` folder includes example YAML files for all the built-in themes, along with their corresponding PDF outputs. Also, there are PNG files of the first pages of each theme in [`docs/assets/images`](https://github.com/sinaatalay/rendercv/tree/main/docs/assets/images). These examples are shown in [`README.md`](https://github.com/sinaatalay/rendercv/blob/main/README.md). -These files are generated using [`docs/update_rendercv_files.py`](https://github.com/sinaatalay/rendercv/blob/main/docs/update_rendercv_files.py). The contents of the examples are taken from the [`get_a_sample_data_model`](https://docs.rendercv.com/reference/data_models/#rendercv.data_models.get_a_sample_data_model) function from [`data_models.py`](https://docs.rendercv.com/reference/data_models/). +These files are generated using [`docs/update_examples.py`](https://github.com/sinaatalay/rendercv/blob/main/docs/update_examples.py). The contents of the examples are taken from the [`get_a_sample_data_model`](https://docs.rendercv.com/reference/data_models/#rendercv.data_models.get_a_sample_data_model) function from [`data_models.py`](https://docs.rendercv.com/reference/data_models/). Run the following command to update the `examples` folder. ```bash -python docs/update_rendercv_files.py +hatch run docs:update-examples ``` ## Updating figures of the entry types in the "[Structure of the YAML Input File](https://docs.rendercv.com/user_guide/structure_of_the_yaml_input_file/)" There are example figures for each entry type for each theme in the "[Structure of the YAML Input File](https://docs.rendercv.com/user_guide/structure_of_the_yaml_input_file/)" page. -The figures are generated using [`docs/update_rendercv_files.py`](https://github.com/sinaatalay/rendercv/blob/main/docs/update_rendercv_files.py). +The figures are generated using [`docs/update_entry_figures.py`](https://github.com/sinaatalay/rendercv/blob/main/docs/update_entry_figures.py). Run the following command to update the figures. ```bash -python docs/update_rendercv_files.py +hatch run docs:update-entry-figures ``` ## Updating the [JSON Schema](https://github.com/sinaatalay/rendercv/blob/main/schema.json) The schema of RenderCV's input file is defined using [Pydantic](https://docs.pydantic.dev/latest/). Pydantic allows automatic creation and customization of JSON schemas from Pydantic models. -The JSON Schema is also generated using [`docs/update_rendercv_files.py`](https://github.com/sinaatalay/rendercv/blob/main/docs/update_rendercv_files.py). It uses [`generate_json_schema`](https://docs.rendercv.com/reference/data_models/#rendercv.data_models.generate_json_schema) function from [`data_models.py`](https://docs.rendercv.com/reference/data_models/). +The JSON Schema is also generated using [`docs/update_schema.py`](https://github.com/sinaatalay/rendercv/blob/main/docs/update_schema.py). It uses [`generate_json_schema`](https://docs.rendercv.com/reference/data_models/#rendercv.data_models.generate_json_schema) function from [`data_models.py`](https://docs.rendercv.com/reference/data_models/). Run the following command to update the JSON Schema. ```bash -python docs/update_rendercv_files.py +hatch run docs:update-schema ``` \ No newline at end of file diff --git a/docs/update_rendercv_files.py b/docs/update_entry_figures.py similarity index 75% rename from docs/update_rendercv_files.py rename to docs/update_entry_figures.py index f7eaf51..0c14d15 100644 --- a/docs/update_rendercv_files.py +++ b/docs/update_entry_figures.py @@ -1,14 +1,19 @@ +"""This script generates the example entry figures and creates an environment for +documentation templates using `mkdocs-macros-plugin`. For example, the content of the +example entries found in +"[Structure of the YAML Input File](https://docs.rendercv.com/user_guide/structure_of_the_yaml_input_file/)" +are coming from this script. +""" + import tempfile import pathlib import io -import os import shutil from typing import Any -import pdfCropMargins import ruamel.yaml +import pdfCropMargins -import rendercv.cli as cli import rendercv.data_models as dm import rendercv.renderer as r @@ -237,77 +242,6 @@ def generate_entry_figures(): output_pdf_file_path.unlink() -def generate_examples(): - """Generate example YAML and PDF files.""" - examples_directory_path = pathlib.Path(__file__).parent.parent / "examples" - - # check if the examples directory exists, if not create it - if not examples_directory_path.exists(): - examples_directory_path.mkdir() - - os.chdir(examples_directory_path) - themes = dm.available_themes - for theme in themes: - cli.cli_command_new( - "John Doe", - theme, - dont_create_theme_source_files=True, - dont_create_markdown_source_files=True, - ) - yaml_file_path = examples_directory_path / "John_Doe_CV.yaml" - - # Rename John_Doe_CV.yaml: - proper_theme_name = theme.capitalize() + "Theme" - new_yaml_file_path = ( - examples_directory_path / f"John_Doe_{proper_theme_name}_CV.yaml" - ) - if new_yaml_file_path.exists(): - new_yaml_file_path.unlink() - yaml_file_path.rename(new_yaml_file_path) - yaml_file_path = new_yaml_file_path - - # Generate the PDF file: - cli.cli_command_render(yaml_file_path) - - output_pdf_file = ( - examples_directory_path / "rendercv_output" / "John_Doe_CV.pdf" - ) - - # Move pdf file to the examples directory: - new_pdf_file_path = examples_directory_path / f"{yaml_file_path.stem}.pdf" - if new_pdf_file_path.exists(): - new_pdf_file_path.unlink() - output_pdf_file.rename(new_pdf_file_path) - - # Remove the rendercv_output directory: - rendercv_output_directory = examples_directory_path / "rendercv_output" - - shutil.rmtree(rendercv_output_directory) - - # convert first page of the pdf to an image: - png_file_paths = r.pdf_to_pngs(new_pdf_file_path) - firt_page_png_file_path = png_file_paths[0] - if len(png_file_paths) > 1: - # remove the other pages - for png_file_path in png_file_paths[1:]: - png_file_path.unlink() - - desired_png_file_path = image_assets_directory / f"{theme}.png" - - # If the image exists, remove it - if desired_png_file_path.exists(): - desired_png_file_path.unlink() - - # Move the image to the desired location - firt_page_png_file_path.rename(desired_png_file_path) - - -def generate_schema(): - """Generate the schema.""" - json_schema_file_path = repository_root / "schema.json" - dm.generate_json_schema_file(json_schema_file_path) - - def update_index(): """Update the index.md file by copying the README.md file.""" index_file_path = repository_root / "docs" / "index.md" @@ -317,6 +251,4 @@ def update_index(): if __name__ == "__main__": generate_entry_figures() - generate_examples() - generate_schema() - # update_index() # currently index.md should be updated manually + print("Entry figures generated successfully.") diff --git a/docs/update_examples.py b/docs/update_examples.py new file mode 100644 index 0000000..30a5fd3 --- /dev/null +++ b/docs/update_examples.py @@ -0,0 +1,83 @@ +"""This script generates the `examples` folder in the repository root.""" + +import pathlib +import os +import shutil + +import rendercv.cli as cli +import rendercv.data_models as dm +import rendercv.renderer as r + +repository_root = pathlib.Path(__file__).parent.parent +rendercv_path = repository_root / "rendercv" +image_assets_directory = pathlib.Path(__file__).parent / "assets" / "images" + + +def generate_examples(): + """Generate example YAML and PDF files.""" + examples_directory_path = pathlib.Path(__file__).parent.parent / "examples" + + # check if the examples directory exists, if not create it + if not examples_directory_path.exists(): + examples_directory_path.mkdir() + + os.chdir(examples_directory_path) + themes = dm.available_themes + for theme in themes: + cli.cli_command_new( + "John Doe", + theme, + dont_create_theme_source_files=True, + dont_create_markdown_source_files=True, + ) + yaml_file_path = examples_directory_path / "John_Doe_CV.yaml" + + # Rename John_Doe_CV.yaml: + proper_theme_name = theme.capitalize() + "Theme" + new_yaml_file_path = ( + examples_directory_path / f"John_Doe_{proper_theme_name}_CV.yaml" + ) + if new_yaml_file_path.exists(): + new_yaml_file_path.unlink() + yaml_file_path.rename(new_yaml_file_path) + yaml_file_path = new_yaml_file_path + + # Generate the PDF file: + cli.cli_command_render(yaml_file_path) + + output_pdf_file = ( + examples_directory_path / "rendercv_output" / "John_Doe_CV.pdf" + ) + + # Move pdf file to the examples directory: + new_pdf_file_path = examples_directory_path / f"{yaml_file_path.stem}.pdf" + if new_pdf_file_path.exists(): + new_pdf_file_path.unlink() + output_pdf_file.rename(new_pdf_file_path) + + # Remove the rendercv_output directory: + rendercv_output_directory = examples_directory_path / "rendercv_output" + + shutil.rmtree(rendercv_output_directory) + + # convert first page of the pdf to an image: + png_file_paths = r.pdf_to_pngs(new_pdf_file_path) + firt_page_png_file_path = png_file_paths[0] + if len(png_file_paths) > 1: + # remove the other pages + for png_file_path in png_file_paths[1:]: + png_file_path.unlink() + + desired_png_file_path = image_assets_directory / f"{theme}.png" + + # If the image exists, remove it + if desired_png_file_path.exists(): + desired_png_file_path.unlink() + + # Move the image to the desired location + firt_page_png_file_path.rename(desired_png_file_path) + + +if __name__ == "__main__": + generate_examples() + print("Examples generated successfully.") diff --git a/docs/update_schema.py b/docs/update_schema.py new file mode 100644 index 0000000..088a022 --- /dev/null +++ b/docs/update_schema.py @@ -0,0 +1,18 @@ +"""This script generates the JSON schema (schema.json) in the repository root.""" + +import pathlib + +import rendercv.data_models as dm + +repository_root = pathlib.Path(__file__).parent.parent + + +def generate_schema(): + """Generate the schema.""" + json_schema_file_path = repository_root / "schema.json" + dm.generate_json_schema_file(json_schema_file_path) + + +if __name__ == "__main__": + generate_schema() + print("Schema generated successfully.") diff --git a/mkdocs.yaml b/mkdocs.yaml index 31fc9de..a50e328 100644 --- a/mkdocs.yaml +++ b/mkdocs.yaml @@ -95,7 +95,7 @@ markdown_extensions: plugins: - search - macros: # mkdocs-macros-plugin - module_name: docs/update_rendercv_files + module_name: docs/update_entry_figures - mkdocstrings: handlers: python: diff --git a/pyproject.toml b/pyproject.toml index 4c3dc76..ad6bb75 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,14 +9,20 @@ # called building. # Python packages need to be built too, even though they are not compiled (mostly). At -# the end of the building process, a source Distribution Package, `sdist`, is created. -# This sdist is a compressed archive of the source code, and it is ready to be uploaded -# to PyPI. See https://packaging.python.org/en/latest/tutorials/packaging-projects/ +# the end of the building process, a source distribution package (sdist) and a built +# distribution package (in Wheel format) are created. +# See https://packaging.python.org/en/latest/tutorials/packaging-projects/ for details. +# Built Distribution: +# https://packaging.python.org/en/latest/glossary/#term-Built-Distribution +# Source Distribution: +# https://packaging.python.org/en/latest/glossary/#term-Source-Distribution-or-sdist # To build RenderCV, we need to specify which build package we want to use. There are # many build packages like `setuptools`, `flit`, `poetry`, `hatchling`, etc. We will use # `hatchling`. -requires = ["hatchling==1.21.1"] # Our dependency to build RenderCV +requires = [ + "hatchling==1.21.1", +] # List of packages that are needed to build RenderCV # Python has a standard object format called build-backend object. Python standard asks # this object to have some specific methods that do a specific job. For example, it @@ -25,34 +31,42 @@ requires = ["hatchling==1.21.1"] # Our dependency to build RenderCV # See https://peps.python.org/pep-0517/ build-backend = "hatchling.build" # A build-backend object for building RenderCV +[tool.hatch.build.targets.sdist] +# In the sdist, what do we want to exclude? +exclude = [ + "rendercv/tinytex-release/download_and_minimize_tinytex_for_rendercv.py", + "rendercv/tinytex-release/.gitignore", + "rendercv/tinytex-release/.git", + ".github/", + ".devcontainer/", + # GIF files are too big: + "*.gif", +] + +[tool.hatch.build.targets.wheel] +# In wheel, what do we want to include and exclude? +packages = ["rendercv"] +exclude = [ + "rendercv/tinytex-release/download_and_minimize_tinytex_for_rendercv.py", + "rendercv/tinytex-release/.gitignore", + "rendercv/tinytex-release/.git", + "rendercv/tinytex-release/README.md", +] + [tool.hatch.version] # We will use hatchling to generate the version number of RenderCV. It will go to the # `path` below and get the version number from there. # See https://hatch.pypa.io/latest/version/ path = "rendercv/__init__.py" -[tool.hatch.build] -# In the sdist package, what do we want to include and exclude? For example, we don't -# want to include `docs` and `tests` because they are not needed to run RenderCV. -include = ["/README.md", "/rendercv"] - -# We use tinytex-release as a git submodule, so it's a seperate repository. We don't -# want to ship all the files from that repository with RenderCV. -exclude = [ - "/rendercv/tinytex-release/download_and_minimize_tinytex_for_rendercv.py", - "/rendercv/tinytex-release/.gitignore", -] - [project] # Under the `project` section, we specify the metadata about RenderCV. name = 'rendercv' description = 'A LaTeX CV/resume framework' -dynamic = [ - "version", -] # We will use hatchling to generate the version number authors = [{ name = 'Sina Atalay', email = 'dev@atalay.biz' }] -requires-python = '>=3.10' +license = "MIT" readme = "README.md" +requires-python = '>=3.10' # RenderCV depends on these packages. They will be installed automatically when RenderCV # is installed: dependencies = [ @@ -78,12 +92,16 @@ classifiers = [ "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", ] # go to https://pypi.org/classifiers/ to see all classifiers +dynamic = [ + "version", +] # We will use hatchling to generate the version number [project.urls] # Here, we can specify the URLs related to RenderCV. They will be listed under the # "Project links" section in PyPI. See https://pypi.org/project/rendercv/ -Documentation = 'https://docs.rendercv.com' Source = 'https://github.com/sinaatalay/rendercv' +Documentation = 'https://docs.rendercv.com' +Changelog = 'https://docs.rendercv.com/changelog' [project.scripts] # Here, we specify the entry points of RenderCV. @@ -91,34 +109,88 @@ Source = 'https://github.com/sinaatalay/rendercv' # See https://hatch.pypa.io/latest/config/metadata/#cli # The key and value below mean this: If someone installs RenderCV, then running -# `rendercv` in the terminal will run the function `app` in the module `__main__` in the +# `rendercv` in the terminal will run the function `app` in the module `cli` in the # package `rendercv`. -rendercv = 'rendercv.__main__:app' +rendercv = 'rendercv.cli:app' -[project.optional-dependencies] -# RenderCV depends on other packages. However, some of these packages are not required -# to run RenderCV, but they are required to develop RenderCV. For example, to build the -# documentation of RenderCV, we need to install some packages. However, not all the -# users of RenderCV will build the documentation, so these are optional dependencies. +# ====================================================================================== +# Virtual Environments Below =========================================================== +# ====================================================================================== -docs = [ +# RenderCV depends on other packages, which are listed under the `project` section as +# `dependencies`. However, for the development of RenderCV, we need some other packages +# too (like `black`, `ruff`, `mkdocs`, etc.). We need these packages in our virtual +# environments and we handle the environments with `hatchling`. + +# There will be three virtual environments for RenderCV: `default`, `docs`, and `test`. + +# `default` is the default virtual environment needed to develop RenderCV. +# `docs` is the virtual environment needed to build the documentation of RenderCV. +# `test` is the virtual environment needed to run the tests of RenderCV. + +[tool.hatch.envs.default] +# Dependencies to be installed in the `default` virtual environment. +dependencies = [ + "ruff==0.4.5", # to lint the code + "black==24.4.2", # to format the code +] +path = ".venv" +[tool.hatch.envs.default.scripts] +# Hatch allows us to define scripts that can be run in the activated virtual environment +# with `hatch run ENV_NAME:SCRIPT_NAME`. +# Format all the code in the `rendercv` package with `black`: +format = "black rendercv" # hatch run format +# Lint the code in the `rendercv` package with `ruff`: +lint = "ruff check rendercv" # hatch run lint + + +[tool.hatch.envs.docs] +# Dependencies to be installed in the `docs` virtual environment. +dependencies = [ "mkdocs-material==9.5.24", # to build docs "mkdocstrings-python==1.10.3", # to build reference documentation from docstrings "pdfCropMargins==2.1.3", # to generate entry figures for the documentation "pillow==10.3.0", # lock the dependency of pdfCropMargins "mkdocs-macros-plugin==1.0.5", # to be able to have dynamic content in the documentation ] -tests = [ +path = ".venv-docs" +[tool.hatch.envs.docs.scripts] +# Build the documentation with `mkdocs`: +build = "mkdocs build --clean --strict" # hatch run docs:build +# Start the development server for the documentation with `mkdocs`: +serve = "mkdocs serve" # hatch run docs:serve +# Deploy the documentation to docs.rendercv.com with `mkdocs`: +deploy = "mkdocs gh-deploy --force" # hatch run docs:deploy +# Update schema.json: +update-schema = "python docs/update_schema.py" # hatch run docs:update-schema +# Update `examples` folder: +update-examples = "python docs/update_examples.py" # hatch run docs:update-examples +# Update entry figures in "Structure of the YAML File" page: +update-entry-figures = "python docs/update_entry_figures.py" # hatch run docs:update-entry-figures + +[tool.hatch.envs.test] +# Dependencies to be installed in the `test` virtual environment. +dependencies = [ "pytest==8.2.1", # to run the tests "coverage==7.5.1", # to generate coverage reports "time-machine==2.14.1", # to select an arbitrary date and time for testing "pypdf==4.2.0", # to read PDF files ] -dev = [ - "ruff==0.4.5", # to lint the code - "black==24.4.2", # to format the code -] +path = ".venv-test" +# [[tool.hatch.envs.test.matrix]] +# # We can specify the Python versions that we want to test RenderCV with. Hatch will +# # create three different virtual environments for each Python version. +# # They will be named as test.py3.10, test.py3.11, and test.py3.12. +# python = ["3.10", "3.11", "3.12"] +[tool.hatch.envs.test.scripts] +# Run the tests: +run = "pytest" # hatch run test:run +# Run the tests and generate the coverage report as HTML: +run-and-report = "coverage run -m pytest && coverage report && coverage html --show-contexts" # hatch run test:coverage +# ====================================================================================== +# Virtual Environments Above =========================================================== +# ====================================================================================== # RenderCV uses different tools to check the code quality, format the code, build the # documentation, build the package, etc. We can specify the settings for these tools in @@ -126,18 +198,29 @@ dev = [ # these tools easily. Generally, popular IDEs grab these settings from `pyproject.toml` # file automatically. +[tool.ruff] +exclude = [ + "rendercv/tinytex-release/download_and_minimize_tinytex_for_rendercv.py", +] +output-format = "github" + [tool.black] line-length = 88 # maximum line length preview = true # to allow enable-unstable-feature enable-unstable-feature = [ "string_processing", -] # breaking strings into multiple lines +] # to break strings into multiple lines [tool.coverage.run] -source = ['rendercv'] -# use relative paths instead of absolute paths, this is useful for combining coverage +source = ['rendercv'] # The source to measure during execution + +# Use relative paths instead of absolute paths, this is useful for combining coverage # reports from different OSes: relative_files = true -# don't include jinja templates in the coverage report: +[tool.coverage.report] +# Don't include jinja templates in the coverage report: omit = ["*.j2.*", "rendercv/__main__.py"] + +# Don't include these lines in the coverage report: +exclude_lines = ["if __name__ == .__main__.:"] diff --git a/schema.json b/schema.json index a52f0cd..26a478e 100644 --- a/schema.json +++ b/schema.json @@ -123,6 +123,18 @@ "title": "Text Alignment", "type": "string" }, + "seperator_between_connections": { + "default": "", + "description": "The separator between the connections in the header. The default value is empty string.", + "title": "Seperator Between Connections", + "type": "string" + }, + "use_icons_for_connections": { + "default": true, + "description": "If this option is set to true, then icons will be used for the connections in the header. The default value is true.", + "title": "Use Icons for Connections", + "type": "boolean" + }, "margins": { "allOf": [ { @@ -212,7 +224,7 @@ }, "email": { "default": null, - "description": "The email of the person.", + "description": "The email address of the person.", "title": "Email", "oneOf": [ { @@ -536,6 +548,18 @@ "title": "Text Alignment", "type": "string" }, + "seperator_between_connections": { + "default": "$|$", + "description": "The separator between the connections in the header. The default value is empty string.", + "title": "Seperator Between Connections", + "type": "string" + }, + "use_icons_for_connections": { + "default": false, + "description": "If this option is set to true, then icons will be used for the connections (like phone, email, and website). The default value is false.", + "title": "Use Icons for Connections", + "type": "boolean" + }, "margins": { "allOf": [ { @@ -955,8 +979,8 @@ ] }, "to": { - "default": "to", - "description": "Translation of the word \"to\" in the locale.", + "default": "–", + "description": "The word or character used to indicate a range in the locale (e.g., \"2020 - 2021\").", "title": "Translation of \"To\"", "oneOf": [ { @@ -966,18 +990,18 @@ }, "abbreviations_for_months": { "default": [ - "Jan.", - "Feb.", - "Mar.", - "Apr.", + "Jan", + "Feb", + "Mar", + "Apr", "May", "June", "July", - "Aug.", - "Sept.", - "Oct.", - "Nov.", - "Dec." + "Aug", + "Sept", + "Oct", + "Nov", + "Dec" ], "description": "Abbreviations of the months in the locale.", "title": "Abbreviations of Months", @@ -1547,7 +1571,7 @@ "properties": { "title": { "description": "The title of the publication.", - "title": "Title of the Publication", + "title": "Publication Title", "type": "string" }, "authors": { @@ -1571,9 +1595,22 @@ } ] }, + "url": { + "default": null, + "description": "The URL of the publication. If DOI is provided, it will be ignored.", + "title": "URL", + "oneOf": [ + { + "format": "uri", + "maxLength": 2083, + "minLength": 1, + "type": "string" + } + ] + }, "journal": { "default": null, - "description": "The journal or the conference name.", + "description": "The journal or conference name.", "title": "Journal", "oneOf": [ { @@ -1713,6 +1750,18 @@ "title": "Text Alignment", "type": "string" }, + "seperator_between_connections": { + "default": "", + "description": "The separator between the connections in the header. The default value is empty string.", + "title": "Seperator Between Connections", + "type": "string" + }, + "use_icons_for_connections": { + "default": true, + "description": "If this option is set to true, then icons will be used for the connections in the header. The default value is true.", + "title": "Use Icons for Connections", + "type": "boolean" + }, "margins": { "allOf": [ { @@ -1840,6 +1889,8 @@ "last_updated_date_style": "Last updated in TODAY", "header_font_size": "30 pt", "text_alignment": "justified", + "seperator_between_connections": "", + "use_icons_for_connections": true, "margins": { "entry_area": { "date_and_location_width": "4.5 cm",