Revision 9e71d383
Added by koszko over 1 year ago
| .gitignore | ||
|---|---|---|
| 10 | 10 |
*.pyc |
| 11 | 11 |
setuptools |
| 12 | 12 |
src/hydrilla/builder/_version.py |
| 13 |
src/hydrilla/locales/hydrilla_builder.pot |
|
| 14 |
hydrilla_builder.mo |
|
| .reuse/dep5 | ||
|---|---|---|
| 3 | 3 |
Upstream-Contact: Wojtek Kosior <koszko@koszko.org> |
| 4 | 4 |
Source: https://git.koszko.org/hydrilla-builder |
| 5 | 5 |
|
| 6 |
# Sample paragraph, commented out: |
|
| 7 |
# |
|
| 8 |
# Files: src/* |
|
| 9 |
# Copyright: $YEAR $NAME <$CONTACT> |
|
| 10 |
# License: ... |
|
| 6 |
Files: PKG-INFO setup.cfg src/hydrilla/builder/_version.py |
|
| 7 |
src/hydrilla.builder.egg-info/* |
|
| 8 |
Copyright: 2022 Wojtek Kosior <koszko@koszko.org> |
|
| 9 |
License: CC0-1.0 |
|
| 10 |
Comment: Those are files that setuptools generate in sdist. |
|
| 11 |
`setup.cfg` gets stripped of comments during generation of |
|
| 12 |
sdist, so we include it here as well. |
|
| MANIFEST.in | ||
|---|---|---|
| 5 | 5 |
# Available under the terms of Creative Commons Zero v1.0 Universal. |
| 6 | 6 |
|
| 7 | 7 |
include src/hydrilla/schemas/*.schema.json* |
| 8 |
include src/hydrilla/locales/*/LC_MESSAGES/hydrilla_builder.po |
|
| 8 | 9 |
include src/test/source-package-example/* |
| 9 | 10 |
global-exclude .git .gitignore .gitmodules |
| pyproject.toml | ||
|---|---|---|
| 6 | 6 |
|
| 7 | 7 |
[build-system] |
| 8 | 8 |
build-backend = "setuptools.build_meta" |
| 9 |
requires = ["setuptools>=45", "wheel", "setuptools_scm>=5.0"] |
|
| 9 |
requires = ["setuptools>=45", "wheel", "setuptools_scm>=5.0", "babel"]
|
|
| 10 | 10 |
|
| 11 | 11 |
[tool.setuptools_scm] |
| 12 | 12 |
write_to = "src/hydrilla/builder/_version.py" |
| setup.cfg | ||
|---|---|---|
| 35 | 35 |
install_requires = |
| 36 | 36 |
click |
| 37 | 37 |
jsonschema |
| 38 |
importlib; python_version == "2.6" |
|
| 39 | 38 |
# reuse is optional: |
| 40 | 39 |
# reuse |
| 41 | 40 |
|
| 41 |
[options.package_data] |
|
| 42 |
* = *.mo |
|
| 43 |
|
|
| 42 | 44 |
[options.extras_require] |
| 43 | 45 |
test = pytest |
| 44 | 46 |
setup = setuptools_scm |
| ... | ... | |
| 50 | 52 |
|
| 51 | 53 |
[options.entry_points] |
| 52 | 54 |
console_scripts = |
| 53 |
hydrilla-builder = hydrilla.builder.__main__:perform_build |
|
| 55 |
hydrilla-builder = hydrilla.builder.build:perform |
|
| 56 |
|
|
| 57 |
[extract_messages] |
|
| 58 |
keywords = _ |
|
| 59 |
width = 80 |
|
| 60 |
input_dirs = src/hydrilla |
|
| 61 |
output_file = src/hydrilla/locales/hydrilla_builder.pot |
|
| 62 |
msgid_bugs_address = koszko@koszko.org |
|
| 63 |
sort_by_file = True |
|
| 64 |
copyright_holder = Wojtek Kosior <koszko@koszko.org> |
|
| 65 |
|
|
| 66 |
[init_catalog] |
|
| 67 |
input_file = src/hydrilla/locales/hydrilla_builder.pot |
|
| 68 |
output_dir = src/hydrilla/locales/ |
|
| 69 |
domain = hydrilla_builder |
|
| 70 |
|
|
| 71 |
[update_catalog] |
|
| 72 |
input_file = src/hydrilla/locales/hydrilla_builder.pot |
|
| 73 |
output_dir = src/hydrilla/locales/ |
|
| 74 |
domain = hydrilla_builder |
|
| 75 |
|
|
| 76 |
[compile_catalog] |
|
| 77 |
directory = src/hydrilla/locales |
|
| 78 |
use_fuzzy = True |
|
| 79 |
domain = hydrilla_builder |
|
| setup.py | ||
|---|---|---|
| 7 | 7 |
|
| 8 | 8 |
import setuptools |
| 9 | 9 |
|
| 10 |
setuptools.setup() |
|
| 10 |
from setuptools.command.build_py import build_py |
|
| 11 |
|
|
| 12 |
class CustomBuildCommand(build_py): |
|
| 13 |
''' |
|
| 14 |
The build command but runs babel before build. |
|
| 15 |
''' |
|
| 16 |
def run(self, *args, **kwargs): |
|
| 17 |
self.run_command('compile_catalog')
|
|
| 18 |
super().run(*args, **kwargs) |
|
| 19 |
|
|
| 20 |
setuptools.setup(cmdclass={'build_py': CustomBuildCommand})
|
|
| src/hydrilla/builder/__main__.py | ||
|---|---|---|
| 1 |
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
| 1 |
# SPDX-License-Identifier: CC0-1.0
|
|
| 2 | 2 |
|
| 3 |
# Command line interface of Hydrilla package builder.
|
|
| 3 |
# Copyright (C) 2022 Wojtek Kosior <koszko@koszko.org>
|
|
| 4 | 4 |
# |
| 5 |
# This file is part of Hydrilla |
|
| 6 |
# |
|
| 7 |
# Copyright (C) 2022 Wojtek Kosior |
|
| 8 |
# |
|
| 9 |
# This program is free software: you can redistribute it and/or modify |
|
| 10 |
# it under the terms of the GNU Affero General Public License as |
|
| 11 |
# published by the Free Software Foundation, either version 3 of the |
|
| 12 |
# License, or (at your option) any later version. |
|
| 13 |
# |
|
| 14 |
# This program is distributed in the hope that it will be useful, |
|
| 15 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 16 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 17 |
# GNU Affero General Public License for more details. |
|
| 18 |
# |
|
| 19 |
# You should have received a copy of the GNU Affero General Public License |
|
| 20 |
# along with this program. If not, see <https://www.gnu.org/licenses/>. |
|
| 21 |
# |
|
| 22 |
# |
|
| 23 |
# I, Wojtek Kosior, thereby promise not to sue for violation of this |
|
| 24 |
# file's license. Although I request that you do not make use this code |
|
| 25 |
# in a proprietary program, I am not going to enforce this in court. |
|
| 26 |
|
|
| 27 |
from pathlib import Path |
|
| 28 |
|
|
| 29 |
import click |
|
| 30 |
|
|
| 31 |
from .build import Build |
|
| 32 |
|
|
| 33 |
dir_type = click.Path(exists=True, file_okay=False, resolve_path=True) |
|
| 5 |
# Available under the terms of Creative Commons Zero v1.0 Universal. |
|
| 34 | 6 |
|
| 35 |
@click.command() |
|
| 36 |
@click.option('-s', '--srcdir', default='./', type=dir_type, show_default=True,
|
|
| 37 |
help='Source directory to build from.') |
|
| 38 |
@click.option('-i', '--index-json', default='index.json', type=click.Path(),
|
|
| 39 |
help='Path to file to be processed instead of index.json (if not absolute, resolved relative to srcdir).') |
|
| 40 |
@click.option('-d', '--dstdir', type=dir_type, required=True,
|
|
| 41 |
help='Destination directory to write built package files to.') |
|
| 42 |
def preform_build(srcdir, index_json, dstdir): |
|
| 43 |
""" |
|
| 44 |
Build Hydrilla package from scrdir and write the resulting files under |
|
| 45 |
dstdir. |
|
| 46 |
""" |
|
| 47 |
build = Build(Path(srcdir), Path(index_json)) |
|
| 48 |
build.write_package_files(Path(dstdir)) |
|
| 7 |
from . import build |
|
| 49 | 8 |
|
| 50 |
preform_build() |
|
| 9 |
build.perform() |
|
| src/hydrilla/builder/build.py | ||
|---|---|---|
| 32 | 32 |
from sys import stderr |
| 33 | 33 |
|
| 34 | 34 |
import jsonschema |
| 35 |
import click |
|
| 35 | 36 |
|
| 36 | 37 |
from .. import util |
| 37 | 38 |
|
| 39 |
_ = util.get_gettext('hydrilla_builder')
|
|
| 40 |
|
|
| 38 | 41 |
index_validator = util.validator_for('package_source-1.schema.json')
|
| 39 | 42 |
|
| 40 | 43 |
class FileReferenceError(Exception): |
| ... | ... | |
| 99 | 102 |
try: |
| 100 | 103 |
from reuse._main import main as reuse_main |
| 101 | 104 |
except ModuleNotFoundError: |
| 102 |
ReuseError("Could not import 'reuse'. Is the tool installed and visible to this Python instance?")
|
|
| 105 |
ReuseError(_('couldnt_import_reuse_is_it_installed'))
|
|
| 103 | 106 |
|
| 104 | 107 |
mocked_output = FileBuffer() |
| 105 | 108 |
if reuse_main(args=['--root', str(root), 'lint'], out=mocked_output) != 0: |
| 106 | 109 |
stderr.write(mocked_output.get_bytes().decode()) |
| 107 |
raise ReuseError('Attempt to generate an SPDX report for a REUSE-incompliant package.')
|
|
| 110 |
raise ReuseError(_('spdx_report_from_reuse_incompliant'))
|
|
| 108 | 111 |
|
| 109 | 112 |
mocked_output = FileBuffer() |
| 110 | 113 |
if reuse_main(args=['--root', str(root), 'spdx'], out=mocked_output) != 0: |
| ... | ... | |
| 188 | 191 |
|
| 189 | 192 |
path = path.resolve() |
| 190 | 193 |
if not path.is_relative_to(self.srcdir): |
| 191 |
raise FileReferenceError(f"Attempt to load '{filename}' which lies outside package source directory.")
|
|
| 194 |
raise FileReferenceError(_('loading_{}_outside_package_dir')
|
|
| 195 |
.format(filename)) |
|
| 192 | 196 |
|
| 193 | 197 |
if str(path.relative_to(self.srcdir)) == 'index.json': |
| 194 |
raise FileReferenceError("Attempt to load 'index.json' which is a reserved filename.")
|
|
| 198 |
raise FileReferenceError(_('loading_reserved_index_json'))
|
|
| 195 | 199 |
|
| 196 | 200 |
file_ref = self.files_by_path.get(path) |
| 197 | 201 |
if file_ref is None: |
| ... | ... | |
| 305 | 309 |
[self._process_file(f['file']) for f in index_obj['copyright']] |
| 306 | 310 |
|
| 307 | 311 |
if generate_spdx and not spdx_ref.include_in_distribution: |
| 308 |
raise FileReferenceError("Told to generate 'report.spdx' but 'report.spdx' is not listed among copyright files. Refusing to proceed.")
|
|
| 312 |
raise FileReferenceError(_('report_spdx_not_in_copyright_list'))
|
|
| 309 | 313 |
|
| 310 | 314 |
item_refs = [self._process_item(d) for d in index_obj['definitions']] |
| 311 | 315 |
|
| ... | ... | |
| 373 | 377 |
version = '.'.join([str(n) for n in item_def['version']]) |
| 374 | 378 |
with open(item_dir_path / version, 'wt') as output: |
| 375 | 379 |
json.dump(item_def, output) |
| 380 |
|
|
| 381 |
dir_type = click.Path(exists=True, file_okay=False, resolve_path=True) |
|
| 382 |
|
|
| 383 |
@click.option('-s', '--srcdir', default='./', type=dir_type, show_default=True,
|
|
| 384 |
help=_('source_directory_to_build_from'))
|
|
| 385 |
@click.option('-i', '--index-json', default='index.json', type=click.Path(),
|
|
| 386 |
help=_('path_instead_of_index_json'))
|
|
| 387 |
@click.option('-d', '--dstdir', type=dir_type, required=True,
|
|
| 388 |
help=_('built_package_files_destination'))
|
|
| 389 |
def perform(srcdir, index_json, dstdir): |
|
| 390 |
"""<this will be replaced by a localized docstring for Click to pick up>""" |
|
| 391 |
build = Build(Path(srcdir), Path(index_json)) |
|
| 392 |
build.write_package_files(Path(dstdir)) |
|
| 393 |
|
|
| 394 |
perform.__doc__ = _('build_package_from_srcdir_to_dstdir')
|
|
| 395 |
|
|
| 396 |
perform = click.command()(perform) |
|
| src/hydrilla/locales/en_US/LC_MESSAGES/hydrilla_builder.po | ||
|---|---|---|
| 1 |
# SPDX-License-Identifier: CC0-1.0 |
|
| 2 |
# |
|
| 3 |
# English (United States) translations for hydrilla.builder. |
|
| 4 |
# Copyright (C) 2022 Wojtek Kosior <koszko@koszko.org> |
|
| 5 |
# Available under the terms of Creative Commons Zero v1.0 Universal. |
|
| 6 |
msgid "" |
|
| 7 |
msgstr "" |
|
| 8 |
"Project-Id-Version: hydrilla.builder 0.1.dev16+g4e46d7f.d20220211\n" |
|
| 9 |
"Report-Msgid-Bugs-To: koszko@koszko.org\n" |
|
| 10 |
"POT-Creation-Date: 2022-02-12 10:49+0100\n" |
|
| 11 |
"PO-Revision-Date: 2022-02-12\n" |
|
| 12 |
"Last-Translator: Wojtek Kosior <koszko@koszko.org>\n" |
|
| 13 |
"Language: en_US\n" |
|
| 14 |
"Language-Team: en_US <koszko@koszko.org>\n" |
|
| 15 |
"Plural-Forms: nplurals=2; plural=(n != 1)\n" |
|
| 16 |
"MIME-Version: 1.0\n" |
|
| 17 |
"Content-Type: text/plain; charset=utf-8\n" |
|
| 18 |
"Content-Transfer-Encoding: 8bit\n" |
|
| 19 |
"Generated-By: Babel 2.8.0\n" |
|
| 20 |
|
|
| 21 |
#: src/hydrilla/builder/build.py:105 |
|
| 22 |
msgid "couldnt_import_reuse_is_it_installed" |
|
| 23 |
msgstr "" |
|
| 24 |
"Could not import 'reuse'. Is the tool installed and visible to this " |
|
| 25 |
"Python instance?" |
|
| 26 |
|
|
| 27 |
#: src/hydrilla/builder/build.py:110 |
|
| 28 |
msgid "spdx_report_from_reuse_incompliant" |
|
| 29 |
msgstr "Attempt to generate an SPDX report for a REUSE-incompliant package." |
|
| 30 |
|
|
| 31 |
#: src/hydrilla/builder/build.py:194 |
|
| 32 |
msgid "loading_{}_outside_package_dir"
|
|
| 33 |
msgstr "Attempt to load '{}' which lies outside package source directory."
|
|
| 34 |
|
|
| 35 |
#: src/hydrilla/builder/build.py:198 |
|
| 36 |
msgid "loading_reserved_index_json" |
|
| 37 |
msgstr "Attempt to load 'index.json' which is a reserved filename." |
|
| 38 |
|
|
| 39 |
#: src/hydrilla/builder/build.py:312 |
|
| 40 |
msgid "report_spdx_not_in_copyright_list" |
|
| 41 |
msgstr "" |
|
| 42 |
"Told to generate 'report.spdx' but 'report.spdx' is not listed among " |
|
| 43 |
"copyright files. Refusing to proceed." |
|
| 44 |
|
|
| 45 |
#: src/hydrilla/builder/build.py:384 |
|
| 46 |
msgid "source_directory_to_build_from" |
|
| 47 |
msgstr "Source directory to build from." |
|
| 48 |
|
|
| 49 |
#: src/hydrilla/builder/build.py:386 |
|
| 50 |
msgid "path_instead_of_index_json" |
|
| 51 |
msgstr "" |
|
| 52 |
"Path to file to be processed instead of index.json (if not absolute, " |
|
| 53 |
"resolved relative to srcdir)." |
|
| 54 |
|
|
| 55 |
#: src/hydrilla/builder/build.py:388 |
|
| 56 |
msgid "built_package_files_destination" |
|
| 57 |
msgstr "Destination directory to write built package files to." |
|
| 58 |
|
|
| 59 |
#: src/hydrilla/builder/build.py:394 |
|
| 60 |
msgid "build_package_from_srcdir_to_dstdir" |
|
| 61 |
msgstr "" |
|
| 62 |
"Build Hydrilla package from `scrdir` and write the resulting files " |
|
| 63 |
"under `dstdir`." |
|
| 64 |
|
|
| 65 |
#: src/hydrilla/util/_util.py:76 |
|
| 66 |
msgid "bad_comment" |
|
| 67 |
msgstr "bad comment" |
|
| src/hydrilla/util/__init__.py | ||
|---|---|---|
| 5 | 5 |
# Available under the terms of Creative Commons Zero v1.0 Universal. |
| 6 | 6 |
|
| 7 | 7 |
from ._util import strip_json_comments, normalize_version, parse_version, \ |
| 8 |
version_string, validator_for |
|
| 8 |
version_string, validator_for, get_gettext |
|
| src/hydrilla/util/_util.py | ||
|---|---|---|
| 26 | 26 |
|
| 27 | 27 |
import re |
| 28 | 28 |
import json |
| 29 |
import locale |
|
| 30 |
import gettext |
|
| 29 | 31 |
|
| 30 | 32 |
from pathlib import Path |
| 31 | 33 |
from typing import Optional |
| ... | ... | |
| 71 | 73 |
# ignore this error, let json module report it |
| 72 | 74 |
stripped = line |
| 73 | 75 |
elif len(match[2]) == 1: |
| 74 |
raise json.JSONDecodeError('bad comment', text,
|
|
| 76 |
raise json.JSONDecodeError(_('bad_comment'), text,
|
|
| 75 | 77 |
processed + len(match[1])) |
| 76 | 78 |
else: |
| 77 | 79 |
stripped = match[1] |
| ... | ... | |
| 127 | 129 |
""" |
| 128 | 130 |
return Draft7Validator(resolver.resolve(schema_filename)[1], |
| 129 | 131 |
resolver=resolver) |
| 132 |
|
|
| 133 |
def get_gettext(domain: str, lang: Optional[str]=None): |
|
| 134 |
""" |
|
| 135 |
Configure translation and return its gettext() function. |
|
| 136 |
|
|
| 137 |
If `lang` is set, look for translations for `lang`. Otherwise, try to |
|
| 138 |
determine system's default language and use that. |
|
| 139 |
""" |
|
| 140 |
# https://stackoverflow.com/questions/3425294/how-to-detect-the-os-default-language-in-python |
|
| 141 |
# But I am not going to surrender to Microbugs' nonfree, crappy OS to test |
|
| 142 |
# it, to the lines inside try: may fail. |
|
| 143 |
try: |
|
| 144 |
from ctypes.windll import kernel32 as windll |
|
| 145 |
lang = locale.windows_locale[windll.GetUserDefaultUILanguage()] |
|
| 146 |
except: |
|
| 147 |
lang = locale.getdefaultlocale()[0] or 'C' |
|
| 148 |
|
|
| 149 |
translation = gettext.translation( |
|
| 150 |
domain, |
|
| 151 |
localedir=(here.parent / 'locales'), |
|
| 152 |
languages=[lang, 'en_US'] |
|
| 153 |
) |
|
| 154 |
|
|
| 155 |
return translation.gettext |
|
| 156 |
|
|
| 157 |
_ = get_gettext('hydrilla_builder')
|
|
Also available in: Unified diff
internationalize using Babel
this commit also makes the sdist tarball generated by setuptools REUSE-compliant