diff --git a/package/share/ahriman/templates/build-status/package-info-modal.jinja2 b/package/share/ahriman/templates/build-status/package-info-modal.jinja2 index bc55a70c..311c9abe 100644 --- a/package/share/ahriman/templates/build-status/package-info-modal.jinja2 +++ b/package/share/ahriman/templates/build-status/package-info-modal.jinja2 @@ -163,7 +163,7 @@ const variableValueInput = document.createElement("input"); variableValueInput.classList.add("form-control"); variableValueInput.readOnly = true; - variableValueInput.value = variable.value; + variableValueInput.value = JSON.stringify(variable.value); const variableButtonRemove = document.createElement("button"); variableButtonRemove.type = "button"; diff --git a/src/ahriman/models/pkgbuild_patch.py b/src/ahriman/models/pkgbuild_patch.py index 9c6f9d32..d935dcb8 100644 --- a/src/ahriman/models/pkgbuild_patch.py +++ b/src/ahriman/models/pkgbuild_patch.py @@ -100,11 +100,11 @@ class PkgbuildPatch: return cls(**filter_json(dump, known_fields)) @classmethod - def parse(cls, key: str | None, source: str) -> Self: + def parse(cls, key: str | None, source: str | list[str]) -> Self: """ parse string value to the PKGBUILD patch value. This method simply takes string, tries to identify it as array or just string and return the respective value. Functions are returned as is. Shell arrays and single values - are returned without quotes + are returned without quotes. If source is ``list``, then value is returned as is Args: key(str | None): variable key @@ -118,6 +118,9 @@ class PkgbuildPatch: case function if key is not None and key.endswith("()"): # the key looks like a function, no further processing should be applied here return function + case list(): + # do not try to perform operations on the list, just return as is + return source case shell_array if shell_array.startswith("(") and shell_array.endswith(")"): # the source value looks like shell array, remove brackets and parse with shlex return shlex.split(shell_array[1:-1]) diff --git a/src/ahriman/web/views/v1/packages/patches.py b/src/ahriman/web/views/v1/packages/patches.py index 8b068ed4..23444483 100644 --- a/src/ahriman/web/views/v1/packages/patches.py +++ b/src/ahriman/web/views/v1/packages/patches.py @@ -101,6 +101,6 @@ class PatchesView(StatusViewGuard, BaseView): except Exception as ex: raise HTTPBadRequest(reason=str(ex)) - self.service().package_patches_update(package_base, PkgbuildPatch(key, value)) + self.service().package_patches_update(package_base, PkgbuildPatch.parse(key, value)) raise HTTPNoContent diff --git a/src/ahriman/web/views/v1/service/add.py b/src/ahriman/web/views/v1/service/add.py index e862797e..d8d4403c 100644 --- a/src/ahriman/web/views/v1/service/add.py +++ b/src/ahriman/web/views/v1/service/add.py @@ -68,7 +68,7 @@ class AddView(BaseView): try: data = await self.request.json() packages = self.get_non_empty(lambda key: [package for package in data[key] if package], "packages") - patches = [PkgbuildPatch(patch["key"], patch.get("value", "")) for patch in data.get("patches", [])] + patches = [PkgbuildPatch.parse(patch["key"], patch.get("value", "")) for patch in data.get("patches", [])] except Exception as ex: raise HTTPBadRequest(reason=str(ex)) diff --git a/src/ahriman/web/views/v1/service/request.py b/src/ahriman/web/views/v1/service/request.py index 9fda2e56..c24984f1 100644 --- a/src/ahriman/web/views/v1/service/request.py +++ b/src/ahriman/web/views/v1/service/request.py @@ -68,7 +68,7 @@ class RequestView(BaseView): try: data = await self.request.json() packages = self.get_non_empty(lambda key: [package for package in data[key] if package], "packages") - patches = [PkgbuildPatch(patch["key"], patch.get("value", "")) for patch in data.get("patches", [])] + patches = [PkgbuildPatch.parse(patch["key"], patch.get("value", "")) for patch in data.get("patches", [])] except Exception as ex: raise HTTPBadRequest(reason=str(ex)) diff --git a/tests/ahriman/models/test_pkgbuild_patch.py b/tests/ahriman/models/test_pkgbuild_patch.py index 92755e44..ca27956e 100644 --- a/tests/ahriman/models/test_pkgbuild_patch.py +++ b/tests/ahriman/models/test_pkgbuild_patch.py @@ -61,6 +61,7 @@ def test_parse() -> None: assert PkgbuildPatch.parse("key", """("QU'OUTED" ARRAY VALUE)""").value == ["QU'OUTED", "ARRAY", "VALUE"] assert PkgbuildPatch.parse("key()", """{ function with " quotes }""").value == """{ function with " quotes }""" assert PkgbuildPatch.parse("key", json.dumps(["array", "value"])).value == ["array", "value"] + assert PkgbuildPatch.parse("key", ["array", "value"]).value == ["array", "value"] def test_quote() -> None: diff --git a/tests/ahriman/web/views/v1/packages/test_view_v1_packages_patches.py b/tests/ahriman/web/views/v1/packages/test_view_v1_packages_patches.py index b337e968..efaeb06e 100644 --- a/tests/ahriman/web/views/v1/packages/test_view_v1_packages_patches.py +++ b/tests/ahriman/web/views/v1/packages/test_view_v1_packages_patches.py @@ -82,6 +82,25 @@ async def test_post_full_diff(client: TestClient, package_ahriman: Package) -> N assert patches == [payload] +async def test_post_array(client: TestClient, package_ahriman: Package) -> None: + """ + must create patch from list variable + """ + await client.post(f"/api/v1/packages/{package_ahriman.base}", + json={"status": BuildStatusEnum.Success.value, "package": package_ahriman.view()}) + request_schema = pytest.helpers.schema_request(PatchesView.post) + + payload = {"key": "k", "value": "(array value)"} + assert not request_schema.validate(payload) + response = await client.post(f"/api/v1/packages/{package_ahriman.base}/patches", json=payload) + assert response.status == 204 + + response = await client.get(f"/api/v1/packages/{package_ahriman.base}/patches") + patches = await response.json() + parsed = [PkgbuildPatch(patch["key"], patch["value"]) for patch in patches] + assert parsed == [PkgbuildPatch("k", ["array", "value"])] + + async def test_post_exception(client: TestClient, package_ahriman: Package) -> None: """ must raise exception on invalid payload