1
0
Fork 1
mirror of https://gitlab.postmarketos.org/postmarketOS/pmbootstrap.git synced 2025-07-13 11:29:46 +03:00
pmbootstrap/pmb/helpers/file.py
Caleb Connolly 31cc898dd5
treewide: adopt pathlib.Path and type hinting (MR 2252)
With the new chroot type, we can now write fancy paths in the pythonic
way. Convert most of the codebase over, as well as adding various other
type hints.

Signed-off-by: Caleb Connolly <caleb@postmarketos.org>
2024-06-23 12:38:37 +02:00

104 lines
3.3 KiB
Python

# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
import os
from pathlib import Path
import time
from pmb.core.types import PmbArgs
import pmb.helpers.run
import pmb.helpers.pmaports
def replace(path: Path, old: str, new: str):
text = ""
with path.open("r", encoding="utf-8") as handle:
text = handle.read()
text = text.replace(old, new)
with path.open("w", encoding="utf-8") as handle:
handle.write(text)
def replace_apkbuild(args: PmbArgs, pkgname, key, new, in_quotes=False):
"""Replace one key=value line in an APKBUILD and verify it afterwards.
:param pkgname: package name, e.g. "hello-world"
:param key: key that should be replaced, e.g. "pkgver"
:param new: new value
:param in_quotes: expect the value to be in quotation marks ("")
"""
# Read old value
path = pmb.helpers.pmaports.find(args, pkgname) / "APKBUILD"
apkbuild = pmb.parse.apkbuild(path)
old = apkbuild[key]
# Prepare old/new strings
if in_quotes:
line_old = '{}="{}"'.format(key, old)
line_new = '{}="{}"'.format(key, new)
else:
line_old = '{}={}'.format(key, old)
line_new = '{}={}'.format(key, new)
# Replace
replace(path, "\n" + line_old + "\n", "\n" + line_new + "\n")
# Verify
del (pmb.helpers.other.cache["apkbuild"][path])
apkbuild = pmb.parse.apkbuild(path)
if apkbuild[key] != str(new):
raise RuntimeError("Failed to set '{}' for pmaport '{}'. Make sure"
" that there's a line with exactly the string '{}'"
" and nothing else in: {}".format(key, pkgname,
line_old, path))
def is_up_to_date(path_sources, path_target=None, lastmod_target=None):
"""Check if a file is up-to-date by comparing the last modified timestamps.
(just like make does it).
:param path_sources: list of full paths to the source files
:param path_target: full path to the target file
:param lastmod_target: the timestamp of the target file. specify this as
alternative to specifying path_target.
"""
if path_target and lastmod_target:
raise RuntimeError(
"Specify path_target *or* lastmod_target, not both!")
lastmod_source = None
for path_source in path_sources:
lastmod = os.path.getmtime(path_source)
if not lastmod_source or lastmod > lastmod_source:
lastmod_source = lastmod
if path_target:
lastmod_target = os.path.getmtime(path_target)
return lastmod_target >= lastmod_source
def is_older_than(path, seconds):
"""Check if a single file is older than a given amount of seconds."""
if not os.path.exists(path):
return True
lastmod = os.path.getmtime(path)
return lastmod + seconds < time.time()
def symlink(args: PmbArgs, file: Path, link: Path):
"""Check if the symlink is already present, otherwise create it."""
if os.path.exists(link):
if (os.path.islink(link) and
os.path.realpath(os.readlink(link)) == os.path.realpath(file)):
return
raise RuntimeError(f"File exists: {link}")
elif link.is_symlink():
link.unlink()
# Create the symlink
pmb.helpers.run.user(args, ["ln", "-s", file, link])