Coverage for src/auto_intersphinx/check_packages.py: 100%

65 statements  

« prev     ^ index     » next       coverage.py v7.4.3, created at 2024-04-22 14:48 +0200

1# SPDX-FileCopyrightText: Copyright © 2022 Idiap Research Institute <contact@idiap.ch> 

2# 

3# SPDX-License-Identifier: BSD-3-Clause 

4 

5from __future__ import annotations # not required for Python >= 3.10 

6 

7import argparse 

8import importlib.resources 

9import json 

10import pathlib 

11import textwrap 

12 

13from . import oneliner 

14from .catalog import ( 

15 Catalog, 

16 docurls_from_environment, 

17 docurls_from_pypi, 

18 docurls_from_rtd, 

19) 

20from .update_catalog import setup_verbosity 

21 

22 

23def _main(args) -> None: 

24 """Main function, that actually executes the check-package command.""" 

25 setup_verbosity(args.verbose) 

26 

27 builtin_catalog = Catalog() 

28 if not args.no_builtin: 

29 catalog_file = importlib.resources.files(__name__.split(".", 1)[0]).joinpath( 

30 "catalog.json" 

31 ) 

32 builtin_catalog.loads(catalog_file.read_text()) 

33 

34 user_catalog = Catalog() 

35 if args.user: 

36 user_catalog.load(args.user) 

37 

38 for p in args.packages: 

39 if p in user_catalog: 

40 print(f"Found {p} in user catalog:") 

41 print( 

42 textwrap.indent( 

43 json.dumps(user_catalog[p]["versions"], indent=2), " | " 

44 ) 

45 ) 

46 if not args.keep_going: 

47 continue 

48 

49 if p in builtin_catalog: 

50 print(f"Found {p} in builtin catalog:") 

51 print( 

52 textwrap.indent( 

53 json.dumps(builtin_catalog[p]["versions"], indent=2), " | " 

54 ) 

55 ) 

56 if not args.keep_going: 

57 continue 

58 

59 if not args.no_environment: 

60 versions = docurls_from_environment(p) 

61 if versions: 

62 print(f"Found {p} documentation in installed Python environment:") 

63 print(textwrap.indent(json.dumps(versions, indent=2), " | ")) 

64 if not args.keep_going: 

65 continue 

66 

67 if not args.no_rtd: 

68 versions = docurls_from_rtd(p) 

69 if versions: 

70 print(f"Found {p} documentation in readthedocs.org:") 

71 print(textwrap.indent(json.dumps(versions, indent=2), " | ")) 

72 if not args.keep_going: 

73 continue 

74 

75 if not args.no_pypi: 

76 print(f"Looking up all PyPI versions of {p} - this may be long...") 

77 versions = docurls_from_pypi(p, args.pypi_max_entries) 

78 if versions: 

79 print(f"Found {p} documentation in PyPI:") 

80 print(textwrap.indent(json.dumps(versions, indent=2), " | ")) 

81 if not args.keep_going: 

82 continue 

83 

84 

85def add_parser(subparsers) -> argparse.ArgumentParser: 

86 """Just sets up the parser for this CLI.""" 

87 prog = "auto-intersphinx check-packages" 

88 

89 parser = subparsers.add_parser( 

90 prog.split()[1], 

91 help="Discover documentation cross-references for packages", 

92 description="Discover documentation cross-references for packages", 

93 formatter_class=argparse.RawDescriptionHelpFormatter, 

94 epilog=textwrap.dedent( 

95 f""" 

96 examples: 

97 

98 1. Checks internal catalog, Python environment, readthedocs.org and 

99 PyPI for package "requests": 

100 

101 .. code:: sh 

102 

103 {prog} requests 

104 

105 2. Checks internal and user catalog, Python environment, 

106 readthedocs.org and PyPI for package "requests": 

107 

108 .. code:: sh 

109 

110 {prog} --user=doc/catalog.json requests 

111 

112 3. Skip internal catalog checks when running for package "requests" 

113 (checks readthedocs.org and PyPI only): 

114 

115 .. code:: sh 

116 

117 {prog} --no-builtin requests 

118 

119 4. Keep looking for references in all available places (do not stop 

120 when first finds a documentation link, such as the extension does): 

121 

122 .. code:: sh 

123 

124 {prog} --keep-going requests 

125 """ 

126 ), 

127 ) 

128 

129 parser.add_argument( 

130 "-v", 

131 "--verbose", 

132 action="count", 

133 default=0, 

134 help="Can be set multiple times to increase console verbosity", 

135 ) 

136 

137 parser.add_argument( 

138 "packages", 

139 nargs="+", 

140 help="Names of packages to check - specify one or more", 

141 ) 

142 

143 parser.add_argument( 

144 "-S", 

145 "--no-builtin", 

146 action="store_true", 

147 default=False, 

148 help="If set, then do not check own catalog", 

149 ) 

150 

151 parser.add_argument( 

152 "-E", 

153 "--no-environment", 

154 action="store_true", 

155 default=False, 

156 help="If set, then do not check the current environment package documentation", 

157 ) 

158 

159 parser.add_argument( 

160 "-R", 

161 "--no-rtd", 

162 action="store_true", 

163 default=False, 

164 help="If set, then do not check readthedocs.org for package documentation", 

165 ) 

166 

167 parser.add_argument( 

168 "-P", 

169 "--no-pypi", 

170 action="store_true", 

171 default=False, 

172 help="If set, then do not check PyPI for package documentation", 

173 ) 

174 

175 parser.add_argument( 

176 "-M", 

177 "--pypi-max-entries", 

178 default=0, 

179 help=oneliner( 

180 """ 

181 The maximum number of entries to lookup in PyPI. A value of zero 

182 will download only the main package information and will hit PyPI 

183 only once. A value bigger than zero will download at most the 

184 information from the last ``max_entries`` releases. Finally, a 

185 negative value will imply the download of all available releases. 

186 """ 

187 ), 

188 ) 

189 

190 parser.add_argument( 

191 "-k", 

192 "--keep-going", 

193 action="store_true", 

194 default=False, 

195 help=oneliner( 

196 """ 

197 If set, then do not stop at first found reference (such as 

198 auto-intersphinx would do), but rather keep searching for all 

199 references. 

200 """ 

201 ), 

202 ) 

203 

204 parser.add_argument( 

205 "-u", 

206 "--user", 

207 type=pathlib.Path, 

208 help="If set, then also checks the local user-catalog at the specified path", 

209 ) 

210 

211 parser.set_defaults(func=_main) 

212 

213 return parser