From 1d7fb3a5d9729d1510ec671bd106fc94340e3da9 Mon Sep 17 00:00:00 2001 From: Michal Suchanek Date: Wed, 16 Oct 2024 21:44:41 +0200 Subject: [PATCH] Revert "Modernize build system" This reverts commit 05f9481b4566f84a26c32be6e0dfb10c64442d5e. This 'modernization' breaks installation of bash-completion and configuration file. Until that's addressed such 'modernization' is broken. Fixes: #181 --- .github/workflows/pylint.yml | 21 +++----- MANIFEST.in | 1 + Makefile | 4 +- README.md | 11 ++-- pyproject.toml | 22 -------- requirements.txt | 5 ++ setup.py | 98 ++++++++++++++++++++++++++++++------ virtme_ng/run.py | 11 ++-- 8 files changed, 108 insertions(+), 65 deletions(-) create mode 100644 MANIFEST.in delete mode 100644 pyproject.toml create mode 100644 requirements.txt diff --git a/.github/workflows/pylint.yml b/.github/workflows/pylint.yml index 869354a..bb0adb1 100644 --- a/.github/workflows/pylint.yml +++ b/.github/workflows/pylint.yml @@ -11,26 +11,17 @@ jobs: matrix: python-version: ["3.8", "3.9", "3.10"] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 + uses: actions/setup-python@v3 with: python-version: ${{ matrix.python-version }} - name: Install dependencies run: | - set -euxo pipefail - python -m pip install --upgrade pip - - # Both build and runtime deps. This is the price of using pip. - pip install 'argparse-manpage[setuptools]' argcomplete requests - - pip install pylint flake8 + pip install -r requirements.txt + pip install pylint + pip install flake8 - name: Analysing the code with pylint run: | - set -euxo pipefail - - pylint vng '**/*.py' - - flake8 vng - find . -name '*.py' | xargs flake8 + python setup.py lint diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..f9bd145 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1 @@ +include requirements.txt diff --git a/Makefile b/Makefile index d36b450..24dc74f 100644 --- a/Makefile +++ b/Makefile @@ -7,8 +7,8 @@ GIT_DESCRIBE := $(shell git describe --always --long --dirty) install: install_from_source install_from_source: @echo "Version: $(GIT_DESCRIBE)" - BUILD_VIRTME_NG_INIT=1 pip3 install --verbose $(INSTALL_ARGS) . + BUILD_VIRTME_NG_INIT=1 pip3 install --verbose -r requirements.txt $(INSTALL_ARGS) . install_only_top: @echo "Version: $(GIT_DESCRIBE)" - BUILD_VIRTME_NG_INIT=0 pip3 install --verbose $(INSTALL_ARGS) . + BUILD_VIRTME_NG_INIT=0 pip3 install --verbose -r requirements.txt $(INSTALL_ARGS) . diff --git a/README.md b/README.md index 1a7bb77..cad1e98 100644 --- a/README.md +++ b/README.md @@ -79,19 +79,18 @@ To install virtme-ng from source you can clone this git repository and build a standalone virtme-ng running the following commands: ``` $ git clone --recurse-submodules https://github.com/arighi/virtme-ng.git - $ BUILD_VIRTME_NG_INIT=1 pip3 install . + $ BUILD_VIRTME_NG_INIT=1 pip3 install --verbose -r requirements.txt . ``` If you are in Debian/Ubuntu you may need to install the following packages to build virtme-ng from source properly: ``` - $ sudo apt install python3-pip flake8 pylint cargo rustc qemu-system-x86 + $ sudo apt install python3-pip python3-argcomplete flake8 pylint \ + cargo rustc qemu-system-x86 ``` -If you'd prefer to use `uv`: -``` - $ BUILD_VIRTME_NG_INIT=1 uv tool install . -``` +In recent versions of pip3 you may need to specify `--break-system-packages` to +properly install virtme-ng in your system from source. * Run from source diff --git a/pyproject.toml b/pyproject.toml deleted file mode 100644 index dfd34df..0000000 --- a/pyproject.toml +++ /dev/null @@ -1,22 +0,0 @@ -[build-system] -requires = [ - "argparse-manpage[setuptools]", - "setuptools", - - # Runtime dependencies, needed to generate manpages. - "argcomplete", - "requests", -] - -[tool.build_manpages] -manpages = [ - """\ - man/vng.1\ - :pyfile=virtme_ng/run.py\ - :function=make_parser\ - :author=virtme-ng is written by Andrea Righi \ - :author=Based on virtme by Andy Lutomirski \ - :manual_title=virtme-ng\ - :description=Quickly run kernels inside a virtualized snapshot of your live system\ - """, -] diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..40f89a7 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,5 @@ +argcomplete +argparse-manpage +requests +setuptools + diff --git a/setup.py b/setup.py index d69918f..753a3e4 100755 --- a/setup.py +++ b/setup.py @@ -1,12 +1,13 @@ #!/usr/bin/env python3 import os -import platform import sys +import platform import sysconfig -from subprocess import check_call -from build_manpages import build_manpages, get_build_py_cmd, get_install_cmd -from setuptools import setup +from glob import glob +from shutil import which +from subprocess import check_call, CalledProcessError +from setuptools import setup, Command from setuptools.command.build_py import build_py from setuptools.command.egg_info import egg_info from virtme_ng.version import get_version_string @@ -34,6 +35,56 @@ os.environ['PYTHONPATH'] = sysconfig.get_paths()['purelib'] +def is_arm_32bit(): + arch = platform.machine() + return arch.startswith("arm") and platform.architecture()[0] == "32bit" + + +def parse_requirements(filename): + with open(filename, 'r', encoding="utf-8") as file: + lines = file.readlines() + return [line.strip() for line in lines if line.strip() and not line.startswith('#')] + + +class LintCommand(Command): + description = "Run coding style checks" + user_options = [] + + def initialize_options(self): + pass + + def finalize_options(self): + pass + + def run(self): + try: + for cmd in ("flake8", "pylint"): + command = [cmd] + for pattern in ( + "vng", + "*.py", + "virtme/*.py", + "virtme/*/*.py", + "virtme_ng/*.py", + ): + command += glob(pattern) + check_call(command) + except CalledProcessError: + sys.exit(1) + + +man_command = f""" +argparse-manpage \ + --pyfile ./virtme_ng/run.py --function make_parser \ + --prog vng --version v{VERSION} \ + --author "virtme-ng is written by Andrea Righi " \ + --author "Based on virtme by Andy Lutomirski " \ + --project-name virtme-ng --manual-title virtme-ng \ + --description "Quickly run kernels inside a virtualized snapshot of your live system" \ + --url https://github.com/arighi/virtme-ng > vng.1 +""" + + class BuildPy(build_py): def run(self): print(f"BUILD_VIRTME_NG_INIT: {build_virtme_ng_init}") @@ -56,6 +107,23 @@ def run(self): ["strip", os.path.join(root, "bin", "virtme-ng-init")], cwd=cwd, ) + # Generate manpage + if which('argparse-manpage'): + env = os.environ.copy() + env["PYTHONPATH"] = os.path.dirname(os.path.abspath(__file__)) + check_call(man_command, shell=True, env=env) + + # Generate bash autocompletion scripts + completion_command = '' + if which("register-python-argcomplete"): + completion_command = "register-python-argcomplete" + elif which("register-python-argcomplete3"): + completion_command = "register-python-argcomplete3" + else: + print("ERROR: 'register-python-argcomplete' or 'register-python-argcomplete3' not found.") + sys.exit(1) + check_call(completion_command + ' virtme-ng > virtme-ng-prompt', shell=True) + check_call(completion_command + ' vng > vng-prompt', shell=True) # Run the rest of virtme-ng build build_py.run(self) @@ -98,28 +166,26 @@ def run(self): data_files = [ ("/etc", ["cfg/virtme-ng.conf"]), + ("/usr/share/bash-completion/completions", ["virtme-ng-prompt"]), + ("/usr/share/bash-completion/completions", ["vng-prompt"]), ] +if which('argparse-manpage'): + data_files.append(("/usr/share/man/man1", ["vng.1"])) + setup( name="virtme-ng", version=VERSION, author="Andrea Righi", author_email="arighi@nvidia.com", description="Build and run a kernel inside a virtualized snapshot of your live system", - url="https://github.com/arighi/virtme-ng", + url="https://git.launchpad.net/~arighi/+git/virtme-ng", license="GPLv2", long_description=open( os.path.join(os.path.dirname(__file__), "README.md"), "r", encoding="utf-8" ).read(), long_description_content_type="text/markdown", - install_requires=[ - 'argcomplete', - 'requests', - # `pkg_resources` is removed in python 3.12, moved to setuptools. - # - # TODO: replace pkg_resources with importlib. # pylint: disable=fixme - 'setuptools', - ], + install_requires=parse_requirements('requirements.txt'), entry_points={ "console_scripts": [ "vng = virtme_ng.run:main", @@ -130,13 +196,13 @@ def run(self): ] }, cmdclass={ - "build_manpages": build_manpages, - "build_py": get_build_py_cmd(BuildPy), - "install": get_install_cmd(), + "build_py": BuildPy, "egg_info": EggInfo, + "lint": LintCommand, }, packages=packages, package_data={"virtme.guest": package_files}, + data_files=data_files, scripts=[ "bin/virtme-prep-kdir-mods", ], diff --git a/virtme_ng/run.py b/virtme_ng/run.py index 2d0fda9..e0c53ee 100644 --- a/virtme_ng/run.py +++ b/virtme_ng/run.py @@ -23,8 +23,12 @@ ) from select import select from pathlib import Path - -import argcomplete +try: + from argcomplete import autocomplete +except ModuleNotFoundError: + def autocomplete(*args, **kwargs): + # pylint: disable=unused-argument + pass from virtme.util import SilentError, get_username from virtme_ng.utils import CONF_FILE, spinner_decorator @@ -75,7 +79,6 @@ def make_parser(): """Main virtme-ng command line parser.""" parser = argparse.ArgumentParser( - prog="vng", formatter_class=argparse.RawTextHelpFormatter, description="Build and run kernels inside a virtualized snapshot of your live system", epilog="""\ @@ -1242,7 +1245,7 @@ def dump(kern_source, args): def do_it() -> int: """Main body.""" - argcomplete.autocomplete(_ARGPARSER) + autocomplete(_ARGPARSER) args = _ARGPARSER.parse_args() kern_source = KernelSource()