diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/hydrilla/__init__.py | 7 | ||||
-rw-r--r-- | src/hydrilla/builder/__init__.py (renamed from src/hydrilla_builder/__init__.py) | 2 | ||||
-rw-r--r-- | src/hydrilla/builder/__main__.py (renamed from src/hydrilla_builder/__main__.py) | 0 | ||||
-rw-r--r-- | src/hydrilla/builder/build.py (renamed from src/hydrilla_builder/build.py) | 69 | ||||
m--------- | src/hydrilla/builder/schemas (renamed from src/hydrilla_builder/schemas) | 0 | ||||
-rw-r--r-- | src/hydrilla/util/__init__.py | 101 | ||||
-rw-r--r-- | src/test/test_hydrilla_builder.py | 7 |
7 files changed, 119 insertions, 67 deletions
diff --git a/src/hydrilla/__init__.py b/src/hydrilla/__init__.py new file mode 100644 index 0000000..6aeb276 --- /dev/null +++ b/src/hydrilla/__init__.py @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: 0BSD + +# Copyright (C) 2013-2020, PyPA + +# https://packaging.python.org/en/latest/guides/packaging-namespace-packages/#pkgutil-style-namespace-packages + +__path__ = __import__('pkgutil').extend_path(__path__, __name__) diff --git a/src/hydrilla_builder/__init__.py b/src/hydrilla/builder/__init__.py index d382ead..73dc579 100644 --- a/src/hydrilla_builder/__init__.py +++ b/src/hydrilla/builder/__init__.py @@ -3,3 +3,5 @@ # Copyright (C) 2022 Wojtek Kosior <koszko@koszko.org> # # Available under the terms of Creative Commons Zero v1.0 Universal. + +from .build import Build diff --git a/src/hydrilla_builder/__main__.py b/src/hydrilla/builder/__main__.py index 5b98202..5b98202 100644 --- a/src/hydrilla_builder/__main__.py +++ b/src/hydrilla/builder/__main__.py diff --git a/src/hydrilla_builder/build.py b/src/hydrilla/builder/build.py index 652e537..d89ead3 100644 --- a/src/hydrilla_builder/build.py +++ b/src/hydrilla/builder/build.py @@ -4,7 +4,7 @@ # # This file is part of Hydrilla # -# Copyright (C) 2021,2022 Wojtek Kosior +# Copyright (C) 2022 Wojtek Kosior # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as @@ -24,7 +24,6 @@ # file's license. Although I request that you do not make use this code # in a proprietary program, I am not going to enforce this in court. - import json import re import zipfile @@ -34,6 +33,8 @@ from sys import stderr import jsonschema +from .. import util + here = Path(__file__).resolve().parent with open(here / 'schemas' / 'package_source-1.schema.json') as schema_file: index_json_schema = json.load(schema_file) @@ -49,66 +50,6 @@ class ReuseError(Exception): Exception used to report various problems when calling the REUSE tool. """ -strip_comment_re = re.compile(r''' -^ # match from the beginning of each line -( # catch the part before '//' comment - (?: # this group matches either a string or a single out-of-string character - [^"/] | - " - (?: # this group matches any in-a-string character - [^"\\] | # match any normal character - \\[^u] | # match any escaped character like '\f' or '\n' - \\u[a-fA-F0-9]{4} # match an escape - )* - " - )* -) -# expect either end-of-line or a comment: -# * unterminated strings will cause matching to fail -# * bad comment (with '/' instead of '//') will be indicated by second group -# having length 1 instead of 2 or 0 -(//?|$) -''', re.VERBOSE) - -def strip_json_comments(text): - """ - Accept JSON text with optional C++-style ('//') comments and return the text - with comments removed. Consecutive slashes inside strings are handled - properly. A spurious single slash ('/') shall generate an error. Errors in - JSON itself shall be ignored. - """ - processed = 0 - stripped_text = [] - for line in text.split('\n'): - match = strip_comment_re.match(line) - - if match is None: # unterminated string - # ignore this error, let json module report it - stripped = line - elif len(match[2]) == 1: - raise json.JSONDecodeError('bad comment', text, - processed + len(match[1])) - else: - stripped = match[1] - - stripped_text.append(stripped) - processed += len(line) + 1 - - return '\n'.join(stripped_text) - -def normalize_version(ver): - ''' - 'ver' is an array of integers. Strip right-most zeroes from ver. - - Returns a *new* array. Doesn't modify its argument. - ''' - new_len = 0 - for i, num in enumerate(ver): - if num != 0: - new_len = i + 1 - - return ver[:new_len] - class FileBuffer: """ Implement a file-like object that buffers data written to it. @@ -221,7 +162,7 @@ class Build: with open(self.index_json_path, 'rt') as index_file: index_json_text = index_file.read() - index_obj = json.loads(strip_json_comments(index_json_text)) + index_obj = json.loads(util.strip_json_comments(index_json_text)) self.files_by_path[self.srcdir / 'index.json'] = \ FileRef(self.srcdir / 'index.json', index_json_text.encode()) @@ -329,7 +270,7 @@ class Build: new_item_obj.update([(p, item_def[p]) for p in copy_props]) - new_item_obj['version'] = normalize_version(item_def['version']) + new_item_obj['version'] = util.normalize_version(item_def['version']) new_item_obj['api_schema_version'] = [1, 0, 1] new_item_obj['source_copyright'] = self.copyright_file_refs new_item_obj['source_name'] = self.source_name diff --git a/src/hydrilla_builder/schemas b/src/hydrilla/builder/schemas -Subproject ca1de2ed4a69a71f2f75552ade693d04ea1baa8 +Subproject ca1de2ed4a69a71f2f75552ade693d04ea1baa8 diff --git a/src/hydrilla/util/__init__.py b/src/hydrilla/util/__init__.py new file mode 100644 index 0000000..72f73bc --- /dev/null +++ b/src/hydrilla/util/__init__.py @@ -0,0 +1,101 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later + +# Building Hydrilla packages. +# +# This file is part of Hydrilla +# +# Copyright (C) 2021, 2022 Wojtek Kosior +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +# +# I, Wojtek Kosior, thereby promise not to sue for violation of this +# file's license. Although I request that you do not make use this code +# in a proprietary program, I am not going to enforce this in court. + +import re as _re +import json as _json + +from typing import Optional as _Optional + +_strip_comment_re = _re.compile(r''' +^ # match from the beginning of each line +( # catch the part before '//' comment + (?: # this group matches either a string or a single out-of-string character + [^"/] | + " + (?: # this group matches any in-a-string character + [^"\\] | # match any normal character + \\[^u] | # match any escaped character like '\f' or '\n' + \\u[a-fA-F0-9]{4} # match an escape + )* + " + )* +) +# expect either end-of-line or a comment: +# * unterminated strings will cause matching to fail +# * bad comment (with '/' instead of '//') will be indicated by second group +# having length 1 instead of 2 or 0 +(//?|$) +''', _re.VERBOSE) + +def strip_json_comments(text: str) -> str: + """ + Accept JSON text with optional C++-style ('//') comments and return the text + with comments removed. Consecutive slashes inside strings are handled + properly. A spurious single slash ('/') shall generate an error. Errors in + JSON itself shall be ignored. + """ + processed = 0 + stripped_text = [] + for line in text.split('\n'): + match = _strip_comment_re.match(line) + + if match is None: # unterminated string + # ignore this error, let json module report it + stripped = line + elif len(match[2]) == 1: + raise _json.JSONDecodeError('bad comment', text, + processed + len(match[1])) + else: + stripped = match[1] + + stripped_text.append(stripped) + processed += len(line) + 1 + + return '\n'.join(stripped_text) + +def normalize_version(ver: list[int]) -> list[int]: + """Strip right-most zeroes from 'ver'. The original list is not modified.""" + new_len = 0 + for i, num in enumerate(ver): + if num != 0: + new_len = i + 1 + + return ver[:new_len] + +def parse_version(ver_str: str) -> list[int]: + """ + Convert 'ver_str' into an array representation, e.g. for ver_str="4.6.13.0" + return [4, 6, 13, 0]. + """ + return [int(num) for num in ver_str.split('.')] + +def version_string(ver: list[int], rev: _Optional[int]=None) -> str: + """ + Produce version's string representation (optionally with revision), like: + 1.2.3-5 + No version normalization is performed. + """ + return '.'.join([str(n) for n in ver]) + ('' if rev is None else f'-{rev}') diff --git a/src/test/test_hydrilla_builder.py b/src/test/test_hydrilla_builder.py index f4a4d2f..410b7a1 100644 --- a/src/test/test_hydrilla_builder.py +++ b/src/test/test_hydrilla_builder.py @@ -16,7 +16,8 @@ from typing import Callable, Optional from jsonschema import ValidationError -from hydrilla_builder import build +from hydrilla import util as hydrilla_util +from hydrilla.builder import build here = Path(__file__).resolve().parent @@ -187,7 +188,7 @@ def prepare_modified(tmpdir: Path, modify_cb: ModifyCb) -> CaseSettings: settings.srcdir = tmpdir / 'srcdir_copy' with open(settings.srcdir / 'index.json', 'rt') as file_handle: - obj = json.loads(build.strip_json_comments(file_handle.read())) + obj = json.loads(hydrilla_util.strip_json_comments(file_handle.read())) contents = modify_cb(settings, obj) @@ -438,4 +439,4 @@ def test_build_error(tmpdir: str, break_index_json: tuple[ModifyCb, type]): with pytest.raises(error_type): build.Build(settings.srcdir, settings.index_json_path)\ - .write_package_files(dstdir) + .write_package_files(dstdir) |