From 126d420b7a6ed2d4b2a42d534ab2e12344869643 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Ke=C3=9Fler?= Date: Fri, 22 Oct 2021 19:29:23 +0200 Subject: [PATCH] handle header correctly, i.e. do not only expand on macro --- build/build.py | 10 +++++- build/build_parser.py | 14 +++++++- build/utils/build_information.py | 57 ++++++++++++++++++++++++++++---- build/utils/pytex_file.py | 19 ++++++++--- config/__init__.py | 3 +- config/header_parts.py | 27 ++++++++------- formatter/tex_formatter.py | 17 +++++++--- macros/default_macros.py | 15 ++------- 8 files changed, 117 insertions(+), 45 deletions(-) diff --git a/build/build.py b/build/build.py index 99e3f99..2df2930 100644 --- a/build/build.py +++ b/build/build.py @@ -21,19 +21,27 @@ def build( include_license: bool = False, # header include_git_version: bool = False, # header include_pytex_info_text: bool = False, # header - use_git: bool = False, # versioning (not implemented yet) + extra_header: Optional[Path] = None, allow_dirty: bool = False, # versioning overwrite_existing_files: bool = False, # output control build_all: bool = False, # output control / versioning write_build_information: bool = True, # meta ): pytex_msg('Getting git repository information...') + if extra_header: + if extra_header.exists(): + with open(extra_header, 'r') as f: + text = f.readlines() + extra_header = [line.rstrip() for line in text] + else: + raise FileNotFoundError('Path to extra header content is invalid.') current_build_info = BuildInfo( include_timestamp=include_timestamp, include_pytex_version=include_pytex_version, include_license=include_license, include_git_version=include_git_version, include_pytex_info_text=include_pytex_info_text, + extra_header=extra_header, author=author, pytex_repo=git.Repo(__file__, search_parent_directories=True), packages_repo=git.Repo(src_dir, search_parent_directories=True) diff --git a/build/build_parser.py b/build/build_parser.py index 610ec76..5957f12 100644 --- a/build/build_parser.py +++ b/build/build_parser.py @@ -53,7 +53,7 @@ def parse_and_build(arglist: [str]): help='Insert git version information into build. This assumes your input' 'files are located in a git repository. Default: false', action='store_true', - dest='use_git' + dest='include_git_version' ) parser.add_argument( '-d', '--allow-dirty', @@ -92,6 +92,18 @@ def parse_and_build(arglist: [str]): action='store_true', dest='overwrite_existing_files' ) + parser.add_argument( + '--pytex-info-text', + help='Include a PyTeX info text into headers', + action='store_true', + dest='include_pytex_info_text' + ) + parser.add_argument( + '-e', '--extra-header', + help='Path to file containing extra text for header of each package', + type=pathlib.Path, + dest='extra_header' + ) args = vars(parser.parse_args(arglist)) for arg in args.keys(): if type(args[arg]) == pathlib.PosixPath: diff --git a/build/utils/build_information.py b/build/utils/build_information.py index 1f9bafc..769eabe 100644 --- a/build/utils/build_information.py +++ b/build/utils/build_information.py @@ -1,8 +1,9 @@ import git import datetime -from typing import Optional +from typing import Optional, List from PyTeX.build.git_hook import git_describe, get_latest_commit +from PyTeX.config.header_parts import * class BuildInfo: @@ -13,6 +14,7 @@ class BuildInfo: include_license: bool = False, include_git_version: bool = False, include_pytex_info_text: bool = False, + extra_header: Optional[List[str]] = None, author: Optional[str] = None, pytex_repo: Optional[git.Repo] = None, packages_repo: Optional[git.Repo] = None): @@ -33,11 +35,12 @@ class BuildInfo: self.get_repo_version() self.create_header( - include_timestamp=include_timestamp, - include_pytex_version=include_pytex_version, include_license=include_license, + include_pytex_info_text=include_pytex_info_text, + include_timestamp=include_timestamp, include_git_version=include_git_version, - include_pytex_info_text=include_pytex_info_text + include_pytex_version=include_pytex_version, + extra_header=extra_header ) @property @@ -86,5 +89,47 @@ class BuildInfo: include_pytex_version: bool = False, include_license: bool = False, include_git_version: bool = False, - include_pytex_info_text: bool = False): - self._header = [] # TODO + include_pytex_info_text: bool = False, + extra_header: Optional[List[str]] = None + ): + if not (include_license + or include_pytex_info_text + or include_timestamp + or include_pytex_version + or include_git_version): + self._header = None + return + else: + self._header = [] + if include_license: + self._header += LICENSE + [''] + if include_pytex_info_text: + self._header += PYTEX_INFO_TEXT + [''] + if include_timestamp or include_pytex_version or include_git_version: + self._header += BUILD_DETAILS + if include_timestamp: + self._header += BUILD_TIME + if include_pytex_version: + self._header += PYTEX_VERSION + if include_git_version: + self._header += SOURCE_CODE_VERSION + self._header += [''] + if extra_header: + self._header += extra_header + [''] + + if self._header[-1] == '': + self._header.pop() + + formatted_header = [] + for line in self._header: + formatted_header.append(line.format( + year=datetime.datetime.now().strftime('%Y'), + copyright_holders=self.author, + source_file='{source_file}', + latex_file_type='{latex_file_type}', + pytex_version=self.pytex_version, + pytex_commit_hash=self.pytex_hash[:7], + packages_version=self.packages_version, + packages_commit_hash=self.packages_hash[:7] + )) + self._header = formatted_header diff --git a/build/utils/pytex_file.py b/build/utils/pytex_file.py index 972bf8e..42a5758 100644 --- a/build/utils/pytex_file.py +++ b/build/utils/pytex_file.py @@ -1,5 +1,5 @@ from pathlib import Path -from typing import Optional +from typing import Optional, List from PyTeX.build.git_hook import is_recent, get_latest_commit from PyTeX import PackageFormatter, ClassFormatter @@ -27,6 +27,8 @@ class TexFileToFormat: self.allow_dirty = allow_dirty self.overwrite_existing_files: overwrite_existing_files self.build_all = build_all + self._header: Optional[List[str]] = None + self.__format_header() self.dirty = not is_recent(self.src_path, self.current_build_info.package_repo, compare=None) self.pytex_dirty: bool = self.current_build_info.pytex_repo.is_dirty( @@ -64,19 +66,28 @@ class TexFileToFormat: else: return self.last_build_info + def __format_header(self): + new_header = [] + for line in self.current_build_info.header: + new_header.append(line.format( + source_file=self.src_path.name, + latex_file_type='package' if '.pysty' in self.src_path.name else 'class' + )) + self._header = new_header + def __format(self) -> dict: if '.pysty' in self.src_path.name: formatter = PackageFormatter( package_name=self.src_path.with_suffix('').name, author=self.current_build_info.author, - extra_header=self.current_build_info.header) + extra_header=self._header) elif '.pycls' in self.src_path.name: formatter = ClassFormatter( class_name=self.src_path.with_suffix('').name, author=self.current_build_info.author, - extra_header=self.current_build_info.header) + extra_header=self._header) else: - exit(1) + raise Exception('Programming error. Please contact the developer.') pytex_msg('Writing file {}'.format(formatter.file_name)) formatter.make_default_macros() formatter.format_file(self.src_path, self.build_path) diff --git a/config/__init__.py b/config/__init__.py index 0f7abce..9671b4c 100644 --- a/config/__init__.py +++ b/config/__init__.py @@ -1,5 +1,5 @@ from .constants import FILENAME_TYPE_PREPEND_AUTHOR, FILENAME_TYPE_RAW_NAME, DATE_FORMAT, BUILD_INFO_FILENAME -from .header_parts import LICENSE, PACKAGE_INFO_TEXT, PYTEX_INFO_TEXT, BUILD_DETAILS +from .header_parts import LICENSE, PYTEX_INFO_TEXT, BUILD_DETAILS __all__ = [ 'FILENAME_TYPE_PREPEND_AUTHOR', @@ -7,7 +7,6 @@ __all__ = [ 'DATE_FORMAT', 'BUILD_INFO_FILENAME', 'LICENSE', - 'PACKAGE_INFO_TEXT', 'PYTEX_INFO_TEXT', 'BUILD_DETAILS' ] diff --git a/config/header_parts.py b/config/header_parts.py index 2c2dc8f..41bf08b 100644 --- a/config/header_parts.py +++ b/config/header_parts.py @@ -19,16 +19,6 @@ LICENSE = [ 'SOFTWARE.' ] -PACKAGE_INFO_TEXT = [ - "This LaTeX {latex_file_type} is free software and distributed under the MIT License. You", - "may use it freely for your purposes. The latest version of the {latex_file_type} can be", - "obtained via GitHub under", - " https://github.com/kesslermaximilian/LatexPackages", - "For further information see the url above.", - "Reportings of bugs, suggestions and improvements are welcome, see the README", - "at the Git repository for further information." -] - PYTEX_INFO_TEXT = [ "This {latex_file_type} has been generated by PyTeX, available at", " https://github.com/kesslermaximilian/PyTeX", @@ -39,8 +29,17 @@ PYTEX_INFO_TEXT = [ ] BUILD_DETAILS = [ - "Build details:", - " Build time: {build_time}", - " PyTeX version: {pytex_version} (commit {pytex_commit_hash})", - " LatexPackages version: {packages_version} (commit {packages_commit_hash})" + "Build details:" +] + +BUILD_TIME = [ + " Build time: {build_time}" +] + +PYTEX_VERSION = [ + " PyTeX version: {pytex_version} (commit {pytex_commit_hash})" +] + +SOURCE_CODE_VERSION = [ + " Source code version: {packages_version} (commit {packages_commit_hash})" ] diff --git a/formatter/tex_formatter.py b/formatter/tex_formatter.py index f773cda..60ca700 100644 --- a/formatter/tex_formatter.py +++ b/formatter/tex_formatter.py @@ -1,15 +1,15 @@ import datetime import re from pathlib import Path -from typing import Dict +from typing import Dict, Optional, List from datetime import * from PyTeX.base import Attributes, Args class TexFormatter: - def __init__(self, name: str, author: str, extra_header: [str], file_extension: str): - self.extra_header = extra_header + def __init__(self, name: str, author: str, header: Optional[List[str]], file_extension: str): + self.header = header self.name_raw = name self.author = author author_parts = self.author.lower().replace('ß', 'ss').split(' ') @@ -28,6 +28,10 @@ class TexFormatter: def __command_name2keyword(keyword: str): return '__' + keyword.upper().strip().replace(' ', '_') + '__' + @property + def filename(self): + return self.file_name + def __parse_replacement_args(self, match_groups, *user_args, **user_kwargs): new_args = [] for arg in user_args: @@ -93,7 +97,12 @@ class TexFormatter: self.source_file_name = str(input_path.name) input_file = input_path.open() lines = input_file.readlines() - newlines = [] + if self.header: + newlines = '%' * 80 + '\n' \ + + '\n'.join(map(lambda line: '% ' + line, self.header)) \ + + '\n' + '%' * 80 + '\n\n' + else: + newlines = [] for line in lines: newlines += self.__format_string_with_arg(self.__format_string(line)) if output_dir is None: diff --git a/macros/default_macros.py b/macros/default_macros.py index d0074df..2653383 100644 --- a/macros/default_macros.py +++ b/macros/default_macros.py @@ -4,26 +4,15 @@ import PyTeX.config def make_default_macros(formatter: PyTeX.formatter.TexFormatter, latex_file_type: str): - header = '%' * 80 + '\n' \ - + '\n'.join(map(lambda line: '% ' + line, - PyTeX.config.LICENSE + [''] + PyTeX.config.PACKAGE_INFO_TEXT + [ - ''] + PyTeX.config.PYTEX_INFO_TEXT - + [''] + formatter.extra_header) - ) \ - + '\n' + '%' * 80 + '\n\n' \ - + '\\NeedsTeXFormat{{LaTeX2e}}\n' \ - '\\Provides{Type}{{{name_lowercase}}}[{date} - {description}]\n\n' + header = '\\NeedsTeXFormat{{LaTeX2e}}\n' \ + '\\Provides{Type}{{{name_lowercase}}}[{date} - {description}]\n\n' formatter.add_arg_replacement( 1, 'header', header, name_lowercase=PyTeX.base.Attributes.name_lowercase, date=PyTeX.base.Attributes.date, description=PyTeX.base.Args.one, - year=PyTeX.base.Attributes.year, - copyright_holders=PyTeX.base.Attributes.author, - source_file=PyTeX.base.Attributes.source_file_name, Type=latex_file_type.capitalize(), - latex_file_type=latex_file_type ) formatter.add_replacement('{Type} name'.format(Type=latex_file_type), '{}', PyTeX.base.Attributes.name_lowercase) formatter.add_replacement('{Type} prefix'.format(Type=latex_file_type), '{}', PyTeX.base.Attributes.prefix)