From df75e1102cfa80da41b0390316cdd241d1b6bd30 Mon Sep 17 00:00:00 2001 From: Nathaniel van Diepen Date: Thu, 5 Sep 2024 20:47:17 -0600 Subject: [PATCH] Fix field_arch not working properly --- .gitignore | 1 + pyproject.toml | 2 +- tests/recipe_parsers/test_installdepends.py | 179 ++++++++++++++++++++ toltec/recipe_parsers/bash.py | 46 ++--- 4 files changed, 205 insertions(+), 23 deletions(-) create mode 100644 tests/recipe_parsers/test_installdepends.py diff --git a/.gitignore b/.gitignore index cd7b834..0dcbd65 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ dist *.onefile-build toltecmk env/ +.venv diff --git a/pyproject.toml b/pyproject.toml index 2ffd94d..b0340e2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "toltecmk" -version = "0.3.2" +version = "0.3.3" authors = [ { name="Mattéo Delabre", email="git.matteo@delab.re" }, { name="Eeems", email="eeems@eeems.email" }, diff --git a/tests/recipe_parsers/test_installdepends.py b/tests/recipe_parsers/test_installdepends.py new file mode 100644 index 0000000..0d28db4 --- /dev/null +++ b/tests/recipe_parsers/test_installdepends.py @@ -0,0 +1,179 @@ +# Copyright (c) 2021 The Toltec Contributors +# SPDX-License-Identifier: MIT + +import os +import re +from os import path +import unittest +from tempfile import TemporaryDirectory +from datetime import datetime, timezone +from toltec import parse_recipe +from toltec.bash import ScriptError +from toltec.recipe import Package, Recipe, Source, RecipeError, RecipeWarning +from toltec.version import ( + Version, + Dependency, + DependencyKind, + VersionComparator, +) + + +class TestInstallDepends(unittest.TestCase): + def setUp(self) -> None: + self.dir_handle = TemporaryDirectory() + self.dir = self.dir_handle.name + + def tearDown(self) -> None: + self.dir = None + self.dir_handle.cleanup() + + def test_installdepends(self) -> None: + """Check that basic fields are parsed.""" + rec_path = path.join(self.dir, "toltec-base") + os.makedirs(rec_path) + + with open(path.join(rec_path, "package"), "w") as rec_def_file: + rec_def_file.write( + """ +archs=(rmall rmallos2 rmallos3 rm1 rm1os2 rm1os3 rm2 rm2os2 rm2os3) +pkgnames=(toltec-base) +pkgdesc="Metapackage defining the base set of packages in a Toltec install" +url=https://toltec-dev.org/ +pkgver=1.4-1 +timestamp=2023-12-27T08:30Z +section="utils" +maintainer="Eeems " +license=MIT +installdepends=(toltec-bootstrap toltec-deletions toltec-completion launcherctl wget-ssl ca-certificates entware-rc) +installdepends_rm1os2=(open-remarkable-shutdown) +installdepends_rm1os3=(open-remarkable-shutdown) +installdepends_rm2os2=(rm2-suspend-fix) +installdepends_rm2os3=(rm2-suspend-fix) + +image=base:v2.1 +source=("https://example.org/toltec/${pkgnames[0]}/release-${pkgver%-*}.zip") +sha256sums=(SKIP) + +build() { + echo "Build function" +} + +package() { + echo "Package function" +} +""" + ) + + basic_depends = [ + Dependency(DependencyKind.HOST, x) + for x in [ + "toltec-bootstrap", + "toltec-deletions", + "toltec-completion", + "launcherctl", + "wget-ssl", + "ca-certificates", + "entware-rc", + ] + ] + rm1_depends = [ + Dependency(DependencyKind.HOST, "open-remarkable-shutdown") + ] + rm2_depends = [Dependency(DependencyKind.HOST, "rm2-suspend-fix")] + + recipes = parse_recipe(rec_path) + + self.assertEqual( + list(recipes.keys()), + [ + "rmall", + "rmallos2", + "rmallos3", + "rm1", + "rm1os2", + "rm1os3", + "rm2", + "rm2os2", + "rm2os3", + ], + ) + recipe = recipes["rmall"] + self.assertIs(type(recipe), Recipe) + self.assertEqual(list(recipe.packages.keys()), ["toltec-base"]) + package = recipe.packages["toltec-base"] + self.assertEqual( + package.installdepends, + set(basic_depends), + ) + + recipe = recipes["rm1"] + self.assertIs(type(recipe), Recipe) + package = recipe.packages["toltec-base"] + self.assertEqual(list(recipe.packages.keys()), ["toltec-base"]) + self.assertEqual( + package.installdepends, + set(basic_depends), + ) + + recipe = recipes["rm2"] + self.assertIs(type(recipe), Recipe) + package = recipe.packages["toltec-base"] + self.assertEqual(list(recipe.packages.keys()), ["toltec-base"]) + self.assertEqual( + package.installdepends, + set(basic_depends), + ) + + recipe = recipes["rmallos2"] + self.assertIs(type(recipe), Recipe) + package = recipe.packages["toltec-base"] + self.assertEqual(list(recipe.packages.keys()), ["toltec-base"]) + self.assertEqual( + package.installdepends, + set(basic_depends), + ) + + recipe = recipes["rmallos3"] + self.assertIs(type(recipe), Recipe) + package = recipe.packages["toltec-base"] + self.assertEqual(list(recipe.packages.keys()), ["toltec-base"]) + self.assertEqual( + package.installdepends, + set(basic_depends), + ) + + recipe = recipes["rm1os2"] + self.assertIs(type(recipe), Recipe) + package = recipe.packages["toltec-base"] + self.assertEqual(list(recipe.packages.keys()), ["toltec-base"]) + self.assertEqual( + package.installdepends, + set(basic_depends + rm1_depends), + ) + + recipe = recipes["rm1os3"] + self.assertIs(type(recipe), Recipe) + package = recipe.packages["toltec-base"] + self.assertEqual(list(recipe.packages.keys()), ["toltec-base"]) + self.assertEqual( + package.installdepends, + set(basic_depends + rm1_depends), + ) + + recipe = recipes["rm2os2"] + self.assertIs(type(recipe), Recipe) + package = recipe.packages["toltec-base"] + self.assertEqual(list(recipe.packages.keys()), ["toltec-base"]) + self.assertEqual( + package.installdepends, + set(basic_depends + rm2_depends), + ) + + recipe = recipes["rm2os3"] + self.assertIs(type(recipe), Recipe) + package = recipe.packages["toltec-base"] + self.assertEqual(list(recipe.packages.keys()), ["toltec-base"]) + self.assertEqual( + package.installdepends, + set(basic_depends + rm2_depends), + ) diff --git a/toltec/recipe_parsers/bash.py b/toltec/recipe_parsers/bash.py index 8499d28..d6793ad 100644 --- a/toltec/recipe_parsers/bash.py +++ b/toltec/recipe_parsers/bash.py @@ -2,6 +2,7 @@ # SPDX-License-Identifier: MIT """Parse recipes from Bash files.""" +import copy import warnings from itertools import product from typing import Any, Dict, Generator, Iterable, Optional, Tuple @@ -62,8 +63,8 @@ def _instantiate_arch( assert archs is not None for arch in archs: - loc_vars: bash.Variables = variables.copy() - loc_funcs: bash.Functions = functions.copy() + loc_vars: bash.Variables = copy.deepcopy(variables) + loc_funcs: bash.Functions = copy.deepcopy(functions) loc_vars["arch"] = arch # Merge variables suffixed with the selected architecture @@ -88,28 +89,29 @@ def _instantiate_arch( if name not in loc_vars: loc_vars[name] = value - else: - normal_value = loc_vars[name] - - if isinstance(normal_value, str): - if not isinstance(value, str): - raise RecipeError( - path, - f"Field '{name}' was declared several times with \ + continue + + normal_value = loc_vars[name] + + if isinstance(normal_value, str): + if not isinstance(value, str): + raise RecipeError( + path, + f"Field '{name}' was declared several times with \ different types", - ) + ) - loc_vars[name] = value + loc_vars[name] = value - if isinstance(normal_value, list): - if not isinstance(value, list): - raise RecipeError( - path, - f"Field '{name}' was declared several times with \ + if isinstance(normal_value, list): + if not isinstance(value, list): + raise RecipeError( + path, + f"Field '{name}' was declared several times with \ different types", - ) + ) - normal_value.extend(value) + normal_value.extend(value) yield arch or "", loc_vars, loc_funcs @@ -219,8 +221,8 @@ def _parse_recipe( # pylint: disable=too-many-locals, disable=too-many-statemen variables["pkgname"] = pkg_name attrs["packages"][pkg_name] = _parse_package( result, - variables.copy(), - raw_vars.copy(), + copy.deepcopy(variables), + copy.deepcopy(raw_vars), functions, ) else: @@ -254,7 +256,7 @@ def _parse_recipe( # pylint: disable=too-many-locals, disable=too-many-statemen attrs["packages"][sub_pkg_name] = _parse_package( result, pkg_vars, - raw_vars.copy(), + copy.deepcopy(raw_vars), {**functions, **pkg_funcs}, )