Coverage for src/somesy/cli/sync.py: 32%

40 statements  

« prev     ^ index     » next       coverage.py v7.6.0, created at 2025-03-10 14:56 +0000

1"""Sync command for somesy.""" 

2 

3import logging 

4from pathlib import Path 

5from typing import List, Optional 

6 

7import typer 

8 

9from somesy.commands import sync as sync_command 

10from somesy.core.models import SomesyInput 

11 

12from .util import ( 

13 existing_file_arg_config, 

14 file_arg_config, 

15 resolved_somesy_input, 

16 wrap_exceptions, 

17) 

18 

19logger = logging.getLogger("somesy") 

20 

21app = typer.Typer() 

22 

23 

24@app.callback(invoke_without_command=True) 

25@wrap_exceptions 

26def sync( 

27 input_file: Optional[Path] = typer.Option( 

28 None, 

29 "--input-file", 

30 "-i", 

31 help="Somesy input file path (default: .somesy.toml)", 

32 **file_arg_config, 

33 ), 

34 no_sync_pyproject: Optional[bool] = typer.Option( 

35 None, 

36 "--no-sync-pyproject", 

37 "-P", 

38 help="Do not sync pyproject.toml file (default: False)", 

39 ), 

40 pyproject_file: Optional[List[Path]] = typer.Option( 

41 None, 

42 "--pyproject-file", 

43 "-p", 

44 help="Existing pyproject.toml file path(s) (default: pyproject.toml)", 

45 **existing_file_arg_config, 

46 ), 

47 no_sync_package_json: Optional[bool] = typer.Option( 

48 None, 

49 "--no-sync-package-json", 

50 "-J", 

51 help="Do not sync package.json file (default: False)", 

52 ), 

53 package_json_file: Optional[List[Path]] = typer.Option( 

54 None, 

55 "--package-json-file", 

56 "-j", 

57 help="Existing package.json file path(s) (default: package.json)", 

58 **existing_file_arg_config, 

59 ), 

60 no_sync_julia: Optional[bool] = typer.Option( 

61 None, 

62 "--no-sync-julia", 

63 "-L", 

64 help="Do not sync Project.toml (Julia) file (default: False)", 

65 ), 

66 julia_file: Optional[List[Path]] = typer.Option( 

67 None, 

68 "--julia-file", 

69 "-l", 

70 help="Custom Project.toml (Julia) file path(s) (default: Project.toml)", 

71 **existing_file_arg_config, 

72 ), 

73 no_sync_fortran: Optional[bool] = typer.Option( 

74 None, 

75 "--no-sync-fortran", 

76 "-F", 

77 help="Do not sync fpm.toml (Fortran) file (default: False)", 

78 ), 

79 fortran_file: Optional[List[Path]] = typer.Option( 

80 None, 

81 "--fortran-file", 

82 "-f", 

83 help="Custom fpm.toml (Fortran) file path(s) (default: fpm.toml)", 

84 **existing_file_arg_config, 

85 ), 

86 no_sync_pom_xml: Optional[bool] = typer.Option( 

87 None, 

88 "--no-sync-pomxml", 

89 "-X", 

90 help="Do not sync pom.xml (Java Maven) file (default: False)", 

91 ), 

92 pom_xml_file: Optional[List[Path]] = typer.Option( 

93 None, 

94 "--pomxml-file", 

95 "-x", 

96 help="Custom pom.xml (Java Maven) file path(s) (default: pom.xml)", 

97 **existing_file_arg_config, 

98 ), 

99 no_sync_mkdocs: Optional[bool] = typer.Option( 

100 None, 

101 "--no-sync-mkdocs", 

102 "-D", 

103 help="Do not sync mkdocs.yml file (default: False)", 

104 ), 

105 mkdocs_file: Optional[List[Path]] = typer.Option( 

106 None, 

107 "--mkdocs-file", 

108 "-d", 

109 help="Custom mkdocs.yml file path(s) (default: mkdocs.yml)", 

110 **existing_file_arg_config, 

111 ), 

112 no_sync_rust: Optional[bool] = typer.Option( 

113 None, 

114 "--no-sync-rust", 

115 "-R", 

116 help="Do not sync Cargo.toml file (default: False)", 

117 ), 

118 rust_file: Optional[List[Path]] = typer.Option( 

119 None, 

120 "--rust-file", 

121 "-r", 

122 help="Custom Cargo.toml file path(s) (default: Cargo.toml)", 

123 **existing_file_arg_config, 

124 ), 

125 no_sync_cff: Optional[bool] = typer.Option( 

126 None, 

127 "--no-sync-cff", 

128 "-C", 

129 help="Do not sync CITATION.cff file (default: False)", 

130 ), 

131 cff_file: Optional[List[Path]] = typer.Option( 

132 None, 

133 "--cff-file", 

134 "-c", 

135 help="CITATION.cff file path(s) (default: CITATION.cff)", 

136 **file_arg_config, 

137 ), 

138 no_sync_codemeta: Optional[bool] = typer.Option( 

139 None, 

140 "--no-sync-codemeta", 

141 "-M", 

142 help="Do not sync codemeta.json file (default: False)", 

143 ), 

144 codemeta_file: Optional[List[Path]] = typer.Option( 

145 None, 

146 "--codemeta-file", 

147 "-m", 

148 help="Custom codemeta.json file path(s) (default: codemeta.json)", 

149 **file_arg_config, 

150 ), 

151 merge_codemeta: Optional[bool] = typer.Option( 

152 False, 

153 "--merge/--overwrite", 

154 help="Merge codemeta.json with with an existing codemeta.json file (default: False)", 

155 ), 

156 pass_validation: Optional[bool] = typer.Option( 

157 False, 

158 "--pass-validation", 

159 "-P", 

160 help="Pass validation of metadata files (default: False)", 

161 ), 

162 packages: Optional[List[Path]] = typer.Option( 

163 None, 

164 "--packages", 

165 "-k", 

166 help="Packages (subfolders) for monorepos with their own somesy config.", 

167 **existing_file_arg_config, 

168 ), 

169): 

