diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2942410eb..aa9d46ae6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -264,7 +264,7 @@ jobs: sudo ln -s ~/go/bin/swupd-extract /usr/bin/swupd-extract - name: Build ${{ matrix.distro }}/${{ matrix.format }} - run: sudo ./mkosi + run: sudo python3 -m mkosi --debug run --distribution ${{ matrix.distro }} --format ${{ matrix.format }} @@ -272,7 +272,7 @@ jobs: - name: Build ${{ matrix.distro }}/${{ matrix.format }} UEFI if: matrix.format != 'directory' && matrix.format != 'tar' && matrix.format != 'plain_squashfs' && (matrix.distro != 'clear' || matrix.format != 'gpt_squashfs') && matrix.distro != 'photon' - run: sudo ./mkosi + run: sudo python3 -m mkosi --debug run --distribution ${{ matrix.distro }} --format ${{ matrix.format }} @@ -282,7 +282,7 @@ jobs: - name: Build ${{ matrix.distro }}/${{ matrix.format }} BIOS if: matrix.format != 'directory' && matrix.format != 'tar' && !contains(matrix.format, 'squashfs') - run: sudo ./mkosi + run: sudo python3 -m mkosi --debug run --distribution ${{ matrix.distro }} --format ${{ matrix.format }} diff --git a/README.md b/README.md index ed944eff9..c95b34265 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,31 @@ bells and whistles. For a longer description and available features and options, see the [man page](mkosi.md). +# Installation + +Installing `mkosi` is easy, as it has no runtime Python dependencies (you will +need all the tools to format filesystems and bootstrap the distribution +appropriate for your image, though). + +If you just want the current master branch you can run +```shell +python3 -m pip install --user git+https://github.com/systemd/mkosi.git +``` + +If you want to hack on mkosi do +```shell +# clone either this repository or your fork of it +git clone https://github.com/systemd/mkosi/ +cd mkosi +python3 -m pip install --user --editable . +``` +This will install mkosi in editable mode to `~/.local/bin/mkosi`, allowing you +to use your own changes right away. + +For development you optionally also need [mypy](https://github.com/python/mypy) +and [pytest](https://github.com/pytest-dev/pytest). We check tests and typing in +CI (see `.github/workflows`), but you can run the tests locally as well. + # References * [Primary mkosi git repository on GitHub](https://github.com/systemd/mkosi/) diff --git a/mkosi.py b/mkosi.py deleted file mode 120000 index b5f44fa8e..000000000 --- a/mkosi.py +++ /dev/null @@ -1 +0,0 @@ -mkosi \ No newline at end of file diff --git a/mkosi b/mkosi/__init__.py old mode 100755 new mode 100644 similarity index 99% rename from mkosi rename to mkosi/__init__.py index 88ede9b5f..a949b0ef3 --- a/mkosi +++ b/mkosi/__init__.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 -# PYTHON_ARGCOMPLETE_OK # SPDX-License-Identifier: LGPL-2.1+ import argparse @@ -59,10 +57,6 @@ __version__ = '5' -if sys.version_info < (3, 6): - sys.exit("Sorry, we need at least Python 3.6.") - - # These types are only generic during type checking and not at runtime, leading # to a TypeError during compilation. # Let's be as strict as we can with the description for the usage we have. @@ -5320,25 +5314,3 @@ def run_verb(args: CommandLineArguments) -> None: if args.verb == "qemu": run_qemu(args) - - -def main() -> None: - try: - args = parse_args() - - for job_name, a in args.items(): - # Change working directory if --directory is passed - if a.directory: - work_dir = a.directory - if os.path.isdir(work_dir): - os.chdir(work_dir) - else: - die("Error: %s is not a directory!" % work_dir) - with complete_step('Processing ' + job_name): - run_verb(a) - except MkosiException: - sys.exit(1) - - -if __name__ == "__main__": - main() diff --git a/mkosi/__main__.py b/mkosi/__main__.py new file mode 100644 index 000000000..0ba6a4785 --- /dev/null +++ b/mkosi/__main__.py @@ -0,0 +1,23 @@ +# SPDX-License-Identifier: LGPL-2.1+ +# PYTHON_ARGCOMPLETE_OK +import os +import sys + +from . import parse_args, complete_step, run_verb, die, MkosiException + + +try: + args = parse_args() + + for job_name, a in args.items(): + # Change working directory if --directory is passed + if a.directory: + work_dir = a.directory + if os.path.isdir(work_dir): + os.chdir(work_dir) + else: + die(f"Error: {work_dir} is not a directory!") + with complete_step(f"Processing {job_name}"): + run_verb(a) +except MkosiException: + sys.exit(1) diff --git a/setup.py b/setup.py index 813921e22..9512aad03 100755 --- a/setup.py +++ b/setup.py @@ -1,8 +1,6 @@ #!/usr/bin/python3 # SPDX-License-Identifier: LGPL-2.1+ -import sys - from setuptools import setup, Command class BuildManpage(Command): @@ -17,9 +15,6 @@ def finalize_options(self): def run(self): self.spawn(['pandoc', '-t', 'man', '-o', 'mkosi.1', 'mkosi.md']) -if sys.version_info < (3, 6): - sys.exit("Sorry, we need at least Python 3.6.") - setup( name="mkosi", @@ -29,6 +24,8 @@ def run(self): maintainer="mkosi contributors", maintainer_email="systemd-devel@lists.freedesktop.org", license="LGPLv2+", - scripts=["mkosi"], - cmdclass = { "man": BuildManpage } + python_requires=">=3.6", + packages = ["mkosi"], + cmdclass = { "man": BuildManpage }, + entry_points = {"console_scripts": ["mkosi=mkosi.__main__"]}, ) diff --git a/tests/conftest.py b/tests/conftest.py index 5a00d434b..938fcbcd1 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -2,13 +2,8 @@ import sys import os -dir_path = os.path.dirname(os.path.realpath(__file__)) -import importlib.util -spec = importlib.util.spec_from_file_location('mkosi', os.path.join(dir_path, '../mkosi.py')) -mkosi_module = importlib.util.module_from_spec(spec) -spec.loader.exec_module(mkosi_module) -sys.modules['mkosi'] = mkosi_module +import mkosi from tests.test_config_parser import MkosiConfig diff --git a/tests/test_config_parser.py b/tests/test_config_parser.py index fafbd27de..f0312445e 100644 --- a/tests/test_config_parser.py +++ b/tests/test_config_parser.py @@ -1,16 +1,12 @@ # SPDX-License-Identifier: LGPL-2.1+ +import configparser +import copy import os -dir_path = os.path.dirname(os.path.realpath(__file__)) - -import importlib.util -spec = importlib.util.spec_from_file_location('mkosi', os.path.join(dir_path, '../mkosi.py')) -mkosi = importlib.util.module_from_spec(spec) -spec.loader.exec_module(mkosi) import pytest -import configparser -import copy + +import mkosi class ChangeCwd(object):