Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

examples: fix up #64

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 45 additions & 1 deletion example/fedora/minimal-40-aarch64.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,49 @@ otk.version: 1
otk.define:
version: 40
architecture: "aarch64"
isolabel: Fedora-${version}-${architecture}

otk.include: "minimal-common.yaml"
packages:
# Repositories to fetch packages from
repositories:
otk.include: "repository/${version}/repositories.yaml"
# GPG keys to verify packages with
keys:
otk.include: "repository/${version}/keys.yaml"
# These packages are used in the buildroot
buildroot:
docs: false
weak: false
packages:
otk.include: "packages/${version}/_buildroot.yaml"
# These packages are used for the operating system tree which is what ends
# up in the outputs.
tree:
docs: false
weak: false
packages:
otk.include: "packages/${version}/minimal.yaml"
filesystem:
root:
uuid: "6e4ff95f-f662-45ee-a82a-bdf44a2d0b75"
vfs_type: "ext4"
path: "/"
options: "defaults"
boot:
uuid: "0194fdc2-fa2f-4cc0-81d3-ff12045b73c8"
vfs_type: "ext4"
path: "/boot"
options: "defaults"
boot-efi:
uuid: "7B77-95E7"
vfs_type: "vfat"
path: "/boot/efi"
options: "defaults,uid=0,gid=0,umask=077,shortname=winnt"
passno: 2

otk.target.osbuild:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we can do better here, not including the pipelines from something like "common.yaml" will mean we have quite a bit of duplication.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could resolve includes before omnifest validation.

pipelines:
- otk.include: "osbuild/buildroot.yaml"
- otk.include: "osbuild/pipeline/tree.yaml"
- otk.include: "osbuild/pipeline/raw.yaml"
- otk.include: "osbuild/pipeline/xz.yaml"
46 changes: 45 additions & 1 deletion example/fedora/minimal-40-x86_64.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,49 @@ otk.version: 1
otk.define:
version: 40
architecture: "x86_64"
isolabel: Fedora-${version}-${architecture}

otk.include: "minimal-common.yaml"
packages:
# Repositories to fetch packages from
repositories:
otk.include: "repository/${version}/repositories.yaml"
# GPG keys to verify packages with
keys:
otk.include: "repository/${version}/keys.yaml"
# These packages are used in the buildroot
buildroot:
docs: false
weak: false
packages:
otk.include: "packages/${version}/_buildroot.yaml"
# These packages are used for the operating system tree which is what ends
# up in the outputs.
tree:
docs: false
weak: false
packages:
otk.include: "packages/${version}/minimal.yaml"
filesystem:
root:
uuid: "6e4ff95f-f662-45ee-a82a-bdf44a2d0b75"
vfs_type: "ext4"
path: "/"
options: "defaults"
boot:
uuid: "0194fdc2-fa2f-4cc0-81d3-ff12045b73c8"
vfs_type: "ext4"
path: "/boot"
options: "defaults"
boot-efi:
uuid: "7B77-95E7"
vfs_type: "vfat"
path: "/boot/efi"
options: "defaults,uid=0,gid=0,umask=077,shortname=winnt"
passno: 2

otk.target.osbuild:
pipelines:
- otk.include: "osbuild/buildroot.yaml"
- otk.include: "osbuild/pipeline/tree.yaml"
- otk.include: "osbuild/pipeline/raw.yaml"
- otk.include: "osbuild/pipeline/xz.yaml"
47 changes: 0 additions & 47 deletions example/fedora/minimal-common.yaml

This file was deleted.

52 changes: 31 additions & 21 deletions src/otk/directive.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import itertools
import logging
import pathlib
import re
from typing import Any, List

import yaml
Expand Down Expand Up @@ -172,34 +173,43 @@ def desugar(ctx: Context, tree: str) -> Any:
then we replace the values inside the string. This requires the type of
the variable to be replaced to be either str, int, or float."""

# TODO use parsimonous instead of this
bracket = r"\$\{%s\}"
pattern = bracket % r"(?P<name>[a-zA-Z0-9-_\.]+)"

if tree.startswith("${"):
name = tree[2 : tree.index("}")]
data = ctx.variable(tree[2 : tree.index("}")])
log.debug("desugaring %r as fullstring to %r", name, data)
return ctx.variable(tree[2 : tree.index("}")])
# If there is a single match and its span is the entire haystack then we
# return its value directly.
if match := re.fullmatch(pattern, tree):
return ctx.variable(match.group("name"))

if "${" in tree:
name = tree[tree.index("${") + 2 : tree.index("}")]
head = tree[: tree.index("${")]
tail = tree[tree.index("}") + 1 :]
# Let's find all matches if there are any. We use `list(re.finditer(...))`
# to get a list of match objects instead of `re.findall` which gives a list
# of matchgroups.

data = ctx.variable(name)
# If there are multiple matches then we always interpolate strings.
if matches := list(re.finditer(pattern, tree)):
for match in matches:
name = match.group("name")
data = ctx.variable(name)

if isinstance(data, (int, float)):
data = str(data)
# We now how to turn ints and floats into str's
if isinstance(data, (int, float)):
data = str(data)

if not isinstance(data, str):
raise TransformDirectiveTypeError(
"string sugar resolves to an incorrect type, expected int, float, or str but got %r",
data,
)
# Any other type we do not
if not isinstance(data, str):
raise TransformDirectiveTypeError(
"string sugar resolves to an incorrect type, expected int, float, or str but got %r",
data,
)

data = head + data + tail
# Replace all occurences of this name in the str

log.debug("desugaring %r as substring to %r", name, data)
# NOTE: this means we can recursively replace names, do we want
# that?
tree = re.sub(bracket % re.escape(name), data, tree)

return data
log.debug("desugaring %r as substring to %r", name, tree)

return tree

return tree
50 changes: 50 additions & 0 deletions test/test_directive_sugar.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import pytest

from otk.context import CommonContext
from otk.document import Omnifest
from otk.error import TransformDirectiveTypeError
from otk.directive import desugar


def test_simple_sugar():
context = CommonContext()
context.define("my_var", "foo")

assert desugar(context, "${my_var}") == "foo"


def test_simple_sugar_tree():
context = CommonContext()
context.define("my_var", [1, 2])

assert desugar(context, "${my_var}") == [1, 2]


def test_simple_sugar_tree_fail():
context = CommonContext()
context.define("my_var", [1, 2])

expected_error = "string sugar resolves to an incorrect type, expected int, float, or str but got %r"

with pytest.raises(TransformDirectiveTypeError, match=expected_error):
desugar(context, "a${my_var}")


def test_sugar_multiple():
context = CommonContext()
context.define("a", "foo")
context.define("b", "bar")

assert desugar(context, "${a}-${b}") == "foo-bar"


def test_sugar_multiple_fail():
context = CommonContext()
context.define("a", "foo")
context.define("b", [1, 2])

expected_error = "string sugar resolves to an incorrect type, expected int, float, or str but got %r"

# Fails due to non-str type
with pytest.raises(TransformDirectiveTypeError, match=expected_error):
desugar(context, "${a}-${b}")
67 changes: 0 additions & 67 deletions test/test_sugar.py

This file was deleted.