Merge pull request #14 from d9pouces/dev

Dev
This commit is contained in:
d9pouces
2026-10-09 20:46:39 +02:00
committed by GitHub
14 changed files with 59 additions and 16 deletions
+4 -3
View File
@@ -62,7 +62,7 @@ from cryptography.hazmat.primitives.serialization import (
from id_configurator.config import JavaRepository, NamedContent
from id_configurator.context import Context
from id_configurator.modules.base import Module, register
from id_configurator.modules.base import Module, register, sanitize_repository_name
logger = logging.getLogger(__name__)
@@ -170,17 +170,18 @@ def _build_maven_settings(repositories: list[JavaRepository]) -> ET.Element:
repositories_el = ET.SubElement(profile, "repositories")
plugin_repositories_el = ET.SubElement(profile, "pluginRepositories")
for repository in repositories:
name = sanitize_repository_name(repository.name)
for parent, tag in (
(repositories_el, "repository"),
(plugin_repositories_el, "pluginRepository"),
):
entry = ET.SubElement(parent, tag)
ET.SubElement(entry, "id").text = repository.name
ET.SubElement(entry, "id").text = name
ET.SubElement(entry, "url").text = repository.url
active_profiles = ET.SubElement(settings, "activeProfiles")
ET.SubElement(active_profiles, "activeProfile").text = "id-configurator"
mirror = ET.SubElement(ET.SubElement(settings, "mirrors"), "mirror")
ET.SubElement(mirror, "id").text = repositories[0].name
ET.SubElement(mirror, "id").text = sanitize_repository_name(repositories[0].name)
ET.SubElement(mirror, "url").text = repositories[0].url
ET.SubElement(mirror, "mirrorOf").text = "*"
return settings
+15 -2
View File
@@ -41,7 +41,19 @@ _DISTUTILS_GLOBS = ("usr/lib/python3.*", "usr/local/lib/python3.*")
def _toml_string(value: str) -> str:
return json.dumps(value)
"""Render `value` as a TOML basic string.
JSON and TOML basic strings share the same escape syntax, so
`json.dumps` is a convenient way to produce one - *except* for
non-ASCII characters: with the default `ensure_ascii=True`, a
character outside the Basic Multilingual Plane (e.g. an emoji) comes
out as a UTF-16 surrogate pair (`\\uXXXX\\uXXXX`), which is valid JSON
but not valid TOML - TOML's `\\uXXXX` must itself be a Unicode scalar
value, not one half of a surrogate pair. `ensure_ascii=False` instead
leaves every non-ASCII character as a literal, raw UTF-8 character,
which TOML basic strings allow directly.
"""
return json.dumps(value, ensure_ascii=False)
def _trusted_host(repository: PythonRepository) -> str | None:
@@ -68,8 +80,9 @@ def _write_pip_conf(context: Context, repositories: list[PythonRepository]) -> N
def _write_uv_toml(context: Context, repositories: list[PythonRepository]) -> None:
lines = ["native-tls = true", ""]
for position, repository in enumerate(repositories):
name = sanitize_repository_name(repository.name)
lines.append("[[index]]")
lines.append(f"name = {_toml_string(repository.name)}")
lines.append(f"name = {_toml_string(name)}")
lines.append(f"url = {_toml_string(repository.index_url)}")
if position == 0:
lines.append("default = true")
+1 -1
View File
@@ -44,7 +44,7 @@ maintainers = [
name = "id-configurator"
readme = "README.md"
requires-python = ">=3.13"
version = "2026.10.6"
version = "2026.10.9"
[project.scripts]
id-configurator = "id_configurator:main"
+1 -1
View File
@@ -10,7 +10,7 @@ configurations:
sources: []
apk:
repositories:
- name: demo
- name: 'demo _.-/\$.:@;''"'
{% set scheme = 'APK_REPO_SCHEME' | env %}
url: {{ scheme }}://host.docker.internal:{{ ('APK_REPO_PORT' if scheme == 'https' else 'APK_REPO_HTTP_PORT') | env }}/
url_to_replace: https://dl-cdn.alpinelinux.org/*
+1 -1
View File
@@ -25,7 +25,7 @@ configurations:
repositories: []
go:
repositories:
- name: demo
- name: 'demo _.-/\$.:@;''"'
{% set scheme = 'GO_REPO_SCHEME' | env %}
url: {{ scheme }}://host.docker.internal:{{ ('GO_REPO_PORT' if scheme == 'https' else 'GO_REPO_HTTP_PORT') | env }}/
ruby:
+1 -1
View File
@@ -21,7 +21,7 @@ configurations:
repositories: []
npm:
repositories:
- name: demo
- name: 'demo _.-/\$.:@;''"'
{% set scheme = 'NPM_REPO_SCHEME' | env %}
url: {{ scheme }}://host.docker.internal:{{ ('NPM_REPO_PORT' if scheme == 'https' else 'NPM_REPO_HTTP_PORT') | env }}/
rust:
+1 -1
View File
@@ -29,6 +29,6 @@ configurations:
repositories: []
nuget:
repositories:
- name: demo
- name: 'demo _.-/\$.:@;''"'
{% set scheme = 'NUGET_REPO_SCHEME' | env %}
url: {{ scheme }}://host.docker.internal:{{ ('NUGET_REPO_PORT' if scheme == 'https' else 'NUGET_REPO_HTTP_PORT') | env }}/index.json
+1 -1
View File
@@ -19,7 +19,7 @@ configurations:
repositories: []
php:
repositories:
- name: demo
- name: 'demo _.-/\$.:@;''"'
{% set scheme = 'PHP_REPO_SCHEME' | env %}
url: {{ scheme }}://host.docker.internal:{{ ('PHP_REPO_PORT' if scheme == 'https' else 'PHP_REPO_HTTP_PORT') | env }}/
npm:
+1 -1
View File
@@ -15,7 +15,7 @@ configurations:
keys: []
python:
repositories:
- name: demo
- name: 'demo _.-/\$.:@;''"'
{% set scheme = 'PYPI_REPO_SCHEME' | env %}
index-url: {{ scheme }}://host.docker.internal:{{ ('PYPI_REPO_PORT' if scheme == 'https' else 'PYPI_REPO_HTTP_PORT') | env }}/simple/
java:
+1 -1
View File
@@ -27,7 +27,7 @@ configurations:
repositories: []
ruby:
repositories:
- name: demo
- name: 'demo _.-/\$.:@;''"'
{% set scheme = 'RUBY_REPO_SCHEME' | env %}
url: {{ scheme }}://host.docker.internal:{{ ('RUBY_REPO_PORT' if scheme == 'https' else 'RUBY_REPO_HTTP_PORT') | env }}/
nuget:
+1 -1
View File
@@ -23,7 +23,7 @@ configurations:
repositories: []
rust:
repositories:
- name: demo
- name: 'demo _.-/\$.:@;''"'
{% set scheme = 'CARGO_REPO_SCHEME' | env %}
url: {{ scheme }}://host.docker.internal:{{ ('CARGO_REPO_PORT' if scheme == 'https' else 'CARGO_REPO_HTTP_PORT') | env }}/
is_sparse: true
+1 -1
View File
@@ -12,7 +12,7 @@ configurations:
repositories: []
yum:
repositories:
- name: demo
- name: 'demo _.-/\$.:@;''"'
{% set scheme = 'YUM_REPO_SCHEME' | env %}
index-url: {{ scheme }}://host.docker.internal:{{ ('YUM_REPO_PORT' if scheme == 'https' else 'YUM_REPO_HTTP_PORT') | env }}/
index-url-to-replace: https://mirrors.rockylinux.org/*
+29
View File
@@ -1,3 +1,5 @@
import tomllib
from id_configurator.config import Configuration
from id_configurator.context import Context
from id_configurator.modules.python import PythonModule
@@ -76,6 +78,33 @@ def test_apply_single_repository(tmp_path) -> None:
assert not (dst / "usr/lib").exists()
def test_apply_sanitizes_uv_index_name_with_non_bmp_characters(tmp_path) -> None:
data = {
"uuid": "12345678-1234-5678-1234-567812345678",
"organisation": "InterDiode",
"configurations": {
"python": {
"repositories": [
{"name": "demo 😀", "index-url": "https://example.invalid/simple"}
]
}
},
}
config = Configuration.model_validate(data)
dst = tmp_path / "dst"
context = Context(config=config, dst=dst, src=None)
PythonModule().apply(context)
uv_toml = (dst / "etc/uv/uv.toml").read_text(encoding="utf-8")
# The emoji isn't a plain identifier character, so sanitize_repository_name
# replaces it (and the space before it) with "_", same as every other
# non-ASCII or syntax-breaking character.
assert '"demo__"' in uv_toml
parsed = tomllib.loads(uv_toml)
assert parsed["index"][0]["name"] == "demo__"
def test_apply_adds_trusted_host_for_non_https_repository(tmp_path) -> None:
data = {
"uuid": "12345678-1234-5678-1234-567812345678",
Generated
+1 -1
View File
@@ -424,7 +424,7 @@ dependencies = [
]
name = "id-configurator"
source = {editable = "."}
version = "2026.10.6"
version = "2026.10.9"
[package.dev-dependencies]
dev = [