-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
c8fba15
commit 88908fe
Showing
23 changed files
with
850 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
name: Python test | ||
|
||
on: | ||
pull_request: | ||
branches: [ "main" ] | ||
|
||
jobs: | ||
build: | ||
name: Build and test | ||
|
||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- name: Checkout repository | ||
uses: actions/checkout@v4 | ||
- name: Verify code quality | ||
shell: bash | ||
run: | | ||
cd python | ||
pip install mypy flake8 pytest | ||
mypy | ||
flake8 | ||
pytest |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
MIT License | ||
|
||
Copyright (c) 2024 EffectiveRange | ||
Copyright (c) 2024 Ferenc Nandor Janky <[email protected]> | ||
Copyright (c) 2024 Attila Gombos <[email protected]> | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#!/bin/bash | ||
|
||
# SPDX-FileCopyrightText: 2024 Ferenc Nandor Janky <[email protected]> | ||
# SPDX-FileCopyrightText: 2024 Attila Gombos <[email protected]> | ||
# SPDX-License-Identifier: MIT | ||
|
||
set -x -e -o pipefail | ||
|
||
if [ ! -d "$1" ]; then | ||
echo "Usage: $0 <workspace dir>" | ||
exit 1 | ||
fi | ||
|
||
if [ ! -d "$1/build" ]; then | ||
echo "No build directory found in $1" | ||
exit 1 | ||
fi | ||
|
||
cd "$1/build" | ||
|
||
DEB_FILES_LIST="$(cpack . | grep "CPack: - package:" | sed -r 's/CPack: - package: //' | sed -r 's/ generated.*//')" | ||
|
||
for f in "$DEB_FILES_LIST" | ||
do | ||
echo "$f" | ||
done |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# SPDX-FileCopyrightText: 2024 Ferenc Nandor Janky <[email protected]> | ||
# SPDX-FileCopyrightText: 2024 Attila Gombos <[email protected]> | ||
# SPDX-License-Identifier: MIT | ||
|
||
import re | ||
import subprocess | ||
import sys | ||
from os.path import exists | ||
from typing import Generator | ||
|
||
|
||
def check_workspace(workspace_dir: str) -> None: | ||
if not exists(workspace_dir): | ||
print(f'Workspace directory {workspace_dir} does not exist', file=sys.stderr) | ||
exit(1) | ||
|
||
if not exists(f'{workspace_dir}/setup.py'): | ||
print(f'There is no setup.py in the workspace directory {workspace_dir}', file=sys.stderr) | ||
exit(2) | ||
|
||
|
||
def run_command(workspace_dir: str, command: str | list[str], matcher: str, | ||
first_match_only: bool = True) -> Generator[str, None, None]: | ||
result = subprocess.run(command, cwd=workspace_dir, text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) | ||
|
||
if result.returncode: | ||
exit(result.returncode) | ||
|
||
output = result.stdout.split('\n') | ||
pattern = re.compile(matcher) | ||
|
||
for line in output: | ||
if match := pattern.match(line): | ||
yield match.group(1) | ||
if first_match_only: | ||
break |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
#!/usr/bin/env python3 | ||
|
||
# SPDX-FileCopyrightText: 2024 Ferenc Nandor Janky <[email protected]> | ||
# SPDX-FileCopyrightText: 2024 Attila Gombos <[email protected]> | ||
# SPDX-License-Identifier: MIT | ||
|
||
import re | ||
import subprocess | ||
from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter, Namespace, BooleanOptionalAction | ||
from configparser import ConfigParser | ||
from os.path import exists, dirname, abspath | ||
|
||
from common.common import check_workspace | ||
|
||
DEFAULT_PACKAGING = 'wheel' | ||
|
||
|
||
def main() -> None: | ||
arguments = _get_arguments() | ||
|
||
workspace_dir = abspath(arguments.workspace_dir) | ||
|
||
check_workspace(workspace_dir) | ||
|
||
config_file = f'{workspace_dir}/{arguments.config_file}' | ||
|
||
packaging = [DEFAULT_PACKAGING] | ||
|
||
configuration = None | ||
|
||
if exists(config_file): | ||
parser = ConfigParser() | ||
parser.read(config_file) | ||
|
||
if parser.has_section('pack-python'): | ||
configuration = dict(parser['pack-python']) | ||
|
||
packaging_options = configuration.get('packaging', '').split() | ||
|
||
if arguments.all: | ||
packaging = packaging_options | ||
else: | ||
default = configuration.get('default', DEFAULT_PACKAGING) | ||
if default in packaging_options: | ||
packaging = [default] | ||
|
||
scripts_dir = f'{abspath(dirname(__file__))}/scripts' | ||
|
||
for script in packaging: | ||
script_file = f'{scripts_dir}/{script}' | ||
if exists(script_file): | ||
|
||
command = [script_file, workspace_dir] | ||
|
||
if configuration: | ||
arg_string = configuration.get(script) | ||
if arg_string: | ||
command.extend(split_arguments(arg_string)) | ||
|
||
if arguments.python_bin: | ||
command.extend(['-p', arguments.python_bin]) | ||
|
||
if arguments.output_dir: | ||
command.extend(['-o', arguments.output_dir]) | ||
|
||
result = subprocess.run(command, text=True, stdout=subprocess.PIPE) | ||
|
||
if not result.returncode: | ||
if result.stdout: | ||
print(result.stdout.rstrip('\n')) | ||
|
||
|
||
def _get_arguments() -> Namespace: | ||
parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter) | ||
parser.add_argument('-a', '--all', help='run all packaging scripts', action=BooleanOptionalAction, default=False) | ||
parser.add_argument('-c', '--config-file', help='config file path relative to the workspace directory', | ||
default='setup.cfg') | ||
parser.add_argument('-p', '--python-bin', help='python executable to use', default='python3') | ||
parser.add_argument('-o', '--output-dir', help='package output directory') | ||
parser.add_argument('workspace_dir', help='workspace directory where setup.py is located') | ||
return parser.parse_args() | ||
|
||
|
||
def split_arguments(arg_string: str) -> list[str]: | ||
# Split on spaces, but allow spaces inside double quotes | ||
pattern = r'\"(.*?)\"|(\S+)' | ||
matches = re.findall(pattern, arg_string) | ||
return [match[0] if match[0] else match[1] for match in matches] | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
#!/usr/bin/env python3 | ||
|
||
# SPDX-FileCopyrightText: 2024 Ferenc Nandor Janky <[email protected]> | ||
# SPDX-FileCopyrightText: 2024 Attila Gombos <[email protected]> | ||
# SPDX-License-Identifier: MIT | ||
|
||
import glob | ||
import os | ||
import re | ||
import shutil | ||
import sys | ||
from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter, Namespace | ||
from os.path import abspath | ||
from pathlib import Path | ||
from typing import Generator | ||
|
||
sys.path.append(str(Path(os.path.dirname(__file__)).resolve().parent)) | ||
|
||
from common.common import check_workspace, run_command | ||
|
||
|
||
def main() -> None: | ||
arguments = _get_arguments() | ||
|
||
workspace_dir = abspath(arguments.workspace_dir) | ||
|
||
check_workspace(workspace_dir) | ||
|
||
output_dir = f'{workspace_dir}/dist' | ||
|
||
if arguments.output_dir: | ||
output_dir = abspath(arguments.output_dir) | ||
|
||
results = create_sources(arguments, workspace_dir, output_dir) | ||
|
||
build_dir = f'{output_dir}/{next(results)}' | ||
|
||
results = build_package(arguments, workspace_dir, build_dir) | ||
|
||
for result in results: | ||
print(f'{output_dir}/{result}') | ||
|
||
|
||
def create_sources(arguments: Namespace, workspace_dir: str, output_dir: str) -> Generator[str, None, None]: | ||
package_name = extract_package_name(workspace_dir) | ||
|
||
command_arguments = ['--package3', package_name, '--dist-dir', output_dir, '--with-dh-virtualenv', '--compat', '10'] | ||
|
||
if arguments.arguments: | ||
command_arguments.extend(arguments.arguments.split()) | ||
|
||
if arguments.service_file: | ||
command_arguments.append('--with-dh-systemd') | ||
|
||
command = [arguments.python_bin, 'setup.py', '--command-packages=stdeb.command', 'sdist_dsc', *command_arguments] | ||
|
||
return run_command(workspace_dir, command, r'copying setup.py -> (.+)') | ||
|
||
|
||
def extract_package_name(workspace_dir: str) -> str: | ||
with open(f'{workspace_dir}/setup.py', 'r') as file: | ||
setup_code = file.read() | ||
|
||
pattern = r'name\s*=\s*[\'"]([^\'"]+)[\'"]' | ||
|
||
match = re.search(pattern, setup_code) | ||
|
||
if match: | ||
return match.group(1) | ||
else: | ||
return workspace_dir.split('/')[-1] | ||
|
||
|
||
def build_package(arguments: Namespace, workspace_dir: str, build_dir: str) -> Generator[str, None, None]: | ||
debian_dir = f'{build_dir}/debian' | ||
|
||
if arguments.service_file: | ||
if arguments.service_file.startswith('/'): | ||
service_file = arguments.service_file | ||
else: | ||
service_file = f'{workspace_dir}/{arguments.service_file}' | ||
|
||
shutil.copy(service_file, debian_dir) | ||
|
||
if arguments.extra_files: | ||
if arguments.extra_files.startswith('/'): | ||
extra_files = arguments.extra_files | ||
else: | ||
extra_files = f'{workspace_dir}/{arguments.extra_files}' | ||
|
||
for file in glob.glob(extra_files): | ||
shutil.copy(file, debian_dir) | ||
|
||
command = ['dpkg-buildpackage', '-us', '-uc', '-ui', '-b'] | ||
|
||
return run_command(build_dir, command, r".*'\.\./(.+\.deb)'") | ||
|
||
|
||
def _get_arguments() -> Namespace: | ||
parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter) | ||
parser.add_argument('-a', '--arguments', help='extra arguments passed to stdeb') | ||
parser.add_argument('-p', '--python-bin', help='python executable to use', default='python3') | ||
parser.add_argument('-s', '--service-file', help='service unit file path') | ||
parser.add_argument('-e', '--extra-files', help='add extra files into debian folder before build') | ||
parser.add_argument('-o', '--output-dir', help='package output directory') | ||
parser.add_argument('workspace_dir', help='workspace directory where setup.py is located') | ||
return parser.parse_args() | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
#!/usr/bin/env python3 | ||
|
||
# SPDX-FileCopyrightText: 2024 Ferenc Nandor Janky <[email protected]> | ||
# SPDX-FileCopyrightText: 2024 Attila Gombos <[email protected]> | ||
# SPDX-License-Identifier: MIT | ||
|
||
import os | ||
import sys | ||
from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter, Namespace | ||
from os.path import abspath | ||
from pathlib import Path | ||
|
||
sys.path.append(str(Path(sys.argv[0]).resolve().parent.parent)) | ||
|
||
from common.common import check_workspace, run_command | ||
|
||
|
||
def main() -> None: | ||
arguments = _get_arguments() | ||
|
||
workspace_dir = abspath(arguments.workspace_dir) | ||
|
||
check_workspace(workspace_dir) | ||
|
||
fpm_arguments = ['-s', 'python', '-t', 'deb', '--python-bin', arguments.python_bin, | ||
'--python-package-name-prefix', 'python3', '--log', 'error', '-f'] | ||
|
||
if arguments.arguments: | ||
fpm_arguments.extend(arguments.arguments.split()) | ||
|
||
output_dir = f'{workspace_dir}/dist' | ||
|
||
if arguments.output_dir: | ||
output_dir = abspath(arguments.output_dir) | ||
|
||
os.makedirs(output_dir, exist_ok=True) | ||
fpm_arguments.extend(['--package', output_dir]) | ||
|
||
command = ['fpm', *fpm_arguments, 'setup.py'] | ||
|
||
results = run_command(workspace_dir, command, r'.*"(.+\.deb)"') | ||
|
||
for result in results: | ||
if not result.startswith('/'): | ||
result = output_dir if arguments.output_dir else f'{workspace_dir}/{result}' | ||
print(result) | ||
|
||
|
||
def _get_arguments() -> Namespace: | ||
parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter) | ||
parser.add_argument('-a', '--arguments', help='extra arguments passed to fpm') | ||
parser.add_argument('-p', '--python-bin', help='python executable to use', default='python3') | ||
parser.add_argument('-o', '--output-dir', help='package output directory') | ||
parser.add_argument('workspace_dir', help='workspace directory where setup.py is located') | ||
return parser.parse_args() | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
Oops, something went wrong.