Skip to content

Commit

Permalink
refactor: use f-strings, absolute imports and more
Browse files Browse the repository at this point in the history
  • Loading branch information
fyhertz committed Oct 7, 2022
1 parent 14d97d0 commit b47e7c1
Show file tree
Hide file tree
Showing 9 changed files with 79 additions and 97 deletions.
6 changes: 3 additions & 3 deletions src/_wheel2deb/apt.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

import attr

from .logger import logging
from .tools import shell
from _wheel2deb.logger import logging
from _wheel2deb.utils import shell

# https://www.debian.org/doc/debian-policy/ch-controlfields.html#version
PACKAGE_VER_RE = re.compile(
Expand Down Expand Up @@ -52,7 +52,7 @@ def search_packages(names, arch):
if not names:
return

logger.debug("searching %s in apt cache...", " ".join(names))
logger.debug(f"searching {' '.join(names)} in apt cache...")

for name in names:
yield search_package(name, arch)
76 changes: 26 additions & 50 deletions src/_wheel2deb/tools.py → src/_wheel2deb/build.py
Original file line number Diff line number Diff line change
@@ -1,51 +1,54 @@
import re
import subprocess
from pathlib import Path
from threading import Event, Thread
from time import sleep

from .logger import logging
from _wheel2deb.logger import logging
from _wheel2deb.utils import shell

logger = logging.getLogger(__name__)


def shell(args, **kwargs):
def parse_debian_control(cwd: Path):
"""
Replacement for subprocess.run on platforms without python3.5
:param args: Command and parameters in a list
:return: A tuple with (command output, return code)
Extract fields from debian/control
:param cwd: Path to debian source package
:return: Dict object with fields as keys
"""

output, returncode = "", 0
logger.debug("running %s", " ".join(args))
try:
if "cwd" in kwargs:
# convert cwd to str in case it's a Path
kwargs["cwd"] = str(kwargs["cwd"])
output = subprocess.check_output(args, stderr=subprocess.STDOUT, **kwargs)
except subprocess.CalledProcessError as e:
returncode = e.returncode
output = e.output
field_re = re.compile(r"^([\w-]+)\s*:\s*(.+)")

return output.decode("utf-8"), returncode
content = (cwd / "debian" / "control").read_text()
control = {}
for line in content.split("\n"):
m = field_re.search(line)
if m:
g = m.groups()
control[g[0]] = g[1]

for k in ("Build-Depends", "Depends"):
m = re.findall(r"([^=\s,()]+)\s?(?:\([^)]+\))?", control[k])
control[k] = m

return control

def build_package(cwd):

def build_package(cwd: Path) -> int:
"""Run dpkg-buildpackage in specified path."""
args = ["dpkg-buildpackage", "-us", "-uc"]
arch = parse_debian_control(cwd)["Architecture"]
if arch != "all":
args += ["--host-arch", arch]

output, returncode = shell(args, cwd=cwd)
logger.debug(output)
stdout, returncode = shell(args, cwd=cwd)
logger.debug(stdout)
if returncode:
logger.error('failed to build package in "%s" ☹', str(cwd))
logger.error(f'failed to build package in "{cwd}" ☹')

return returncode


def build_packages(paths, threads=4):
def build_packages(paths, threads: int = 4) -> None:
"""
Run several instances of dpkg-buildpackage in parallel.
:param paths: List of paths where dpkg-buildpackage will be called
Expand All @@ -60,7 +63,7 @@ def build_packages(paths, threads=4):
workers.append(dict(done=event, path=None))

def build(done, path):
logger.info("building %s", path)
logger.info(f"building {path}")
build_package(path)
done.set()

Expand All @@ -71,30 +74,3 @@ def build(done, path):
w["path"] = paths.pop()
Thread(target=build, kwargs=w).start()
sleep(1)


def parse_debian_control(cwd):
"""
Extract fields from debian/control
:param cwd: Path to debian source package
:return: Dict object with fields as keys
"""

if isinstance(cwd, str):
cwd = Path(cwd)

field_re = re.compile(r"^([\w-]+)\s*:\s*(.+)")

content = (cwd / "debian" / "control").read_text()
control = {}
for line in content.split("\n"):
m = field_re.search(line)
if m:
g = m.groups()
control[g[0]] = g[1]

for k in ("Build-Depends", "Depends"):
m = re.findall(r"([^=\s,()]+)\s?(?:\([^)]+\))?", control[k])
control[k] = m

return control
4 changes: 2 additions & 2 deletions src/_wheel2deb/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
import attr
import yaml

from .pyvers import Version
from .version import __version__
from _wheel2deb.pyvers import Version
from _wheel2deb.version import __version__


@attr.s
Expand Down
14 changes: 7 additions & 7 deletions src/_wheel2deb/debian.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
from setuptools.command.install_scripts import install_scripts
from setuptools.dist import Distribution

from .depends import normalize_package_version, search_python_deps, suggest_name
from .logger import logging
from .templates import environment
from .tools import shell
from .version import __version__
from _wheel2deb.depends import normalize_package_version, search_python_deps, suggest_name
from _wheel2deb.logger import logging
from _wheel2deb.templates import environment
from _wheel2deb.utils import shell
from _wheel2deb.version import __version__

logger = logging.getLogger(__name__)
dirsync_logger = logging.getLogger("dirsync")
Expand Down Expand Up @@ -271,7 +271,7 @@ def search_shlibs_deps(self):
+ ["-l" + str(self.src / x) for x in self.wheel.record.lib_dirs]
+ [str(self.src / x) for x in self.wheel.record.libs]
)
output = shell(args, cwd=self.root)[0]
output, _ = shell(args, cwd=self.root)
missing_libs.update(DPKG_SHLIBS_RE.findall(output, re.MULTILINE))

if missing_libs:
Expand All @@ -283,7 +283,7 @@ def search_shlibs_deps(self):

# search packages providing those libs
for lib in missing_libs:
output = shell(["apt-file", "search", lib, "-a", self.arch])[0]
output, _ = shell(["apt-file", "search", lib, "-a", self.arch])
packages = set(APT_FILE_RE.findall(output))

# remove dbg packages
Expand Down
24 changes: 10 additions & 14 deletions src/_wheel2deb/depends.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

from packaging.version import parse

from .apt import search_packages
from .logger import logging
from _wheel2deb.apt import search_packages
from _wheel2deb.logger import logging

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -96,7 +96,7 @@ def search_python_deps(ctx, wheel, extras=None):
# filter out ignored requirements
def is_required(r):
if r.name in ctx.ignore_requirements:
logger.warning("ignoring requirement %s", str(r))
logger.warning(f"ignoring requirement {str(r)}")
return False
else:
return True
Expand Down Expand Up @@ -124,9 +124,9 @@ def is_required(r):

def check(x):
if req.specifier.contains(x.version, prereleases=True):
logger.info("%s satisfies requirement %s", x, req)
logger.info(f"{x} satisfies requirement {req}")
else:
logger.warning("%s does not satisfy requirement %s", x, req)
logger.warning(f"{x} does not satisfy requirement {req}")
return ctx.ignore_upstream_versions or req.specifier.contains(
x.version, prereleases=True
)
Expand All @@ -138,11 +138,11 @@ def check(x):
version = candidate.version

if not version:
logger.error("could not find a candidate for requirement %s", req)
logger.error(f"could not find a candidate for requirement {req}")
missing_deps.append(str(req))

if req.name in ctx.ignore_specifiers:
logger.warning("ignoring specifiers for dependency %s", req.name)
logger.warning(f"ignoring specifiers for dependency {req.name}")
debian_deps.append(pdep)
elif not ctx.ignore_upstream_versions and len(req.specifier):
for specifier in req.specifier:
Expand All @@ -166,17 +166,13 @@ def get_dependency_string(package_name, operator, version):
parsed = parse(v)
if len(parsed.release) == 1:
# For versions of the form "x" or "x.*". This will return "{x+1}.0"
return "%s (<< %s)" % (package_name, parsed.release[0] + 1)
return f"{package_name} (<< {parsed.release[0] + 1})"
elif len(parsed.release) > 1:
# For version of the form "x.y" or "x.y.z". This will return "x.{y+1}"
return "%s (<< %s.%s)" % (
package_name,
parsed.release[0],
parsed.release[1] + 1,
)
return f"{package_name} (<< {parsed.release[0]}.{parsed.release[1] + 1})"
if operator == "<=":
v += "-+"
return "%s (%s %s)" % (package_name, _translate_op(operator), v)
return f"{package_name} ({_translate_op(operator)} {v})"

return None

Expand Down
16 changes: 8 additions & 8 deletions src/_wheel2deb/pydist.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
from pkginfo import Distribution
from wheel.wheelfile import WheelFile

from .logger import logging
from .pyvers import Version, VersionRange
from _wheel2deb.logger import logging
from _wheel2deb.pyvers import Version, VersionRange

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -43,17 +43,17 @@ def from_str(cls, content):
record = Record()
for file in files:
if re.search(cls.LICENSE_RE, file):
logger.debug("found license: %s", file)
logger.debug(f"found license: {file}")
record.licenses.append(file)
continue

if ".data/scripts/" in file:
logger.debug("found script: %s", file)
logger.debug(f"found script: {file}")
record.scripts.append(file)
continue

if re.findall(cls.SHLIBS_RE, os.path.basename(file)):
logger.debug("found shared lib: %s", file)
logger.debug(f"found shared lib: {file}")
record.libs.append(file)

if file:
Expand Down Expand Up @@ -84,10 +84,10 @@ def __init__(self, filepath, extract_path=None):
)

if not filepath.exists():
raise ValueError("No such file: %s" % filepath)
raise ValueError(f"No such file: {filepath}")

if not self.filename.endswith(".whl"):
raise ValueError("Not a known wheel archive format: %s" % filepath)
raise ValueError(f"Not a known wheel archive format: {filepath}")

# parse wheel name
# https://www.python.org/dev/peps/pep-0425
Expand Down Expand Up @@ -171,7 +171,7 @@ def _unpack(self):
return

with WheelFile(str(self.filepath)) as wf:
logger.debug("unpacking wheel to: %s..." % self.extract_path)
logger.debug(f"unpacking wheel to: {self.extract_path}...")
wf.extractall(str(self.extract_path))

def __repr__(self):
Expand Down
10 changes: 10 additions & 0 deletions src/_wheel2deb/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import subprocess
from pathlib import Path
from typing import List, Tuple


def shell(args: List[str], cwd: Path | None = None) -> Tuple[str, int]:
result = subprocess.run(
args, cwd=cwd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT
)
return result.stdout.decode("utf-8"), result.returncode
24 changes: 12 additions & 12 deletions src/wheel2deb.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@
from pathlib import Path

from _wheel2deb import logger as logging
from _wheel2deb import tools
from _wheel2deb.build import build_packages
from _wheel2deb.context import Settings, load
from _wheel2deb.debian import SourcePackage
from _wheel2deb.pydist import Wheel

logger = logging.getLogger(__name__)

DEFAULT_CONFIG_NAME = "wheel2deb.yml"
EXTRACT_PATH = Path("/tmp/wheel2deb")


Expand Down Expand Up @@ -82,8 +83,8 @@ def debianize(args):
# load config file
if args.config:
settings = load(args.config)
elif Path("wheel2deb.yml").is_file():
settings = load("wheel2deb.yml")
elif Path(DEFAULT_CONFIG_NAME).is_file():
settings = load(DEFAULT_CONFIG_NAME)
else:
settings = Settings()

Expand Down Expand Up @@ -122,13 +123,13 @@ def debianize(args):

if not wheel.cpython_supported:
# ignore wheels that are not cpython compatible
logger.warning("%s does not support cpython", wheel.filename)
logger.warning(f"{wheel.filename} does not support cpython")
continue

if not wheel.version_supported(ctx.python_version):
# ignore wheels that are not compatible specified python version
logger.warning(
"%s does not support python %s", wheel.filename, ctx.python_version
f"{wheel.filename} does not support python {ctx.python_version}"
)
continue

Expand All @@ -138,7 +139,7 @@ def debianize(args):
packages = []
for wheel in wheels:
if wheel.filename in args.include:
logger.task("Debianizing wheel %s", wheel)
logger.task(f"Debianizing wheel {wheel}")
ctx = settings.get_ctx(wheel.filename)
package = SourcePackage(ctx, wheel, args.output, extras=wheels)
package.create()
Expand Down Expand Up @@ -183,8 +184,8 @@ def build(argv):
# source package already built, skipping build
src_packages.remove(path)

logger.task("Building %s source packages...", len(src_packages))
tools.build_packages(src_packages, args.threads)
logger.task(f"Building {len(src_packages)} source packages...")
build_packages(src_packages, args.threads)


def main():
Expand All @@ -207,10 +208,9 @@ def main():
debianize(args)

logger.summary(
"\nWarnings: %s. Errors: %s. Elapsed: %ss.",
logging.get_warning_counter(),
logging.get_error_counter(),
round(time.time() - start_time, 3),
f"\nWarnings: {logging.get_warning_counter()}. "
f"Errors: {logging.get_error_counter()}. "
f"Elapsed: {round(time.time() - start_time, 3)}s."
)

# the return code is the number of errors
Expand Down
2 changes: 1 addition & 1 deletion tests/test_tools.py → tests/test_build.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from _wheel2deb.tools import parse_debian_control
from _wheel2deb.build import parse_debian_control

DEBIAN_CONTROL = """\
Source: python-absl-py
Expand Down

0 comments on commit b47e7c1

Please sign in to comment.