Skip to content

Commit

Permalink
otk: detect circular imports
Browse files Browse the repository at this point in the history
This commit adds detection of cirular imports.
  • Loading branch information
mvo5 committed Jun 24, 2024
1 parent 842ea69 commit e12240f
Show file tree
Hide file tree
Showing 8 changed files with 30 additions and 9 deletions.
6 changes: 6 additions & 0 deletions src/otk/error.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,9 @@ class TransformDirectiveUnknownError(TransformError):
"""Unknown directive."""

pass


class CircularIncludeError(OTKError):
"""Cirtcular include detected."""

pass
14 changes: 8 additions & 6 deletions src/otk/transform.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,17 @@

import itertools
import logging
import os
import pathlib
import re
from typing import Any, List

import yaml

from . import tree
from .constant import (NAME_VERSION, PREFIX, PREFIX_DEFINE, PREFIX_INCLUDE,
PREFIX_OP, PREFIX_TARGET)
from .constant import NAME_VERSION, PREFIX, PREFIX_DEFINE, PREFIX_INCLUDE, PREFIX_OP, PREFIX_TARGET
from .context import Context, OSBuildContext
from .error import TransformDirectiveTypeError, TransformDirectiveUnknownError
from .error import CircularIncludeError, TransformDirectiveTypeError, TransformDirectiveUnknownError
from .external import call
from .traversal import State

Expand Down Expand Up @@ -65,7 +65,6 @@ def resolve_dict(ctx: Context, state: State, tree: dict[str, Any]) -> Any:
if isinstance(val, str):
val = substitute_vars(ctx, val)
if is_directive(key):

if key.startswith(PREFIX_DEFINE):
process_defines(ctx, state, val)
continue
Expand Down Expand Up @@ -170,20 +169,23 @@ def process_include(ctx: Context, state: State, path: pathlib.Path) -> dict:
"""
# resolve 'path' relative to 'state.path'
cur_path = state.path.parent
path = cur_path / pathlib.Path(path)
path = (cur_path / pathlib.Path(path)).resolve()
try:
with open(path, mode="r", encoding="utf=8") as fp:
data = yaml.safe_load(fp)
except FileNotFoundError as fnfe:
raise FileNotFoundError(f"file {path} referenced from {state.path} was not found") from fnfe

if data is not None:
if path in state.includes:
circle = [os.fspath(p) for p in state.includes]
raise CircularIncludeError(f"circular include from {circle}")
new_state = state.copy(path=path)
new_state.includes.append(path)
return resolve(ctx, new_state, data)
return {}



@tree.must_be(str)
def include(ctx: Context, tree: Any) -> Any:
"""Include a separate file."""
Expand Down
11 changes: 8 additions & 3 deletions src/otk/traversal.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
class State:
def __init__(self, path, defines):
def __init__(self, path, defines, includes=None):
self.path = path
self.defines = defines
if includes is None:
includes = []
self.includes = includes

def copy(self, *, path=None, defines=None) -> "State":
def copy(self, *, path=None, defines=None, includes=None) -> "State":
"""
Return a new State, optionally redefining the path and defines
properties. Properties not defined in the args are (shallow) copied
Expand All @@ -16,5 +19,7 @@ def copy(self, *, path=None, defines=None) -> "State":
path = self.path
if defines is None:
defines = self.defines
if includes is None:
includes = self.includes.copy()

return State(path, defines)
return State(path, defines, includes)
1 change: 1 addition & 0 deletions test/data/error/01-circular.err
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
circular include from
4 changes: 4 additions & 0 deletions test/data/error/01-circular.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
otk.version: 1

otk.target.osbuild.name:
otk.include: 01-circular/a.yaml
1 change: 1 addition & 0 deletions test/data/error/01-circular/a.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
otk.include: b.yaml
1 change: 1 addition & 0 deletions test/data/error/01-circular/b.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
otk.include: subdir/c.yaml
1 change: 1 addition & 0 deletions test/data/error/01-circular/subdir/c.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
otk.include: ../a.yaml

0 comments on commit e12240f

Please sign in to comment.