Skip to content

Commit

Permalink
use flit instead of setuptools
Browse files Browse the repository at this point in the history
Since we don't need to build tree-sitter-bash lib, we became pure python
package, where flit is much better suited for this task. This now also
matches other packages under pkgcore stack. This simplifies a lot the
release process, as we don't need to build the lib anymore using
cibuildwheel.

Signed-off-by: Arthur Zamarin <[email protected]>
  • Loading branch information
arthurzam committed Mar 23, 2024
1 parent 82be768 commit a641348
Show file tree
Hide file tree
Showing 5 changed files with 181 additions and 259 deletions.
75 changes: 19 additions & 56 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,15 @@ on:
workflow_dispatch:

jobs:
build-sdist:
build-and-deploy:
runs-on: ubuntu-latest
environment: release

permissions:
id-token: write # Used to authenticate to PyPI via OIDC

contents: write # Used to authenticate github release publish

steps:
- name: Checkout code
uses: actions/checkout@v4
Expand All @@ -34,78 +41,34 @@ jobs:
make man
make sdist
- name: Build wheel
run: make wheel

- name: Output dist file info
run: |
sha512sum dist/*
tar -ztf dist/*.tar.gz | sort
- name: Upload sdist artifact
uses: actions/upload-artifact@v4
with:
name: dist-sdist
path: dist/*.tar.gz


build-wheel:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
arch: [x86_64, aarch64]

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: ${{matrix.arch}}

- name: Build wheels
uses: joerick/[email protected]
with:
output-dir: dist
env:
CIBW_ARCHS_LINUX: ${{matrix.arch}}

- name: Upload wheel artifacts
uses: actions/upload-artifact@v4
with:
name: dist-wheel-${{matrix.arch}}
path: dist/*.whl


deploy:
if: startsWith(github.ref, 'refs/tags/')
needs: ["build-sdist", "build-wheel"]
runs-on: ubuntu-latest
environment: release

permissions:
id-token: write # Used to authenticate to PyPI via OIDC

contents: write # Used to authenticate github release publish

steps:
- uses: actions/download-artifact@v4
- uses: actions/upload-artifact@v4
with:
pattern: dist-*
path: dist
merge-multiple: true
name: results
path: dist/*

- name: Publish a Python distribution to PyPI
- name: publish
uses: pypa/gh-action-pypi-publish@release/v1
if: startsWith(github.ref, 'refs/tags/')

- name: Create GitHub release
uses: softprops/action-gh-release@v1
if: startsWith(github.ref, 'refs/tags/')
with:
files: dist/*.tar.gz
fail_on_unmatched_files: true
draft: true

build-and-push-docker-image:
if: startsWith(github.ref, 'refs/tags/')
needs: ["deploy"]
needs: ["build-and-deploy"]
runs-on: ubuntu-latest
environment: release

Expand Down
14 changes: 0 additions & 14 deletions MANIFEST.in

This file was deleted.

147 changes: 147 additions & 0 deletions py_build.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
import sys
from collections import defaultdict
from functools import partial
from contextlib import contextmanager
from pathlib import Path
from textwrap import dedent

from flit_core import buildapi


@contextmanager
def sys_path():
orig_path = sys.path[:]
sys.path.insert(0, str(Path.cwd() / "src"))
try:
yield
finally:
sys.path = orig_path


def write_verinfo(cleanup_files):
from snakeoil.version import get_git_version

cleanup_files.append(path := Path.cwd() / "src/pkgcheck/_verinfo.py")
path.parent.mkdir(parents=True, exist_ok=True)
print(f"generating version info: {path}")
path.write_text(f"version_info={get_git_version(Path.cwd())!r}")


def write_const(cleanup_files):
cleanup_files.append(path := Path.cwd() / "src/pkgcheck/_const.py")
print(f"writing path constants to {path}")
with path.open("w") as f:
path.chmod(0o644)
f.write(
dedent(
"""\
from os.path import abspath, exists, join
import sys
INSTALL_PREFIX = abspath(sys.prefix)
if not exists(join(INSTALL_PREFIX, 'lib/pkgcore')):
INSTALL_PREFIX = abspath(sys.base_prefix)
DATA_PATH = join(INSTALL_PREFIX, 'share/pkgcheck')
"""
)
)


def write_objects(cleanup_files):
cleanup_files.append(path := Path.cwd() / "src/pkgcheck/_objects.py")
print(f"writing objects to {path}")

class _kls:
def __init__(self, module):
self.module = module

def __repr__(self):
return self.module

with sys_path():
from pkgcheck import objects

modules = defaultdict(set)
objs = defaultdict(list)
for obj in ("KEYWORDS", "CHECKS", "REPORTERS"):
for name, cls in getattr(objects, obj).items():
parent, module = cls.__module__.rsplit(".", 1)
modules[parent].add(module)
objs[obj].append((name, _kls(f"{module}.{name}")))

keywords = tuple(objs["KEYWORDS"])
checks = tuple(objs["CHECKS"])
reporters = tuple(objs["REPORTERS"])

with path.open("w") as f:
path.chmod(0o644)
for k, v in sorted(modules.items()):
f.write(f"from {k} import {', '.join(sorted(v))}\n")
f.write(
dedent(
f"""\
KEYWORDS = {keywords}
CHECKS = {checks}
REPORTERS = {reporters}
"""
)
)


def write_files(cleanup_files):
with sys_path():
from pkgcheck import base, objects
from pkgcheck.addons import caches

(dst := Path.cwd() / "data/share/pkgcheck").mkdir(parents=True, exist_ok=True)

print("Generating available scopes")
cleanup_files.append(path := dst / "scopes")
path.write_text("\n".join(base.scopes) + "\n")

print("Generating available cache types")
cache_objs = caches.CachedAddon.caches.values()
cleanup_files.append(path := dst / "caches")
path.write_text("\n".join(x.type for x in cache_objs) + "\n")

for obj in ("KEYWORDS", "CHECKS", "REPORTERS"):
print(f"Generating {obj.lower()} list")
cleanup_files.append(path := dst / obj.lower())
path.write_text("\n".join(getattr(objects, obj)) + "\n")


def prepare_pkgcheck(callback, only_version: bool):
cleanup_files = []
try:
write_verinfo(cleanup_files)
if not only_version:
write_const(cleanup_files)
write_objects(cleanup_files)
write_files(cleanup_files)

return callback()
finally:
for path in cleanup_files:
try:
path.unlink()
except OSError:
pass


def build_wheel(wheel_directory, config_settings=None, metadata_directory=None):
"""Builds a wheel, places it in wheel_directory"""
callback = partial(buildapi.build_wheel, wheel_directory, config_settings, metadata_directory)
return prepare_pkgcheck(callback, only_version=False)


def build_editable(wheel_directory, config_settings=None, metadata_directory=None):
"""Builds an "editable" wheel, places it in wheel_directory"""
callback = partial(
buildapi.build_editable, wheel_directory, config_settings, metadata_directory
)
return prepare_pkgcheck(callback, only_version=True)


def build_sdist(sdist_directory, config_settings=True):
"""Builds an sdist, places it in sdist_directory"""
callback = partial(buildapi.build_sdist, sdist_directory, config_settings)
return prepare_pkgcheck(callback, only_version=True)
59 changes: 15 additions & 44 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
[build-system]
requires = [
"setuptools >= 61.0.0",
"wheel",
"flit_core >=3.8,<4",
# repeat all normal runtime dependencies here
"chardet",
"lazy-object-proxy",
Expand All @@ -12,7 +11,8 @@ requires = [
"snakeoil~=0.10.7",
"pkgcore~=0.12.25",
]
build-backend = "setuptools.build_meta"
build-backend = "py_build"
backend-path = ["."]

[project]
name = "pkgcheck"
Expand Down Expand Up @@ -48,7 +48,6 @@ dependencies = [
"tree-sitter-bash>=0.21.0",
"snakeoil~=0.10.7",
"pkgcore~=0.12.25",
"setuptools; python_version >= '3.12'",
]

[project.optional-dependencies]
Expand All @@ -74,11 +73,19 @@ Source = "https://github.com/pkgcore/pkgcheck"
[project.scripts]
pkgcheck = "pkgcheck.scripts.__init__:main"

[tool.setuptools]
zip-safe = false
[tool.flit.external-data]
directory = "data"

[tool.setuptools.dynamic]
version = {attr = "pkgcheck.__version__"}
[tool.flit.sdist]
include = [
"Makefile", "py_build.py", "tox.ini",
"NEWS.rst", "doc", "tests", "testdata", "contrib",
"build/sphinx/man/pkgcheck.1",
]
exclude = [
".github/", ".gitignore",
"doc/api/", "doc/generated/", "doc/_build/",
]

[tool.black]
line-length = 100
Expand All @@ -87,39 +94,3 @@ line-length = 100
minversion = "6.0"
addopts = "-vv -ra -l"
testpaths = ["tests"]

[tool.cibuildwheel]
build = "cp310-*"
build-frontend = "build"

before-build = [
"rm -f {project}/src/pkgcheck/bash/lang.so"
]
test-requires = ["pytest", "requests"]
test-command = "pytest {project}/tests"

# glibc 2.24
manylinux-x86_64-image = "manylinux_2_28"
manylinux-i686-image = "manylinux_2_28"
manylinux-aarch64-image = "manylinux_2_28"
manylinux-ppc64le-image = "manylinux_2_28"
manylinux-s390x-image = "manylinux_2_28"
test-skip = "*-*linux_{aarch64,ppc64le,s390x}"

[[tool.cibuildwheel.overrides]]
select = "*-musllinux*"
before-all = [
"apk add --no-cache git bash libxml2-dev libxslt-dev",
]

[[tool.cibuildwheel.overrides]]
select = "*-manylinux*"
before-all = [
# "apt-get update",
# "apt-get install -y git libxml2-dev libxslt-dev",
"yum update -y --nogpgcheck",
"yum install -y --nogpgcheck git libxslt-devel libxml2-devel",

"curl -L \"https://github.com/robxu9/bash-static/releases/download/5.2.015-1.2.3-2/bash-linux-$(uname -m)\" -o /usr/local/bin/bash",
"chmod +x /usr/local/bin/bash",
]
Loading

0 comments on commit a641348

Please sign in to comment.