diff --git a/.github/workflows/publish-a-release.yaml b/.github/workflows/publish-a-release.yaml index 23e8276f..d4486933 100644 --- a/.github/workflows/publish-a-release.yaml +++ b/.github/workflows/publish-a-release.yaml @@ -14,6 +14,34 @@ jobs: name: Run Tests uses: ./.github/workflows/test.yaml + create_executables: + name: Create Executables + + strategy: + fail-fast: false + matrix: + os: [ubuntu, windows, macos] + + runs-on: ${{ matrix.os }}-latest + permissions: + contents: write + + steps: + - uses: actions/checkout@v4 + + - name: Install Hatch + uses: pypa/hatch@install + + - name: Create executable + run: | + hatch run create-executable + + - name: Upload executable + uses: softprops/action-gh-release@v2 + with: + files: | + bin/* + publish_to_pypi: name: Publish to PyPI needs: @@ -37,9 +65,6 @@ jobs: run: | hatch build - - name: Upload package to PyPI - uses: pypa/gh-action-pypi-publish@release/v1 - - name: Upload wheel and source distribution uses: softprops/action-gh-release@v2 with: @@ -47,6 +72,9 @@ jobs: dist/*.whl dist/*.tar.gz + - name: Upload package to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + publish_to_dockerhub: name: Publish to Docker Hub needs: diff --git a/.github/workflows/update-files.yaml b/.github/workflows/update-files.yaml index bc6c211e..07174ce6 100644 --- a/.github/workflows/update-files.yaml +++ b/.github/workflows/update-files.yaml @@ -27,14 +27,14 @@ jobs: - name: Update schema.json continue-on-error: true run: | - hatch run docs:update-schema + hatch run update-schema git add schema.json git commit -m "docs: update schema.json" - name: Update `examples` folder continue-on-error: true run: | - hatch run docs:update-examples + hatch run update-examples git add examples/* git add docs/assets/images/*.png git commit -m "docs: update examples" diff --git a/.gitignore b/.gitignore index 0a0c4a71..f493f687 100644 --- a/.gitignore +++ b/.gitignore @@ -186,4 +186,7 @@ rendercv_output/ .DS_Store # Profiling: -render_command.prof \ No newline at end of file +render_command.prof + +# Executables: +bin/ \ No newline at end of file diff --git a/docs/assets/images/moderncv/bullet_entry.png b/docs/assets/images/moderncv/bullet_entry.png index 81d7e712..a4306c43 100644 Binary files a/docs/assets/images/moderncv/bullet_entry.png and b/docs/assets/images/moderncv/bullet_entry.png differ diff --git a/docs/assets/images/moderncv/education_entry.png b/docs/assets/images/moderncv/education_entry.png index 0173fdad..388cf9d1 100644 Binary files a/docs/assets/images/moderncv/education_entry.png and b/docs/assets/images/moderncv/education_entry.png differ diff --git a/docs/assets/images/moderncv/experience_entry.png b/docs/assets/images/moderncv/experience_entry.png index 98f639bd..f60a144e 100644 Binary files a/docs/assets/images/moderncv/experience_entry.png and b/docs/assets/images/moderncv/experience_entry.png differ diff --git a/docs/assets/images/moderncv/normal_entry.png b/docs/assets/images/moderncv/normal_entry.png index 5dd717b9..0cc51456 100644 Binary files a/docs/assets/images/moderncv/normal_entry.png and b/docs/assets/images/moderncv/normal_entry.png differ diff --git a/docs/assets/images/moderncv/numbered_entry.png b/docs/assets/images/moderncv/numbered_entry.png index 313489eb..419ffbc3 100644 Binary files a/docs/assets/images/moderncv/numbered_entry.png and b/docs/assets/images/moderncv/numbered_entry.png differ diff --git a/docs/assets/images/moderncv/one_line_entry.png b/docs/assets/images/moderncv/one_line_entry.png index d995092f..9775fa7e 100644 Binary files a/docs/assets/images/moderncv/one_line_entry.png and b/docs/assets/images/moderncv/one_line_entry.png differ diff --git a/docs/assets/images/moderncv/publication_entry.png b/docs/assets/images/moderncv/publication_entry.png index c5d0a68a..b4f01415 100644 Binary files a/docs/assets/images/moderncv/publication_entry.png and b/docs/assets/images/moderncv/publication_entry.png differ diff --git a/docs/assets/images/moderncv/reversed_numbered_entry.png b/docs/assets/images/moderncv/reversed_numbered_entry.png index 2fdeaff1..502aa2c9 100644 Binary files a/docs/assets/images/moderncv/reversed_numbered_entry.png and b/docs/assets/images/moderncv/reversed_numbered_entry.png differ diff --git a/docs/assets/images/moderncv/text_entry.png b/docs/assets/images/moderncv/text_entry.png index b8fc54f8..a7f30005 100644 Binary files a/docs/assets/images/moderncv/text_entry.png and b/docs/assets/images/moderncv/text_entry.png differ diff --git a/docs/assets/images/sb2nov/education_entry.png b/docs/assets/images/sb2nov/education_entry.png index e50af7a8..b7fb9216 100644 Binary files a/docs/assets/images/sb2nov/education_entry.png and b/docs/assets/images/sb2nov/education_entry.png differ diff --git a/docs/assets/images/sb2nov/experience_entry.png b/docs/assets/images/sb2nov/experience_entry.png index aad4681d..78abf0fa 100644 Binary files a/docs/assets/images/sb2nov/experience_entry.png and b/docs/assets/images/sb2nov/experience_entry.png differ diff --git a/docs/assets/images/sb2nov/publication_entry.png b/docs/assets/images/sb2nov/publication_entry.png index c9628d98..6d8b6965 100644 Binary files a/docs/assets/images/sb2nov/publication_entry.png and b/docs/assets/images/sb2nov/publication_entry.png differ diff --git a/docs/developer_guide/index.md b/docs/developer_guide/index.md index e3ef620a..25493877 100644 --- a/docs/developer_guide/index.md +++ b/docs/developer_guide/index.md @@ -56,6 +56,10 @@ This is done with [Development containers](https://containers.dev/), and the env These commands are defined in the [`pyproject.toml`](https://github.com/rendercv/rendercv/blob/main/pyproject.toml) file. +- Build the package + ```bash + hatch run build + ``` - Format the code with [Black](https://github.com/psf/black) and [Ruff](https://github.com/astral-sh/ruff) ```bash hatch run format @@ -80,6 +84,18 @@ These commands are defined in the [`pyproject.toml`](https://github.com/rendercv ```bash hatch run test-and-report ``` +- Update [schema.json](https://github.com/rendercv/rendercv/blob/main/schema.json) + ```bash + hatch run update-schema + ``` +- Update [`examples`](https://github.com/rendercv/rendercv/tree/main/examples) folder + ```bash + hatch run update-examples + ``` +- Create an executable version of RenderCV with [PyInstaller](https://www.pyinstaller.org/) + ```bash + hatch run create-executables + ``` - Preview the documentation as you write it ```bash hatch run docs:serve @@ -88,14 +104,6 @@ These commands are defined in the [`pyproject.toml`](https://github.com/rendercv ```bash hatch run docs:build ``` -- Update [schema.json](https://github.com/rendercv/rendercv/blob/main/schema.json) - ```bash - hatch run docs:update-schema - ``` -- Update [`examples`](https://github.com/rendercv/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](../user_guide/structure_of_the_yaml_input_file.md)" ```bash hatch run docs:update-entry-figures diff --git a/docs/developer_guide/writing_documentation.md b/docs/developer_guide/writing_documentation.md index cc8d6f8f..39da76ef 100644 --- a/docs/developer_guide/writing_documentation.md +++ b/docs/developer_guide/writing_documentation.md @@ -13,12 +13,12 @@ Once the changes are pushed to the `main` branch, the [`deploy-docs.yaml`](https 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/rendercv/rendercv/tree/main/docs/assets/images). These examples are shown in [`README.md`](https://github.com/rendercv/rendercv/blob/main/README.md). -These files are generated using [`docs/update_examples.py`](https://github.com/rendercv/rendercv/blob/main/docs/update_examples.py). The contents of the examples are taken from the [`create_a_sample_data_model`](https://docs.rendercv.com/reference/data/#rendercv.data.create_a_sample_data_model) function from [`rendercv.data`](https://docs.rendercv.com/reference/data/). +These files are generated using [`scripts/update_examples.py`](https://github.com/rendercv/rendercv/blob/main/scripts/update_examples.py). The contents of the examples are taken from the [`create_a_sample_data_model`](https://docs.rendercv.com/reference/data/#rendercv.data.create_a_sample_data_model) function from [`rendercv.data`](https://docs.rendercv.com/reference/data/). Run the following command to update the `examples` folder. ```bash -hatch run docs:update-examples +hatch run update-examples ``` Once a new release is created on GitHub, the [`publish-to-pypi.yaml`](https://github.com/rendercv/rendercv/blob/main/.github/workflows/publish-to-pypi.yaml) workflow will be automatically triggered, and the `examples` folder will be updated to the most recent version. @@ -27,7 +27,7 @@ Once a new release is created on GitHub, the [`publish-to-pypi.yaml`](https://gi There are example figures for each entry type for each theme in the "[Structure of the YAML Input File](../user_guide/structure_of_the_yaml_input_file.md)" page. -The figures are generated using [`docs/update_entry_figures.py`](https://github.com/rendercv/rendercv/blob/main/docs/update_entry_figures.py). +The figures are generated using [`scripts/update_entry_figures.py`](https://github.com/rendercv/rendercv/blob/main/scripts/update_entry_figures.py). Run the following command to update the figures. @@ -41,12 +41,12 @@ Once a new release is created on GitHub, the [`publish-to-pypi.yaml`](https://gi 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_schema.py`](https://github.com/rendercv/rendercv/blob/main/docs/update_schema.py). It uses [`generate_json_schema`](https://docs.rendercv.com/reference/data/#rendercv.data.generate_json_schema) function from [`rendercv.data`](https://docs.rendercv.com/reference/data/). +The JSON Schema is also generated using [`scripts/update_schema.py`](https://github.com/rendercv/rendercv/blob/main/scripts/update_schema.py). It uses [`generate_json_schema`](https://docs.rendercv.com/reference/data/#rendercv.data.generate_json_schema) function from [`rendercv.data`](https://docs.rendercv.com/reference/data/). Run the following command to update the JSON Schema. ```bash -hatch run docs:update-schema +hatch run update-schema ``` Once a new release is created on GitHub, the [`publish-to-pypi.yaml`](https://github.com/rendercv/rendercv/blob/main/.github/workflows/publish-to-pypi.yaml) workflow will be automatically triggered, and `schema.json` will be updated to the most recent version. diff --git a/docs/dynamic_content_generation.py b/docs/dynamic_content_generation.py new file mode 100644 index 00000000..6a472d5d --- /dev/null +++ b/docs/dynamic_content_generation.py @@ -0,0 +1,150 @@ +"""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 io +import pathlib +from typing import get_args + +import pydantic +import ruamel.yaml + +import rendercv.data as data +import rendercv.themes.options as theme_options + +repository_root = pathlib.Path(__file__).parent.parent +rendercv_path = repository_root / "rendercv" +image_assets_directory = pathlib.Path(__file__).parent / "assets" / "images" + + +class SampleEntries(pydantic.BaseModel): + education_entry: data.EducationEntry + experience_entry: data.ExperienceEntry + normal_entry: data.NormalEntry + publication_entry: data.PublicationEntry + one_line_entry: data.OneLineEntry + bullet_entry: data.BulletEntry + numbered_entry: data.NumberedEntry + reversed_numbered_entry: data.ReversedNumberedEntry + text_entry: str + + +def dictionary_to_yaml(dictionary: dict): + """Converts a dictionary to a YAML string. + + Args: + dictionary: The dictionary to be converted to YAML. + Returns: + The YAML string. + """ + yaml_object = ruamel.yaml.YAML() + yaml_object.width = 60 + yaml_object.indent(mapping=2, sequence=4, offset=2) + with io.StringIO() as string_stream: + yaml_object.dump(dictionary, string_stream) + return string_stream.getvalue() + + +def define_env(env): + # See https://mkdocs-macros-plugin.readthedocs.io/en/latest/macros/ + sample_entries = data.read_a_yaml_file( + repository_root / "docs" / "user_guide" / "sample_entries.yaml" + ) + # validate the parsed dictionary by creating an instance of SampleEntries: + SampleEntries(**sample_entries) + + entries_showcase = {} + for entry_name, entry in sample_entries.items(): + proper_entry_name = entry_name.replace("_", " ").title().replace(" ", "") + entries_showcase[proper_entry_name] = { + "yaml": dictionary_to_yaml(entry), + "figures": [ + { + "path": f"../assets/images/{theme}/{entry_name}.png", + "alt_text": f"{proper_entry_name} in {theme}", + "theme": theme, + } + for theme in data.available_themes + ], + } + + env.variables["sample_entries"] = entries_showcase + + # For theme templates reference docs + themes_path = rendercv_path / "themes" + theme_templates = {} + for theme in data.available_themes: + theme_templates[theme] = {} + for theme_file in themes_path.glob(f"{theme}/*.typ"): + theme_templates[theme][theme_file.stem] = theme_file.read_text() + + # Update ordering of theme templates + order = [ + "Preamble.j2", + "Header.j2", + "SectionBeginning.j2", + "SectionEnding.j2", + "TextEntry.j2", + "BulletEntry.j2", + "OneLineEntry.j2", + "EducationEntry.j2", + "ExperienceEntry.j2", + "NormalEntry.j2", + "PublicationEntry.j2", + ] + theme_templates[theme] = {key: theme_templates[theme][key] for key in order} + + if theme != "markdown": + theme_templates[theme] = { + f"{key}.typ": value for key, value in theme_templates[theme].items() + } + else: + theme_templates[theme] = { + f"{key}.md": value for key, value in theme_templates[theme].items() + } + + env.variables["theme_templates"] = theme_templates + + # Available themes strings (put available themes between ``) + themes = [f"`{theme}`" for theme in data.available_themes] + env.variables["available_themes"] = ", ".join(themes) + + # Available social networks strings (put available social networks between ``) + social_networks = [ + f"`{social_network}`" for social_network in data.available_social_networks + ] + env.variables["available_social_networks"] = ", ".join(social_networks) + + # Others: + env.variables["available_page_sizes"] = ", ".join( + [f"`{page_size}`" for page_size in get_args(theme_options.PageSize)] + ) + env.variables["available_font_families"] = ", ".join( + [f"`{font_family}`" for font_family in get_args(theme_options.FontFamily)] + ) + env.variables["available_text_alignments"] = ", ".join( + [ + f"`{text_alignment}`" + for text_alignment in get_args(theme_options.TextAlignment) + ] + ) + env.variables["available_header_alignments"] = ", ".join( + [ + f"`{header_alignment}`" + for header_alignment in get_args(theme_options.Alignment) + ] + ) + env.variables["available_section_title_types"] = ", ".join( + [ + f"`{section_title_type}`" + for section_title_type in get_args( + get_args(theme_options.SectionTitleType)[0] + ) + ] + ) + env.variables["available_bullets"] = ", ".join( + [f"`{bullet}`" for bullet in get_args(theme_options.BulletPoint)] + ) diff --git a/mkdocs.yaml b/mkdocs.yaml index 9db3bfe1..75116d05 100644 --- a/mkdocs.yaml +++ b/mkdocs.yaml @@ -124,7 +124,7 @@ markdown_extensions: plugins: - search - macros: # mkdocs-macros-plugin - module_name: docs/update_entry_figures + module_name: docs/dynamic_content_generation - mkdocstrings: handlers: python: diff --git a/pyproject.toml b/pyproject.toml index 2ca7edec..0ccbfeea 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -126,15 +126,16 @@ rendercv = 'rendercv.cli:app' installer = "uv" python = "3.13" dependencies = [ - "ruff", # to lint and format the code - "black", # to format the code - "ipython", # for ipython shell - "pyright", # to check the types - "pre-commit", # to run the checks before committing - "pytest==8.3.4", # to run the tests - "coverage==7.6.10", # to generate coverage reports - "pypdf==5.1.0", # to read PDF files - "snakeviz==2.2.2", # for profiling + "ruff", # to lint and format the code + "black", # to format the code + "ipython", # for ipython shell + "pyright", # to check the types + "pre-commit", # to run the checks before committing + "pytest==8.3.4", # to run the tests + "coverage==7.6.10", # to generate coverage reports + "pypdf==5.1.0", # to read PDF files + "snakeviz==2.2.2", # for profiling + "pyinstaller==6.11.1", # to build the executable ] features = ["full"] # to install full optional dependencies [tool.hatch.envs.default.scripts] @@ -154,6 +155,12 @@ test = "pytest" # hatch run test test-and-report = "coverage run -m pytest && coverage combine && coverage report && coverage html --show-contexts" # hatch run test-and-report # Profile render command profile-render-command = "python -m cProfile -o render_command.prof -m rendercv render examples/John_Doe_ClassicTheme_CV.yaml && snakeviz render_command.prof" +# Update schema.json: +update-schema = "python scripts/update_schema.py" # hatch run update-schema +# Update `examples` folder: +update-examples = "python scripts/update_examples.py" # hatch run update-examples +# Create executables +create-executable = "python scripts/create_executable.py" # hatch run create-executables [tool.hatch.envs.test] template = "default" @@ -178,12 +185,8 @@ features = ["full"] # to install full optional dependencies 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 -# 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 +update-entry-figures = "python scripts/update_entry_figures.py" # hatch run docs:update-entry-figures # ====================================================================================== # Virtual Environments Above =========================================================== # ====================================================================================== diff --git a/scripts/create_executable.py b/scripts/create_executable.py new file mode 100644 index 00000000..5a72e121 --- /dev/null +++ b/scripts/create_executable.py @@ -0,0 +1,62 @@ +import os +import pathlib +import subprocess +import sys + + +def create_executable(): + # Make sure the current working directory is the root of the project: + root = pathlib.Path(__file__).parent.parent + os.chdir(root) + + rendercv_file_path = root / "rendercv.py" + rendercv_file_path.touch() + rendercv_file_path.write_text("import rendercv.cli as cli; cli.app()") + + # Run pyinstaller: + subprocess.run( + [ + sys.executable, + "-m", + "PyInstaller", + "--onefile", + "--clean", + "--collect-all", + "rendercv", + "--collect-all", + "rendercv_fonts", + "--distpath", + "bin", + str(rendercv_file_path), + ], + check=True, + ) + + # Remove the temporary file: + rendercv_file_path.unlink() + (root / "rendercv.spec").unlink() + + # Rename the executable: + platform = { + "linux": "linux", + "darwin": "macos", + "win32": "windows", + } + if sys.platform == "win32": + executable_path = root / "bin" / "rendercv.exe" + executable_path.rename( + root + / "bin" + / f"rendercv-{platform[sys.platform]}-{os.environ['PROCESSOR_ARCHITECTURE']}" + ) + else: + executable_path = root / "bin" / "rendercv" + executable_path.rename( + root / "bin" / f"rendercv-{platform[sys.platform]}-{os.uname().machine}" + ) + + print('Executable created at "bin" folder.') # NOQA: T201 + + +if __name__ == "__main__": + create_executable() diff --git a/docs/update_entry_figures.py b/scripts/update_entry_figures.py similarity index 54% rename from docs/update_entry_figures.py rename to scripts/update_entry_figures.py index 75f774ed..ff115326 100644 --- a/docs/update_entry_figures.py +++ b/scripts/update_entry_figures.py @@ -5,24 +5,20 @@ example entries found in are coming from this script. """ -import io import pathlib import shutil import tempfile -from typing import get_args import fitz import pdfCropMargins import pydantic -import ruamel.yaml import rendercv.data as data import rendercv.renderer as renderer -import rendercv.themes.options as theme_options repository_root = pathlib.Path(__file__).parent.parent rendercv_path = repository_root / "rendercv" -image_assets_directory = pathlib.Path(__file__).parent / "assets" / "images" +image_assets_directory = repository_root / "docs" / "assets" / "images" class SampleEntries(pydantic.BaseModel): @@ -37,124 +33,6 @@ class SampleEntries(pydantic.BaseModel): text_entry: str -def dictionary_to_yaml(dictionary: dict): - """Converts a dictionary to a YAML string. - - Args: - dictionary: The dictionary to be converted to YAML. - Returns: - The YAML string. - """ - yaml_object = ruamel.yaml.YAML() - yaml_object.width = 60 - yaml_object.indent(mapping=2, sequence=4, offset=2) - with io.StringIO() as string_stream: - yaml_object.dump(dictionary, string_stream) - return string_stream.getvalue() - - -def define_env(env): - # See https://mkdocs-macros-plugin.readthedocs.io/en/latest/macros/ - sample_entries = data.read_a_yaml_file( - repository_root / "docs" / "user_guide" / "sample_entries.yaml" - ) - # validate the parsed dictionary by creating an instance of SampleEntries: - SampleEntries(**sample_entries) - - entries_showcase = {} - for entry_name, entry in sample_entries.items(): - proper_entry_name = entry_name.replace("_", " ").title().replace(" ", "") - entries_showcase[proper_entry_name] = { - "yaml": dictionary_to_yaml(entry), - "figures": [ - { - "path": f"../assets/images/{theme}/{entry_name}.png", - "alt_text": f"{proper_entry_name} in {theme}", - "theme": theme, - } - for theme in data.available_themes - ], - } - - env.variables["sample_entries"] = entries_showcase - - # For theme templates reference docs - themes_path = rendercv_path / "themes" - theme_templates = {} - for theme in data.available_themes: - theme_templates[theme] = {} - for theme_file in themes_path.glob(f"{theme}/*.typ"): - theme_templates[theme][theme_file.stem] = theme_file.read_text() - - # Update ordering of theme templates - order = [ - "Preamble.j2", - "Header.j2", - "SectionBeginning.j2", - "SectionEnding.j2", - "TextEntry.j2", - "BulletEntry.j2", - "OneLineEntry.j2", - "EducationEntry.j2", - "ExperienceEntry.j2", - "NormalEntry.j2", - "PublicationEntry.j2", - ] - theme_templates[theme] = {key: theme_templates[theme][key] for key in order} - - if theme != "markdown": - theme_templates[theme] = { - f"{key}.typ": value for key, value in theme_templates[theme].items() - } - else: - theme_templates[theme] = { - f"{key}.md": value for key, value in theme_templates[theme].items() - } - - env.variables["theme_templates"] = theme_templates - - # Available themes strings (put available themes between ``) - themes = [f"`{theme}`" for theme in data.available_themes] - env.variables["available_themes"] = ", ".join(themes) - - # Available social networks strings (put available social networks between ``) - social_networks = [ - f"`{social_network}`" for social_network in data.available_social_networks - ] - env.variables["available_social_networks"] = ", ".join(social_networks) - - # Others: - env.variables["available_page_sizes"] = ", ".join( - [f"`{page_size}`" for page_size in get_args(theme_options.PageSize)] - ) - env.variables["available_font_families"] = ", ".join( - [f"`{font_family}`" for font_family in get_args(theme_options.FontFamily)] - ) - env.variables["available_text_alignments"] = ", ".join( - [ - f"`{text_alignment}`" - for text_alignment in get_args(theme_options.TextAlignment) - ] - ) - env.variables["available_header_alignments"] = ", ".join( - [ - f"`{header_alignment}`" - for header_alignment in get_args(theme_options.Alignment) - ] - ) - env.variables["available_section_title_types"] = ", ".join( - [ - f"`{section_title_type}`" - for section_title_type in get_args( - get_args(theme_options.SectionTitleType)[0] - ) - ] - ) - env.variables["available_bullets"] = ", ".join( - [f"`{bullet}`" for bullet in get_args(theme_options.BulletPoint)] - ) - - def render_pngs_from_pdf(pdf_file_path: pathlib.Path) -> list[pathlib.Path]: """Render a PNG file for each page of the given PDF file. diff --git a/docs/update_examples.py b/scripts/update_examples.py similarity index 97% rename from docs/update_examples.py rename to scripts/update_examples.py index 23417ad0..f172072c 100644 --- a/docs/update_examples.py +++ b/scripts/update_examples.py @@ -10,7 +10,7 @@ import rendercv.renderer as renderer repository_root = pathlib.Path(__file__).parent.parent rendercv_path = repository_root / "rendercv" -image_assets_directory = pathlib.Path(__file__).parent / "assets" / "images" +image_assets_directory = repository_root / "docs" / "assets" / "images" def generate_examples(): diff --git a/docs/update_schema.py b/scripts/update_schema.py similarity index 100% rename from docs/update_schema.py rename to scripts/update_schema.py diff --git a/tests/conftest.py b/tests/conftest.py index 7aef28dd..41b37a0f 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -26,7 +26,6 @@ from rendercv.renderer import templater # reference files with the latest output. update_testdata = False -# copy sample entries from docs/update_rendercv_files.py: education_entry_dictionary = { "institution": "Boğaziçi University", "location": "Istanbul, Turkey", diff --git a/tests/test_hatch_scripts.py b/tests/test_hatch_scripts.py index 4479342d..2d719bea 100644 --- a/tests/test_hatch_scripts.py +++ b/tests/test_hatch_scripts.py @@ -1,5 +1,4 @@ import subprocess -import sys import pytest @@ -9,16 +8,19 @@ import pytest [ "format", "lint", - "sort-imports", "check-types", + "precommit", + "update-schema", + "update-examples", + "create-executable", "docs:build", - "docs:update-schema", - "docs:update-examples", "docs:update-entry-figures", - # "docs:serve", - # "test:run", - # "test:run-and-report", ], ) def test_default_format(script_name): - subprocess.run([sys.executable, "-m", "hatch", "run", script_name], check=False) + # Check if hatch is installed: + try: + subprocess.run(["hatch", "--version"], check=True) + subprocess.run(["hatch", "run", script_name], check=True) + except FileNotFoundError: + pass