22
22
from markdown_checker .utils .spinner import spinner
23
23
24
24
25
- def check_url (url : MarkdownURL , skip_domains : list [str ], skip_urls_containing : list [str ], timeout : int , retries : int ):
25
+ def check_url (
26
+ url : MarkdownURL , skip_domains : list [str ], skip_urls_containing : list [str ], timeout : int , retries : int
27
+ ) -> Union [None , MarkdownURL ]:
26
28
if any (url .host_name ().lower () in domain .lower () for domain in skip_domains ) or any (
27
29
url .link in substring for substring in skip_urls_containing
28
30
):
@@ -150,44 +152,83 @@ def detect_issues(
150
152
return detected_issues , links_count
151
153
152
154
155
+ class ListOfStrings (click .Option ):
156
+ """
157
+ Helper class to parse a list of strings from the command line.
158
+
159
+ Ref: https://stackoverflow.com/questions/47631914/how-to-pass-several-list-of-arguments-to-click-option
160
+ """
161
+
162
+ def type_cast_value (self , ctx , value ):
163
+ try :
164
+ if isinstance (value , str ):
165
+ # split the string by comma and remove empty strings
166
+ return list (filter (None , value .split ("," )))
167
+ elif isinstance (value , list ):
168
+ return value
169
+ else :
170
+ raise Exception
171
+ except Exception :
172
+ raise click .BadParameter (value )
173
+
174
+
153
175
@click .command ()
154
176
@click .option (
155
177
"-d" ,
156
178
"--dir" ,
157
- type = click .Path (exists = True , file_okay = False , dir_okay = True , readable = True ),
179
+ type = click .Path (path_type = Path , exists = True , file_okay = False , dir_okay = True , readable = True ),
158
180
help = "Path to the root directory to check." ,
159
181
required = True ,
160
182
)
183
+ @click .option (
184
+ "-f" ,
185
+ "--func" ,
186
+ type = click .Choice (
187
+ [
188
+ "check_broken_paths" ,
189
+ "check_broken_urls" ,
190
+ "check_paths_tracking" ,
191
+ "check_urls_tracking" ,
192
+ "check_urls_locale" ,
193
+ ]
194
+ ),
195
+ help = "Function to be executed." ,
196
+ required = True ,
197
+ )
161
198
@click .option (
162
199
"-ext" ,
163
200
"--extensions" ,
201
+ cls = ListOfStrings ,
164
202
type = list [str ],
165
203
default = [".md" , ".ipynb" ],
166
204
help = "File extensions to filter the files." ,
167
- required = True ,
205
+ required = False ,
168
206
)
169
207
@click .option (
170
208
"-td" ,
171
209
"--tracking-domains" ,
210
+ cls = ListOfStrings ,
172
211
type = list [str ],
173
212
default = ["github.com" , "microsoft.com" , "visualstudio.com" , "aka.ms" , "azure.com" ],
174
213
help = "List of tracking domains to check." ,
175
- required = True ,
214
+ required = False ,
176
215
)
177
216
@click .option (
178
217
"-sf" ,
179
218
"--skip-files" ,
219
+ cls = ListOfStrings ,
180
220
type = list [str ],
181
221
default = [
182
222
"CODE_OF_CONDUCT.md" ,
183
223
"SECURITY.md" ,
184
224
],
185
225
help = "List of file names to skip check." ,
186
- required = True ,
226
+ required = False ,
187
227
)
188
228
@click .option (
189
229
"-sd" ,
190
230
"--skip-domains" ,
231
+ cls = ListOfStrings ,
191
232
type = list [str ],
192
233
default = [],
193
234
help = "List of domains to skip check." ,
@@ -196,45 +237,31 @@ def detect_issues(
196
237
@click .option (
197
238
"-suc" ,
198
239
"--skip-urls-containing" ,
240
+ cls = ListOfStrings ,
199
241
type = list [str ],
200
242
default = ["https://www.microsoft.com/en-us/security/blog" , "video-embed.html" ],
201
243
help = "List of urls to skip check." ,
202
244
required = False ,
203
245
)
204
- @click .option (
205
- "-f" ,
206
- "--func" ,
207
- type = click .Choice (
208
- [
209
- "check_broken_paths" ,
210
- "check_broken_urls" ,
211
- "check_paths_tracking" ,
212
- "check_urls_tracking" ,
213
- "check_urls_locale" ,
214
- ]
215
- ),
216
- help = "Function to be executed." ,
217
- required = True ,
218
- )
219
246
@click .option (
220
247
"-gu" ,
221
248
"--guide-url" ,
222
249
type = str ,
223
250
help = "Full url of your contributing guide." ,
224
- required = True ,
251
+ required = False ,
225
252
)
226
253
@click .option (
227
254
"-to" ,
228
255
"--timeout" ,
229
- type = int ,
256
+ type = click . IntRange ( 0 , 50 ) ,
230
257
default = 10 ,
231
258
help = "Timeout in seconds for the requests." ,
232
259
required = False ,
233
260
)
234
261
@click .option (
235
262
"-rt" ,
236
263
"--retries" ,
237
- type = int ,
264
+ type = click . IntRange ( 0 , 10 ) ,
238
265
default = 3 ,
239
266
help = "Number of retries for the requests." ,
240
267
required = False ,
@@ -245,12 +272,12 @@ def detect_issues(
245
272
type = str ,
246
273
default = "comment" ,
247
274
help = "Name of the output file." ,
248
- required = True ,
275
+ required = False ,
249
276
)
250
277
@click .argument (
251
278
"src" ,
252
279
nargs = - 1 ,
253
- type = click .Path (exists = True , file_okay = True , dir_okay = True , readable = True ),
280
+ type = click .Path (path_type = Path , exists = True , file_okay = True , dir_okay = True , readable = True ),
254
281
is_eager = True ,
255
282
metavar = "SRC ..." ,
256
283
required = False ,
@@ -259,23 +286,22 @@ def detect_issues(
259
286
message = (f"%(prog)s, %(version)s\n " f"Python ({ platform .python_implementation ()} ) { platform .python_version ()} " ),
260
287
)
261
288
def main (
262
- src : tuple [str , ...],
263
- dir : str ,
289
+ src : tuple [Path , ...],
290
+ dir : Path ,
264
291
func : str ,
265
- guide_url : str ,
292
+ guide_url : Union [ str , None ] ,
266
293
extensions : list [str ],
267
294
skip_files : list [str ],
268
295
skip_domains : list [str ],
269
296
skip_urls_containing : list [str ],
297
+ tracking_domains : list [str ],
270
298
timeout : int ,
271
299
retries : int ,
272
- tracking_domains : list [str ],
273
300
output_file_name : str ,
274
301
) -> None :
275
302
"""A markdown link validation reporting tool."""
276
- _ = tuple (Path (item ) for item in src ) or (Path ("./" ),) # default to current directory
277
-
278
- _ , files_paths = get_files_paths_list (Path (dir ), extensions )
303
+ _ = src or (Path ("./" ),) # default to current directory
304
+ _ , files_paths = get_files_paths_list (dir , extensions )
279
305
280
306
# remove files from skip_files list
281
307
files_paths = [file_path for file_path in files_paths if file_path .name not in skip_files ]
0 commit comments