Coverage for src/somesy/core/core.py: 71%
52 statements
« prev ^ index » next coverage.py v7.16.0, created at 2026-09-04 11:35 +0000
« prev ^ index » next coverage.py v7.16.0, created at 2026-09-04 11:35 +0000
1"""Core somesy functions."""
3import json
4import logging
5from pathlib import Path
6from typing import Any
8import tomlkit
10from .log import VERBOSE
12logger = logging.getLogger("somesy")
14INPUT_FILES_ORDERED = [
15 ".somesy.toml",
16 "somesy.toml",
17 "pyproject.toml",
18 "package.json",
19 "Project.toml",
20 "fpm.toml",
21 "Cargo.toml",
22]
23"""Input files ordered by priority for discovery."""
26def discover_input(input_file: Path | None = None) -> Path:
27 """Check given input file path. If not given, find somesy configuration file path from default list.
29 Args:
30 input_file: somesy configuration file path. Defaults to None.
32 Raises:
33 FileNotFoundError: Raised if no somesy input file found from cli input or the defaults.
35 Returns:
36 somesy configuration file path.
38 """
39 if input_file:
40 if input_file.is_file():
41 logger.info(f"Using provided file '{input_file}' as somesy input file.")
42 return input_file
43 else:
44 msg = f"Passed file '{input_file}' does not exist. Searching for usable somesy input file..."
45 logger.log(VERBOSE, msg)
47 for filename in INPUT_FILES_ORDERED:
48 input_file = Path(filename)
49 if input_file.is_file():
50 try:
51 get_input_content(input_file)
52 except RuntimeError:
53 continue
55 msg = f"Using '{input_file}' as somesy input file."
56 logger.log(VERBOSE, msg)
57 return input_file
59 raise FileNotFoundError("No somesy input file found.")
62def get_input_content(path: Path, *, no_unwrap: bool = False) -> dict[str, Any]:
63 """Read contents of a supported somesy input file.
65 Given a path to a TOML file, this function reads the file and returns its content as a TOMLDocument object.
66 The function checks if the file is a valid somesy input file by checking its name and content.
68 Args:
69 path (Path): path to the input file
70 no_unwrap (bool): if True, the function returns the TOMLDocument object instead of unwrapping it
72 Returns:
73 the content of the input file as a TOMLDocument object
75 Raises:
76 ValueError: if the input file is not a valid somesy input file or if the file is not a TOML file.
77 RuntimeError: if the input file does not contain a somesy input section at expected key
79 """
80 logger.debug(f"Path {path}")
81 # somesy.toml / .somesy.toml
82 if path.suffix == ".toml" and "somesy" in path.name:
83 with open(path, "r") as f:
84 ret = tomlkit.load(f)
85 return ret if no_unwrap else ret.unwrap()
87 # pyproject.toml or fpm.toml
88 if (path.suffix == ".toml" and "pyproject" in path.name) or path.name in [
89 "Project.toml",
90 "fpm.toml",
91 ]:
92 with open(path, "r") as f:
93 input_content = tomlkit.load(f)
94 if "tool" in input_content and "somesy" in input_content["tool"]:
95 return input_content["tool"]["somesy"].unwrap()
96 else:
97 raise RuntimeError(
98 "No tool.somesy section found in pyproject.toml file!"
99 )
101 # Cargo.toml
102 if path.name == "Cargo.toml":
103 with open(path, "r") as f:
104 input_content = tomlkit.load(f)
105 if (
106 "package" in input_content
107 and "metadata" in input_content["package"]
108 and "somesy" in input_content["package"]["metadata"]
109 ):
110 return input_content["package"]["metadata"]["somesy"].unwrap()
111 else:
112 raise RuntimeError(
113 "No package.somesy section found in Cargo.toml file!"
114 )
116 # package.json
117 if path.suffix == ".json" and "package" in path.name:
118 with open(path, "r") as f:
119 input_content = json.load(f)
120 if "somesy" in input_content:
121 return input_content["somesy"]
122 else:
123 raise RuntimeError("No somesy section found in package.json file!")
125 # no match:
126 raise ValueError("Unsupported input file.")