overhaul warning and error handling
This commit is contained in:
parent
ffa0253193
commit
5d9ddf60b7
1 changed files with 58 additions and 18 deletions
76
recipes.py
76
recipes.py
|
@ -1,5 +1,6 @@
|
|||
from abc import abstractmethod
|
||||
from collections import defaultdict
|
||||
import collections
|
||||
import sys
|
||||
from typing import Dict, List, Any, Optional, Set
|
||||
import os
|
||||
|
@ -10,6 +11,38 @@ import jinja2
|
|||
import jsonschema
|
||||
import jsonschema.exceptions
|
||||
|
||||
ISSUE_UNKNOWN_UNIT = "unknown-unit"
|
||||
ISSUE_UNKNOWN_INGREDIENT = "unknown-ingredient"
|
||||
ISSUE_DUPLICATE_UNITS = "duplicate-units"
|
||||
ISSUE_KNOWN_PRICE_UNKNOWN_CONVERSION = "known-price-unknown-conversion"
|
||||
|
||||
class Issue:
|
||||
def __init__(self, id: str, msg: str) -> None:
|
||||
self.id = id
|
||||
self.msg = msg
|
||||
|
||||
class Issues:
|
||||
def __init__(self) -> None:
|
||||
self.errors: List[Issue] = []
|
||||
self.warnings: List[Issue] = []
|
||||
|
||||
def error(self, id: str, msg: str) -> None:
|
||||
self.errors.append(Issue(id, msg))
|
||||
|
||||
def warn(self, id: str, msg: str) -> None:
|
||||
self.warnings.append(Issue(id, msg))
|
||||
|
||||
def check(self) -> int:
|
||||
retcode = len(self.errors) != 0
|
||||
|
||||
for msg in self.errors:
|
||||
print(f"ERROR {msg.id}: {msg.msg}")
|
||||
for msg in self.warnings:
|
||||
print(f"WARNING {msg.id}: {msg.msg}")
|
||||
|
||||
self.errors.clear()
|
||||
self.warnings.clear()
|
||||
return retcode
|
||||
|
||||
class Context:
|
||||
def __init__(self) -> None:
|
||||
|
@ -17,7 +50,7 @@ class Context:
|
|||
self.default_unit = Unit(self, {"name": "piece"})
|
||||
self.units.units.append(self.default_unit)
|
||||
self.ingredients = Ingredients(self)
|
||||
self.issues: List[str] = []
|
||||
self.issues = Issues()
|
||||
|
||||
|
||||
class Element:
|
||||
|
@ -103,12 +136,20 @@ class Units:
|
|||
return unit
|
||||
return None
|
||||
|
||||
def validate(self) -> None:
|
||||
unitnames = []
|
||||
for unit in self.units:
|
||||
unitnames.append(unit["name"])
|
||||
for unitname, num in collections.Counter(unitnames).items():
|
||||
if num>1:
|
||||
self.ctx.issues.error(ISSUE_DUPLICATE_UNITS, f"units.yaml: {unitname} should only have one entry, found {num}")
|
||||
|
||||
|
||||
class Ingredient(Element):
|
||||
def load(self, dct: Dict[str, Any]) -> None:
|
||||
if "prices" in dct:
|
||||
pricedb = PriceDBs(self.ctx)
|
||||
self.ctx.issues += pricedb.load(dct["prices"])
|
||||
pricedb.load(dct["prices"])
|
||||
self["prices"] = pricedb
|
||||
|
||||
conversions = []
|
||||
|
@ -155,8 +196,8 @@ class Ingredient(Element):
|
|||
# find path between conversions
|
||||
path = self.dfs(conversions, unitfrom["name"], unitto["name"])
|
||||
if path is None:
|
||||
print(
|
||||
f'WARNING: {self["name"]} has a known price, but conversion {unitfrom["name"]} -> {unitto["name"]} not known'
|
||||
self.ctx.issues.warn(ISSUE_KNOWN_PRICE_UNKNOWN_CONVERSION,
|
||||
f'{self["name"]} has a known price, but conversion {unitfrom["name"]} -> {unitto["name"]} not known'
|
||||
)
|
||||
return None
|
||||
assert len(path) != 0
|
||||
|
@ -210,11 +251,10 @@ class PriceDBs:
|
|||
self.ctx = ctx
|
||||
self.pricedbs: List[PriceDB] = []
|
||||
|
||||
def load(self, lst: List[Any]) -> List[str]:
|
||||
def load(self, lst: List[Any]) -> None:
|
||||
for elem in lst:
|
||||
pricedb = PriceDB(self.ctx, elem)
|
||||
self.pricedbs.append(pricedb)
|
||||
return self.ctx.issues
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return self.pricedbs.__repr__()
|
||||
|
@ -229,7 +269,7 @@ class PriceDB(Element):
|
|||
unitstr = dct["unit"]
|
||||
self["unit"] = self.ctx.units.get(unitstr)
|
||||
if self["unit"] is None:
|
||||
self.ctx.issues.append(f"unknown unit {unitstr}")
|
||||
self.ctx.issues.error(ISSUE_UNKNOWN_UNIT, f"unknown unit {unitstr}")
|
||||
else:
|
||||
self["unit"] = self.ctx.default_unit
|
||||
|
||||
|
@ -238,7 +278,7 @@ class IngredientInstance(Element):
|
|||
def load(self, dct: Dict[str, Any]) -> None:
|
||||
ingredient = self.ctx.ingredients.get(dct["name"])
|
||||
if ingredient is None:
|
||||
self.ctx.issues.append(f"unknown ingredient {dct['name']}")
|
||||
self.ctx.issues.error(ISSUE_UNKNOWN_INGREDIENT, f"unknown ingredient {dct['name']}")
|
||||
self["ingredient"] = ingredient
|
||||
|
||||
if "amount" not in dct:
|
||||
|
@ -248,7 +288,7 @@ class IngredientInstance(Element):
|
|||
unitstr = dct["unit"]
|
||||
self["unit"] = self.ctx.units.get(unitstr)
|
||||
if self["unit"] is None:
|
||||
self.ctx.issues.append("unknown unit {unitstr}")
|
||||
self.ctx.issues.error(ISSUE_UNKNOWN_UNIT, "unknown unit {unitstr}")
|
||||
else:
|
||||
self["unit"] = self.ctx.default_unit
|
||||
|
||||
|
@ -356,18 +396,17 @@ class Builder:
|
|||
unitsschema = self.load_file("schemas/units.json")
|
||||
jsonschema.validate(instance=unitsdct, schema=unitsschema)
|
||||
self.ctx.units.load(unitsdct)
|
||||
if len(self.ctx.issues) != 0:
|
||||
for issue in self.ctx.issues:
|
||||
print("ERROR in units.yaml:", issue)
|
||||
retcode = self.ctx.issues.check()
|
||||
if retcode != 0:
|
||||
return 1
|
||||
self.ctx.units.validate()
|
||||
|
||||
ingredientsdct = self.load_file(dir + "/ingredients.yaml")
|
||||
ingredientsschema = self.load_file("schemas/ingredients.json")
|
||||
jsonschema.validate(instance=ingredientsdct, schema=ingredientsschema)
|
||||
self.ctx.ingredients.load(ingredientsdct)
|
||||
if len(self.ctx.issues) != 0:
|
||||
for issue in self.ctx.issues:
|
||||
print("ERROR in ingredients.yaml:", issue)
|
||||
retcode = self.ctx.issues.check()
|
||||
if retcode != 0:
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
@ -389,11 +428,12 @@ class Builder:
|
|||
recipe = Recipe(self.ctx, recipedct)
|
||||
recipe.srcpath = file
|
||||
recipe.outpath = file[:-5] + ".html"
|
||||
if self.ctx.issues.check() != 0:
|
||||
continue
|
||||
recipes.append(recipe)
|
||||
|
||||
if len(self.ctx.issues) != 0:
|
||||
for issue in self.ctx.issues:
|
||||
print("ERROR", issue)
|
||||
retcode = self.ctx.issues.check()
|
||||
if retcode != 0:
|
||||
return 1
|
||||
|
||||
self.rendertemplate(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue