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

51 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2024-04-30 09:42 +0000

1"""Core somesy functions.""" 

2import json 

3import logging 

4from pathlib import Path 

5from typing import Any, Dict, Optional 

6 

7import tomlkit 

8 

9logger = logging.getLogger("somesy") 

10 

11INPUT_FILES_ORDERED = [ 

12 ".somesy.toml", 

13 "somesy.toml", 

14 "pyproject.toml", 

15 "package.json", 

16 "Project.toml", 

17 "fpm.toml", 

18 "Cargo.toml", 

19] 

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

21 

22 

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

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

25 

26 Args: 

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

28 

29 Raises: 

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

31 

32 Returns: 

33 somesy configuration file path. 

34 """ 

35 if input_file: 

36 if input_file.is_file(): 

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

38 return input_file 

39 else: 

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

41 logger.verbose(msg) 

42 

43 for filename in INPUT_FILES_ORDERED: 

44 input_file = Path(filename) 

45 if input_file.is_file(): 

46 try: 

47 get_input_content(input_file) 

48 except RuntimeError: 

49 continue 

50 

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

52 logger.verbose(msg) 

53 return input_file 

54 

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

56 

57 

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

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

60 

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

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

63 

64 Args: 

65 path (Path): path to the input file 

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

67 

68 Returns: 

69 the content of the input file as a TOMLDocument object 

70 

71 Raises: 

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

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

74 """ 

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

76 # somesy.toml / .somesy.toml 

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

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

79 ret = tomlkit.load(f) 

80 return ret if no_unwrap else ret.unwrap() 

81 

82 # pyproject.toml or fpm.toml 

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

84 "Project.toml", 

85 "fpm.toml", 

86 ]: 

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

88 input_content = tomlkit.load(f) 

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

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

91 else: 

92 raise RuntimeError( 

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

94 ) 

95 

96 # Cargo.toml 

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

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

99 input_content = tomlkit.load(f) 

100 if ( 

101 "package" in input_content 

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

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

104 ): 

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

106 else: 

107 raise RuntimeError( 

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

109 ) 

110 

111 # package.json 

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

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

114 input_content = json.load(f) 

115 if "somesy" in input_content: 

116 return input_content["somesy"] 

117 else: 

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

119 

120 # no match: 

121 raise ValueError("Unsupported input file.")