170 """Sync project metadata input with metadata files.""" 

171 somesy_input = resolved_somesy_input( 

172 input_file=input_file, 

173 no_sync_cff=no_sync_cff, 

174 cff_file=cff_file, 

175 no_sync_pyproject=no_sync_pyproject, 

176 pyproject_file=pyproject_file, 

177 no_sync_package_json=no_sync_package_json, 

178 package_json_file=package_json_file, 

179 no_sync_codemeta=no_sync_codemeta, 

180 codemeta_file=codemeta_file, 

181 no_sync_julia=no_sync_julia, 

182 julia_file=julia_file, 

183 no_sync_fortran=no_sync_fortran, 

184 fortran_file=fortran_file, 

185 no_sync_pom_xml=no_sync_pom_xml, 

186 pom_xml_file=pom_xml_file, 

187 no_sync_mkdocs=no_sync_mkdocs, 

188 mkdocs_file=mkdocs_file, 

189 no_sync_rust=no_sync_rust, 

190 rust_file=rust_file, 

191 merge_codemeta=merge_codemeta, 

192 pass_validation=pass_validation, 

193 packages=packages, 

194 ) 

195 

196 run_sync(somesy_input) 

197 

198 

199def run_sync(somesy_input: SomesyInput): 

200 """Write log messages and run synchronization based on passed config.""" 

201 conf = somesy_input.config 

202 logger.info("[bold green]Synchronizing project metadata...[/bold green]") 

203 logger.info("Files to sync:") 

204 if not conf.no_sync_pyproject: 

205 logger.info( 

206 f" - [italic]pyproject.toml[/italic]:\t[grey]{conf.pyproject_file}[/grey]" 

207 ) 

208 if not conf.no_sync_package_json: 

209 logger.info( 

210 f" - [italic]package.json[/italic]:\t[grey]{conf.package_json_file}[/grey]" 

211 ) 

212 if not conf.no_sync_julia: 

213 logger.info( 

214 f" - [italic]Project.toml[/italic]:\t[grey]{conf.julia_file}[/grey]\n" 

215 ) 

216 if not conf.no_sync_fortran: 

217 logger.info( 

218 f" - [italic]fpm.toml(fortran)[/italic]:\t[grey]{conf.fortran_file}[/grey]" 

219 ) 

220 if not conf.no_sync_pom_xml: 

221 logger.info( 

222 f" - [italic]pom.xml[/italic]:\t[grey]{conf.pom_xml_file}[/grey]\n" 

223 ) 

224 if not conf.no_sync_mkdocs: 

225 logger.info( 

226 f" - [italic]mkdocs.yml[/italic]:\t[grey]{conf.mkdocs_file}[/grey]" 

227 ) 

228 if not conf.no_sync_rust: 

229 logger.info(f" - [italic]Cargo.toml[/italic]:\t[grey]{conf.rust_file}[/grey]") 

230 

231 if not conf.no_sync_cff: 

232 logger.info(f" - [italic]CITATION.cff[/italic]:\t[grey]{conf.cff_file}[/grey]") 

233 if not conf.no_sync_codemeta: 

234 logger.info( 

235 f" - [italic]codemeta.json[/italic]:\t[grey]{conf.codemeta_file}[/grey]\n" 

236 ) 

237 # ---- 

238 if conf.pass_validation: 

239 logger.info("[bold yellow]Passing validation of metadata files.[/bold yellow]") 

240 sync_command(somesy_input) 

241 # ---- 

242 logger.info("[bold green]Metadata synchronization completed.[/bold green]")