Coverage for src/somesy/core/core.py: 59%

51 statements  

« prev     ^ index     » next       coverage.py v7.6.0, created at 2024-07-29 07:50 +0000

1"""Core somesy functions.""" 

2 

3import json 

4import logging 

5from pathlib import Path 

6from typing import Any, Dict, Optional 

7 

8import tomlkit 

9 

10logger = logging.getLogger("somesy") 

11 

12INPUT_FILES_ORDERED = [ 

13 ".somesy.toml", 

14 "somesy.toml", 

15 "pyproject.toml", 

16 "package.json", 

17 "Project.toml", 

18 "fpm.toml", 

19 "Cargo.toml", 

20] 

21"""Input files ordered by priority for discovery.""" 

22 

23 

24def discover_input(input_file: Optional[Path] = None) -> Path: 

25 """Check given input file path. If not given, find somesy configuration file path from default list. 

26 

27 Args: 

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

29 

30 Raises: 

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

32 

33 Returns: 

34 somesy configuration file path. 

35 

36 """ 

37 if input_file: 

38 if input_file.is_file(): 

39 logger.info(f"Using provided file '{input_file}' as somesy input file.") 

40 return input_file 

41 else: 

42 msg = f"Passed file '{input_file}' does not exist. Searching for usable somesy input file..." 

43 logger.verbose(msg) 

44 

45 for filename in INPUT_FILES_ORDERED: 

46 input_file = Path(filename) 

47 if input_file.is_file(): 

48 try: 

49 get_input_content(input_file) 

50 except RuntimeError: 

51 continue 

52 

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

54 logger.verbose(msg) 

55 return input_file 

56 

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

58 

59 

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

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

62 

63 Given a path to a TOML file, this function reads the file and returns its content as a TOMLDocument object. 

64 The function checks if the file is a valid somesy input file by checking its name and content. 

65 

66 Args: 

67 path (Path): path to the input file 

68 no_unwrap (bool): if True, the function returns the TOMLDocument object instead of unwrapping it 

69 

70 Returns: 

71 the content of the input file as a TOMLDocument object 

72 

73 Raises: 

74 ValueError: if the input file is not a valid somesy input file or if the file is not a TOML file. 

75 RuntimeError: if the input file does not contain a somesy input section at expected key 

76 

77 """ 

78 logger.debug(f"Path {path}") 

79 # somesy.toml / .somesy.toml 

80 if path.suffix == ".toml" and "somesy" in path.name: 

81 with open(path, "r") as f: 

82 ret = tomlkit.load(f) 

83 return ret if no_unwrap else ret.unwrap() 

84 

85 # pyproject.toml or fpm.toml 

86 if (path.suffix == ".toml" and "pyproject" in path.name) or path.name in [ 

87 "Project.toml", 

88 "fpm.toml", 

89 ]: 

90 with open(path, "r") as f: 

91 input_content = tomlkit.load(f) 

92 if "tool" in input_content and "somesy" in input_content["tool"]: 

93 return input_content["tool"]["somesy"].unwrap() 

94 else: 

95 raise RuntimeError( 

96 "No tool.somesy section found in pyproject.toml file!" 

97 ) 

98 

99 # Cargo.toml 

100 if path.name == "Cargo.toml": 

101 with open(path, "r") as f: 

102 input_content = tomlkit.load(f) 

103 if ( 

104 "package" in input_content 

105 and "metadata" in input_content["package"] 

106 and "somesy" in input_content["package"]["metadata"] 

107 ): 

108 return input_content["package"]["metadata"]["somesy"].unwrap() 

109 else: 

110 raise RuntimeError( 

111 "No package.somesy section found in Cargo.toml file!" 

112 ) 

113 

114 # package.json 

115 if path.suffix == ".json" and "package" in path.name: 

116 with open(path, "r") as f: 

117 input_content = json.load(f) 

118 if "somesy" in input_content: 

119 return input_content["somesy"] 

120 else: 

121 raise RuntimeError("No somesy section found in package.json file!") 

122 

123 # no match: 

124 raise ValueError("Unsupported input file.")