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

1"""Core somesy functions.""" 

2 

3import json 

4import logging 

5from pathlib import Path 

6from typing import Any 

7 

8import tomlkit 

9 

10from .log import VERBOSE 

11 

12logger = logging.getLogger("somesy") 

13 

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.""" 

24 

25 

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. 

28 

29 Args: 

30 input_file: somesy configuration file path. Defaults to None. 

31 

32 Raises: 

33 FileNotFoundError: Raised if no somesy input file found from cli input or the defaults. 

34 

35 Returns: 

36 somesy configuration file path. 

37 

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) 

46 

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 

54 

55 msg = f"Using '{input_file}' as somesy input file." 

56 logger.log(VERBOSE, msg) 

57 return input_file 

58 

59 raise FileNotFoundError("No somesy input file found.") 

60 

61 

62def get_input_content(path: Path, *, no_unwrap: bool = False) -> dict[str, Any]: 

63 """Read contents of a supported somesy input file. 

64 

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. 

67 

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 

71 

72 Returns: 

73 the content of the input file as a TOMLDocument object 

74 

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 

78 

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() 

86 

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 ) 

100 

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 ) 

115 

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!") 

124 

125 # no match: 

126 raise ValueError("Unsupported input file.")