diff options
Diffstat (limited to 'sysutils/py-rendercv')
17 files changed, 340 insertions, 0 deletions
diff --git a/sysutils/py-rendercv/Makefile b/sysutils/py-rendercv/Makefile new file mode 100644 index 000000000000..4eb46c2ca27c --- /dev/null +++ b/sysutils/py-rendercv/Makefile @@ -0,0 +1,43 @@ +PORTNAME= rendercv +DISTVERSION= 2.5 +CATEGORIES= sysutils python +MASTER_SITES= PYPI +PKGNAMEPREFIX= ${PYTHON_PKGNAMEPREFIX} + +MAINTAINER= dtxdf@FreeBSD.org +COMMENT= Typst-based CV/resume generator +WWW= https://github.com/rendercv/rendercv \ + https://pypi.org/project/rendercv + +LICENSE= MIT + +BUILD_DEPENDS= ${PYTHON_PKGNAMEPREFIX}uv-build>=0:devel/py-uv-build@${PY_FLAVOR} +RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}Jinja2>=0:devel/py-Jinja2@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}phonenumbers>=0:devel/py-phonenumbers@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}pydantic2>=0:devel/py-pydantic2@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}pydantic-extra-types>=0:devel/py-pydantic-extra-types@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}email-validator>=0:mail/py-email-validator@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}ruamel.yaml>=0:devel/py-ruamel.yaml@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}packaging>=0:devel/py-packaging@${PY_FLAVOR} + +USES= python +USE_PYTHON= autoplist pep517 + +NO_ARCH= yes + +OPTIONS_DEFINE= CLI MARKDOWN WATCHDOG TYPST FONT +OPTIONS_DEFAULT= CLI MARKDOWN WATCHDOG TYPST FONT + +CLI_DESC= Enable Command-line interface support +MARKDOWN_DESC= Convert Markdown to HTML +WATCHDOG_DESC= Monitor files for updates +TYPST_DESC= Render PDF from Typst source files +FONT_DESC= Font files for RenderCV + +CLI_RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}typer>=0:devel/py-typer@${PY_FLAVOR} +MARKDOWN_RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}markdown>=0:textproc/py-markdown@${PY_FLAVOR} +WATCHDOG_RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}watchdog>=0:devel/py-watchdog@${PY_FLAVOR} +TYPST_RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}typst>=0:textproc/py-typst@${PY_FLAVOR} +FONT_RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}rendercv-fonts>=0:x11-fonts/py-rendercv-fonts@${PY_FLAVOR} + +.include <bsd.port.mk> diff --git a/sysutils/py-rendercv/distinfo b/sysutils/py-rendercv/distinfo new file mode 100644 index 000000000000..c6f5b4128d33 --- /dev/null +++ b/sysutils/py-rendercv/distinfo @@ -0,0 +1,3 @@ +TIMESTAMP = 1766178034 +SHA256 (rendercv-2.5.tar.gz) = 7e5b51c7ed4340fa2e78084a3d74aa4784aa3e42e53d585c3c8433082982434b +SIZE (rendercv-2.5.tar.gz) = 77147 diff --git a/sysutils/py-rendercv/files/patch-src_rendercv_cli_error__handler.py b/sysutils/py-rendercv/files/patch-src_rendercv_cli_error__handler.py new file mode 100644 index 000000000000..7c8350de5c53 --- /dev/null +++ b/sysutils/py-rendercv/files/patch-src_rendercv_cli_error__handler.py @@ -0,0 +1,20 @@ +--- src/rendercv/cli/error_handler.py.orig 2025-12-20 00:46:25 UTC ++++ src/rendercv/cli/error_handler.py +@@ -8,7 +8,7 @@ from rendercv.exception import RenderCVUserError + from rendercv.exception import RenderCVUserError + + +-def handle_user_errors[T, **P](function: Callable[P, None]) -> Callable[P, None]: ++def handle_user_errors(function): + """Decorator that catches user errors and displays friendly messages without stack traces. + + Why: +@@ -33,7 +33,7 @@ def handle_user_errors[T, **P](function: Callable[P, N + """ + + @functools.wraps(function) +- def wrapper(*args: P.args, **kwargs: P.kwargs) -> None: ++ def wrapper(*args, **kwargs) -> None: + try: + return function(*args, **kwargs) + except RenderCVUserError as e: diff --git a/sysutils/py-rendercv/files/patch-src_rendercv_cli_render__command_run__rendercv.py b/sysutils/py-rendercv/files/patch-src_rendercv_cli_render__command_run__rendercv.py new file mode 100644 index 000000000000..3ede1d8e2ce3 --- /dev/null +++ b/sysutils/py-rendercv/files/patch-src_rendercv_cli_render__command_run__rendercv.py @@ -0,0 +1,21 @@ +--- src/rendercv/cli/render_command/run_rendercv.py.orig 2025-12-20 00:43:25 UTC ++++ src/rendercv/cli/render_command/run_rendercv.py +@@ -19,13 +19,13 @@ from .progress_panel import ProgressPanel + from .progress_panel import ProgressPanel + + +-def timed_step[T, **P]( ++def timed_step( + message: str, + progress_panel: ProgressPanel, +- func: Callable[P, T], +- *args: P.args, +- **kwargs: P.kwargs, +-) -> T: ++ func, ++ *args, ++ **kwargs, ++): + """Execute function, measure timing, and update progress panel with result. + + Why: diff --git a/sysutils/py-rendercv/files/patch-src_rendercv_renderer_templater_entry__templates__from__input.py b/sysutils/py-rendercv/files/patch-src_rendercv_renderer_templater_entry__templates__from__input.py new file mode 100644 index 000000000000..d3fbd6e1175e --- /dev/null +++ b/sysutils/py-rendercv/files/patch-src_rendercv_renderer_templater_entry__templates__from__input.py @@ -0,0 +1,20 @@ +--- src/rendercv/renderer/templater/entry_templates_from_input.py.orig 2025-12-20 00:49:48 UTC ++++ src/rendercv/renderer/templater/entry_templates_from_input.py +@@ -14,14 +14,14 @@ uppercase_word_pattern = re.compile(r"\b[A-Z_]+\b") + uppercase_word_pattern = re.compile(r"\b[A-Z_]+\b") + + +-def render_entry_templates[EntryType: Entry]( +- entry: EntryType, ++def render_entry_templates( ++ entry, + *, + templates: Templates, + locale: Locale, + show_time_span: bool, + current_date: Date, +-) -> EntryType: ++): + """Expand entry templates by substituting field placeholders with processed values. + + Why: diff --git a/sysutils/py-rendercv/files/patch-src_rendercv_schema_models_cv_entries_bases_entry__with__complex__fields.py b/sysutils/py-rendercv/files/patch-src_rendercv_schema_models_cv_entries_bases_entry__with__complex__fields.py new file mode 100644 index 000000000000..c3e40f6ba6fd --- /dev/null +++ b/sysutils/py-rendercv/files/patch-src_rendercv_schema_models_cv_entries_bases_entry__with__complex__fields.py @@ -0,0 +1,11 @@ +--- src/rendercv/schema/models/cv/entries/bases/entry_with_complex_fields.py.orig 2025-12-19 21:42:57 UTC ++++ src/rendercv/schema/models/cv/entries/bases/entry_with_complex_fields.py +@@ -37,7 +37,7 @@ def validate_exact_date(date: str | int) -> str | int: + return date + + +-type ExactDate = Annotated[str | int, pydantic.AfterValidator(validate_exact_date)] ++ExactDate = Annotated[str | int, pydantic.AfterValidator(validate_exact_date)] + + + def get_date_object(date: str | int, current_date: Date | None = None) -> Date: diff --git a/sysutils/py-rendercv/files/patch-src_rendercv_schema_models_cv_entries_bases_entry__with__date.py b/sysutils/py-rendercv/files/patch-src_rendercv_schema_models_cv_entries_bases_entry__with__date.py new file mode 100644 index 000000000000..8c792c689936 --- /dev/null +++ b/sysutils/py-rendercv/files/patch-src_rendercv_schema_models_cv_entries_bases_entry__with__date.py @@ -0,0 +1,11 @@ +--- src/rendercv/schema/models/cv/entries/bases/entry_with_date.py.orig 2025-12-19 21:34:29 UTC ++++ src/rendercv/schema/models/cv/entries/bases/entry_with_date.py +@@ -31,7 +31,7 @@ def validate_arbitrary_date(date: int | str) -> int | + return date + + +-type ArbitraryDate = Annotated[ ++ArbitraryDate = Annotated[ + int | str, pydantic.AfterValidator(validate_arbitrary_date) + ] + diff --git a/sysutils/py-rendercv/files/patch-src_rendercv_schema_models_cv_section.py b/sysutils/py-rendercv/files/patch-src_rendercv_schema_models_cv_section.py new file mode 100644 index 000000000000..d2f7a9c12c81 --- /dev/null +++ b/sysutils/py-rendercv/files/patch-src_rendercv_schema_models_cv_section.py @@ -0,0 +1,46 @@ +--- src/rendercv/schema/models/cv/section.py.orig 2025-12-19 21:43:39 UTC ++++ src/rendercv/schema/models/cv/section.py +@@ -21,7 +21,7 @@ from .entries.reversed_numbered import ReversedNumbere + # Below needs to be updated when new entry types are added. + + # str is an entry type (TextEntry) but not a model, so it's not included in EntryModel. +-type EntryModel = ( ++EntryModel = ( + OneLineEntry + | NormalEntry + | ExperienceEntry +@@ -31,13 +31,22 @@ type EntryModel = ( + | NumberedEntry + | ReversedNumberedEntry + ) +-type Entry = EntryModel | str ++Entry = EntryModel | str + ######################################################################################## +-available_entry_models: tuple[type[EntryModel], ...] = get_args(EntryModel.__value__) ++available_entry_models: tuple[type[EntryModel], ...] = ( ++ OneLineEntry, ++ NormalEntry, ++ ExperienceEntry, ++ EducationEntry, ++ PublicationEntry, ++ BulletEntry, ++ NumberedEntry, ++ ReversedNumberedEntry ++) + available_entry_type_names: tuple[str, ...] = tuple( + [entry_type.__name__ for entry_type in available_entry_models] + ["TextEntry"] + ) +-type ListOfEntries = list[str] | reduce( # pyright: ignore[reportInvalidTypeForm] ++ListOfEntries = list[str] | reduce( # pyright: ignore[reportInvalidTypeForm] + or_, [list[entry_type] for entry_type in available_entry_models] + ) + +@@ -244,7 +253,7 @@ def validate_section(sections_input: Any) -> Any: + # Create a custom type named Section, which is a list of entries. The entries can be any + # of the available entry types. The section is validated with the `validate_section` + # function. +-type Section = Annotated[ ++Section = Annotated[ + pydantic.json_schema.SkipJsonSchema[Any] | ListOfEntries, + pydantic.BeforeValidator(lambda entries: validate_section(entries)), + ] diff --git a/sysutils/py-rendercv/files/patch-src_rendercv_schema_models_cv_social__network.py b/sysutils/py-rendercv/files/patch-src_rendercv_schema_models_cv_social__network.py new file mode 100644 index 000000000000..50d71355c92c --- /dev/null +++ b/sysutils/py-rendercv/files/patch-src_rendercv_schema_models_cv_social__network.py @@ -0,0 +1,20 @@ +--- src/rendercv/schema/models/cv/social_network.py.orig 2025-12-19 21:44:26 UTC ++++ src/rendercv/schema/models/cv/social_network.py +@@ -10,7 +10,7 @@ url_validator = pydantic.TypeAdapter(pydantic.HttpUrl) + from ..base import BaseModelWithoutExtraKeys + + url_validator = pydantic.TypeAdapter(pydantic.HttpUrl) +-type SocialNetworkName = Literal[ ++SocialNetworkName = Literal[ + "LinkedIn", + "GitHub", + "GitLab", +@@ -27,7 +27,7 @@ type SocialNetworkName = Literal[ + "Leetcode", + "X", + ] +-available_social_networks = get_args(SocialNetworkName.__value__) ++#available_social_networks = get_args(SocialNetworkName.__value__) + url_dictionary: dict[SocialNetworkName, str] = { + "LinkedIn": "https://linkedin.com/in/", + "GitHub": "https://github.com/", diff --git a/sysutils/py-rendercv/files/patch-src_rendercv_schema_models_design_built__in__design.py b/sysutils/py-rendercv/files/patch-src_rendercv_schema_models_design_built__in__design.py new file mode 100644 index 000000000000..2519ce6c6ec4 --- /dev/null +++ b/sysutils/py-rendercv/files/patch-src_rendercv_schema_models_design_built__in__design.py @@ -0,0 +1,22 @@ +--- src/rendercv/schema/models/design/built_in_design.py.orig 2025-12-19 21:32:57 UTC ++++ src/rendercv/schema/models/design/built_in_design.py +@@ -37,14 +37,13 @@ def discover_other_themes() -> list[type[ClassicTheme] + + return discovered + ++discovered_other_themes = discover_other_themes() + + # Build discriminated union dynamically +-type BuiltInDesign = Annotated[ +- ClassicTheme | reduce(or_, discover_other_themes()), # pyright: ignore[reportInvalidTypeForm] ++BuiltInDesign = Annotated[ ++ ClassicTheme | reduce(or_, discovered_other_themes), # pyright: ignore[reportInvalidTypeForm] + pydantic.Field(discriminator="theme"), + ] +-available_themes: list[str] = [ +- ThemeClass.model_fields["theme"].default +- for ThemeClass in get_args(get_args(BuiltInDesign.__value__)[0]) +-] ++discovered_other_themes.append(ClassicTheme) ++available_themes: list[str] = [ThemeClass.model_fields["theme"].default for ThemeClass in discovered_other_themes] + built_in_design_adapter = pydantic.TypeAdapter(BuiltInDesign) diff --git a/sysutils/py-rendercv/files/patch-src_rendercv_schema_models_design_classic__theme.py b/sysutils/py-rendercv/files/patch-src_rendercv_schema_models_design_classic__theme.py new file mode 100644 index 000000000000..30f05b163fbc --- /dev/null +++ b/sysutils/py-rendercv/files/patch-src_rendercv_schema_models_design_classic__theme.py @@ -0,0 +1,23 @@ +--- src/rendercv/schema/models/design/classic_theme.py.orig 2025-12-19 21:33:55 UTC ++++ src/rendercv/schema/models/design/classic_theme.py +@@ -7,14 +7,14 @@ from rendercv.schema.models.design.typst_dimension imp + from rendercv.schema.models.design.font_family import FontFamily as FontFamilyType + from rendercv.schema.models.design.typst_dimension import TypstDimension + +-type Bullet = Literal["●", "•", "◦", "-", "◆", "★", "■", "—", "○"] +-type BodyAlignment = Literal["left", "justified", "justified-with-no-hyphenation"] +-type Alignment = Literal["left", "center", "right"] +-type SectionTitleType = Literal[ ++Bullet = Literal["●", "•", "◦", "-", "◆", "★", "■", "—", "○"] ++BodyAlignment = Literal["left", "justified", "justified-with-no-hyphenation"] ++Alignment = Literal["left", "center", "right"] ++SectionTitleType = Literal[ + "with_partial_line", "with_full_line", "without_line", "moderncv" + ] +-type PhoneNumberFormatType = Literal["national", "international", "E164"] +-type PageSize = Literal["a4", "a5", "us-letter", "us-executive"] ++PhoneNumberFormatType = Literal["national", "international", "E164"] ++PageSize = Literal["a4", "a5", "us-letter", "us-executive"] + + length_common_description = ( + "It can be specified with units (cm, in, pt, mm, ex, em). For example, `0.1cm`." diff --git a/sysutils/py-rendercv/files/patch-src_rendercv_schema_models_design_font__family.py b/sysutils/py-rendercv/files/patch-src_rendercv_schema_models_design_font__family.py new file mode 100644 index 000000000000..0563084ad505 --- /dev/null +++ b/sysutils/py-rendercv/files/patch-src_rendercv_schema_models_design_font__family.py @@ -0,0 +1,8 @@ +--- src/rendercv/schema/models/design/font_family.py.orig 2025-12-19 21:33:15 UTC ++++ src/rendercv/schema/models/design/font_family.py +@@ -50,4 +50,4 @@ available_font_families = sorted( + ) + + +-type FontFamily = SkipJsonSchema[str] | Literal[*tuple(available_font_families)] # pyright: ignore[reportInvalidTypeForm] ++FontFamily = SkipJsonSchema[str] | Literal[*tuple(available_font_families)] # pyright: ignore[reportInvalidTypeForm] diff --git a/sysutils/py-rendercv/files/patch-src_rendercv_schema_models_design_typst__dimension.py b/sysutils/py-rendercv/files/patch-src_rendercv_schema_models_design_typst__dimension.py new file mode 100644 index 000000000000..f9c2dfb78d2c --- /dev/null +++ b/sysutils/py-rendercv/files/patch-src_rendercv_schema_models_design_typst__dimension.py @@ -0,0 +1,8 @@ +--- src/rendercv/schema/models/design/typst_dimension.py.orig 2025-12-19 21:33:37 UTC ++++ src/rendercv/schema/models/design/typst_dimension.py +@@ -29,4 +29,4 @@ def validate_typst_dimension(dimension: str) -> str: + return dimension + + +-type TypstDimension = Annotated[str, pydantic.AfterValidator(validate_typst_dimension)] ++TypstDimension = Annotated[str, pydantic.AfterValidator(validate_typst_dimension)] diff --git a/sysutils/py-rendercv/files/patch-src_rendercv_schema_models_locale_locale.py b/sysutils/py-rendercv/files/patch-src_rendercv_schema_models_locale_locale.py new file mode 100644 index 000000000000..78889b6444b0 --- /dev/null +++ b/sysutils/py-rendercv/files/patch-src_rendercv_schema_models_locale_locale.py @@ -0,0 +1,22 @@ +--- src/rendercv/schema/models/locale/locale.py.orig 2025-12-19 21:44:44 UTC ++++ src/rendercv/schema/models/locale/locale.py +@@ -37,14 +37,13 @@ def discover_other_locales() -> list[type[EnglishLocal + + return discovered + ++discovered_other_locales = discover_other_locales() + + # Build discriminated union dynamically +-type Locale = Annotated[ +- EnglishLocale | reduce(or_, discover_other_locales()), # pyright: ignore[reportInvalidTypeForm] ++Locale = Annotated[ ++ EnglishLocale | reduce(or_, discovered_other_locales), # pyright: ignore[reportInvalidTypeForm] + pydantic.Field(discriminator="language"), + ] +-available_locales = [ +- LocaleModel.model_fields["language"].default +- for LocaleModel in get_args(get_args(Locale.__value__)[0]) +-] ++discovered_other_locales.append(EnglishLocale) ++available_locales = [LocaleModel.model_fields["language"].default for LocaleModel in discovered_other_locales] + locale_adapter = pydantic.TypeAdapter(Locale) diff --git a/sysutils/py-rendercv/files/patch-src_rendercv_schema_models_path.py b/sysutils/py-rendercv/files/patch-src_rendercv_schema_models_path.py new file mode 100644 index 000000000000..74b7cab315b6 --- /dev/null +++ b/sysutils/py-rendercv/files/patch-src_rendercv_schema_models_path.py @@ -0,0 +1,19 @@ +--- src/rendercv/schema/models/path.py.orig 2025-12-19 21:40:25 UTC ++++ src/rendercv/schema/models/path.py +@@ -60,14 +60,14 @@ def serialize_path(path: pathlib.Path) -> str: + return str(path.relative_to(pathlib.Path.cwd())) + + +-type ExistingPathRelativeToInput = Annotated[ ++ExistingPathRelativeToInput = Annotated[ + pathlib.Path, + pydantic.AfterValidator( + lambda path, info: resolve_relative_path(path, info, must_exist=True) + ), + ] + +-type PlannedPathRelativeToInput = Annotated[ ++PlannedPathRelativeToInput = Annotated[ + pathlib.Path, + pydantic.AfterValidator( + lambda path, info: resolve_relative_path(path, info, must_exist=False) diff --git a/sysutils/py-rendercv/files/patch-src_rendercv_schema_variant__pydantic__model__generator.py b/sysutils/py-rendercv/files/patch-src_rendercv_schema_variant__pydantic__model__generator.py new file mode 100644 index 000000000000..8760ecb47deb --- /dev/null +++ b/sysutils/py-rendercv/files/patch-src_rendercv_schema_variant__pydantic__model__generator.py @@ -0,0 +1,38 @@ +--- src/rendercv/schema/variant_pydantic_model_generator.py.orig 2025-12-19 21:48:58 UTC ++++ src/rendercv/schema/variant_pydantic_model_generator.py +@@ -6,17 +6,17 @@ from rendercv.exception import RenderCVInternalError + + from rendercv.exception import RenderCVInternalError + +-type FieldSpec = tuple[type[Any], FieldInfo] ++FieldSpec = tuple[type[Any], FieldInfo] + + +-def create_variant_pydantic_model[T: pydantic.BaseModel]( ++def create_variant_pydantic_model( + variant_name: str, + defaults: dict[str, Any], +- base_class: type[T], ++ base_class, + discriminator_field: str, + class_name_suffix: str, + module_name: str, +-) -> type[T]: ++): + """Create Pydantic model variant with customized defaults. + + Why: +@@ -190,10 +190,10 @@ def create_discriminator_field_spec( + return (cast(type[Any], field_annotation), new_field) + + +-def deep_merge_nested_object[T: pydantic.BaseModel]( +- base_nested_obj: T, ++def deep_merge_nested_object( ++ base_nested_obj, + updates: dict[str, Any], +-) -> T: ++): + """Recursively merge nested dictionary updates into Pydantic model instance. + + Why: diff --git a/sysutils/py-rendercv/pkg-descr b/sysutils/py-rendercv/pkg-descr new file mode 100644 index 000000000000..58a97762cbe9 --- /dev/null +++ b/sysutils/py-rendercv/pkg-descr @@ -0,0 +1,5 @@ +RenderCV is a python tool for creating a CV from YAML. + +Write your CV or resume as YAML, then run RenderCV, and get a PDF +with perfect typography. No template wrestling. No broken layouts. +Consistent spacing, every time. |
