Fiw-Gentoo-Dots/lib/device_presets.py

49 lines
1.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Named local selections for individual devices; no hardware identifiers."""
import json
import re
import tempfile
from pathlib import Path
def path(repo, name):
if not re.fullmatch(r'[a-z0-9][a-z0-9_-]{0,47}', name):
raise ValueError('Use 1–48 lowercase letters, digits, underscores or hyphens for a device preset name.')
root = repo / 'local/devices'
if not root.resolve().is_relative_to(repo.resolve()):
raise RuntimeError('Device preset directory points outside the checkout.')
target = root / (name + '.json')
if target.is_symlink():
raise RuntimeError('Device preset is a symlink; preserving it.')
return target
def list_presets(repo, load):
root = repo / 'local/devices'
result = {}
for candidate in sorted(root.glob('*.json')):
try:
checked = path(repo, candidate.stem)
result[candidate.stem] = load(checked)
except (ValueError, OSError, RuntimeError):
# A malformed local file cannot block the normal installer.
continue
return result
def save(repo, name, selection, ask):
destination = path(repo, name)
if destination.exists() and ask('Replace saved device preset ' + name + '?', ['save', 'keep'], 'keep') != 'save':
print('Kept device preset: ' + name)
return
destination.parent.mkdir(parents=True, exist_ok=True)
# Use a new inode and refuse links; saved selections stay user-readable only.
with tempfile.NamedTemporaryFile(mode='w', dir=destination.parent, prefix='.device-', delete=False) as stream:
temporary = Path(stream.name)
json.dump(dict(selection, name=name), stream, indent=2)
stream.write('\n')
try:
temporary.chmod(0o600)
temporary.replace(destination)
finally:
temporary.unlink(missing_ok=True)
print('Saved device preset: ' + name)