Markdown-Checker 0.2.0__tar.gz → 0.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {markdown_checker-0.2.0/src/markdown_checker.egg-info → markdown_checker-0.2.2}/PKG-INFO +1 -1
- {markdown_checker-0.2.0 → markdown_checker-0.2.2}/pyproject.toml +1 -1
- {markdown_checker-0.2.0 → markdown_checker-0.2.2}/src/markdown_checker/__init__.py +63 -32
- {markdown_checker-0.2.0 → markdown_checker-0.2.2}/src/markdown_checker/reports/md_reports/generator.py +12 -19
- {markdown_checker-0.2.0 → markdown_checker-0.2.2}/src/markdown_checker/urls.py +3 -2
- {markdown_checker-0.2.0 → markdown_checker-0.2.2/src/markdown_checker.egg-info}/PKG-INFO +1 -1
- {markdown_checker-0.2.0 → markdown_checker-0.2.2}/LICENSE +0 -0
- {markdown_checker-0.2.0 → markdown_checker-0.2.2}/README.md +0 -0
- {markdown_checker-0.2.0 → markdown_checker-0.2.2}/setup.cfg +0 -0
- {markdown_checker-0.2.0 → markdown_checker-0.2.2}/src/markdown_checker/markdown_link_base.py +0 -0
- {markdown_checker-0.2.0 → markdown_checker-0.2.2}/src/markdown_checker/paths.py +0 -0
- {markdown_checker-0.2.0 → markdown_checker-0.2.2}/src/markdown_checker/py.typed +0 -0
- {markdown_checker-0.2.0 → markdown_checker-0.2.2}/src/markdown_checker/reports/__init__.py +0 -0
- {markdown_checker-0.2.0 → markdown_checker-0.2.2}/src/markdown_checker/reports/generator_base.py +0 -0
- {markdown_checker-0.2.0 → markdown_checker-0.2.2}/src/markdown_checker/reports/md_reports/__init__.py +0 -0
- {markdown_checker-0.2.0 → markdown_checker-0.2.2}/src/markdown_checker/reports/md_reports/templates/paths/broken.md +0 -0
- {markdown_checker-0.2.0 → markdown_checker-0.2.2}/src/markdown_checker/reports/md_reports/templates/paths/tracking.md +0 -0
- {markdown_checker-0.2.0 → markdown_checker-0.2.2}/src/markdown_checker/reports/md_reports/templates/urls/broken.md +0 -0
- {markdown_checker-0.2.0 → markdown_checker-0.2.2}/src/markdown_checker/reports/md_reports/templates/urls/locale.md +0 -0
- {markdown_checker-0.2.0 → markdown_checker-0.2.2}/src/markdown_checker/reports/md_reports/templates/urls/tracking.md +0 -0
- {markdown_checker-0.2.0 → markdown_checker-0.2.2}/src/markdown_checker/utils/__init__.py +0 -0
- {markdown_checker-0.2.0 → markdown_checker-0.2.2}/src/markdown_checker/utils/extract_links.py +0 -0
- {markdown_checker-0.2.0 → markdown_checker-0.2.2}/src/markdown_checker/utils/format_output.py +0 -0
- {markdown_checker-0.2.0 → markdown_checker-0.2.2}/src/markdown_checker/utils/list_files.py +0 -0
- {markdown_checker-0.2.0 → markdown_checker-0.2.2}/src/markdown_checker/utils/spinner.py +0 -0
- {markdown_checker-0.2.0 → markdown_checker-0.2.2}/src/markdown_checker.egg-info/SOURCES.txt +0 -0
- {markdown_checker-0.2.0 → markdown_checker-0.2.2}/src/markdown_checker.egg-info/dependency_links.txt +0 -0
- {markdown_checker-0.2.0 → markdown_checker-0.2.2}/src/markdown_checker.egg-info/entry_points.txt +0 -0
- {markdown_checker-0.2.0 → markdown_checker-0.2.2}/src/markdown_checker.egg-info/requires.txt +0 -0
- {markdown_checker-0.2.0 → markdown_checker-0.2.2}/src/markdown_checker.egg-info/top_level.txt +0 -0
- {markdown_checker-0.2.0 → markdown_checker-0.2.2}/tests/test_markdown_checker.py +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "markdown-checker"
|
|
3
3
|
description= "A markdown link validation reporting tool."
|
|
4
|
-
version = "0.2.
|
|
4
|
+
version = "0.2.2"
|
|
5
5
|
authors = [{ name = "John Aziz", email = "johnaziz269@gmail.com" }]
|
|
6
6
|
maintainers = [{ name = "John Aziz", email = "johnaziz269@gmail.com" }]
|
|
7
7
|
license = {file = "LICENSE"}
|
|
@@ -22,7 +22,9 @@ from markdown_checker.utils.list_files import get_files_paths_list
|
|
|
22
22
|
from markdown_checker.utils.spinner import spinner
|
|
23
23
|
|
|
24
24
|
|
|
25
|
-
def check_url(
|
|
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
|
):
|
|
@@ -94,6 +96,11 @@ def detect_issues(
|
|
|
94
96
|
"dotnet.microsoft.com",
|
|
95
97
|
"www.gemini.com",
|
|
96
98
|
"upload.wikimedia.org",
|
|
99
|
+
"medium.com",
|
|
100
|
+
"blogs.nvidia.com",
|
|
101
|
+
"blog.gopenai.com",
|
|
102
|
+
"towardsdatascience.com",
|
|
103
|
+
"code.visualstudio.com",
|
|
97
104
|
]
|
|
98
105
|
)
|
|
99
106
|
with concurrent.futures.ProcessPoolExecutor() as executor:
|
|
@@ -150,44 +157,83 @@ def detect_issues(
|
|
|
150
157
|
return detected_issues, links_count
|
|
151
158
|
|
|
152
159
|
|
|
160
|
+
class ListOfStrings(click.Option):
|
|
161
|
+
"""
|
|
162
|
+
Helper class to parse a list of strings from the command line.
|
|
163
|
+
|
|
164
|
+
Ref: https://stackoverflow.com/questions/47631914/how-to-pass-several-list-of-arguments-to-click-option
|
|
165
|
+
"""
|
|
166
|
+
|
|
167
|
+
def type_cast_value(self, ctx, value):
|
|
168
|
+
try:
|
|
169
|
+
if isinstance(value, str):
|
|
170
|
+
# split the string by comma and remove empty strings
|
|
171
|
+
return list(filter(None, value.split(",")))
|
|
172
|
+
elif isinstance(value, list):
|
|
173
|
+
return value
|
|
174
|
+
else:
|
|
175
|
+
raise Exception
|
|
176
|
+
except Exception:
|
|
177
|
+
raise click.BadParameter(value)
|
|
178
|
+
|
|
179
|
+
|
|
153
180
|
@click.command()
|
|
154
181
|
@click.option(
|
|
155
182
|
"-d",
|
|
156
183
|
"--dir",
|
|
157
|
-
type=click.Path(exists=True, file_okay=False, dir_okay=True, readable=True),
|
|
184
|
+
type=click.Path(path_type=Path, exists=True, file_okay=False, dir_okay=True, readable=True),
|
|
158
185
|
help="Path to the root directory to check.",
|
|
159
186
|
required=True,
|
|
160
187
|
)
|
|
188
|
+
@click.option(
|
|
189
|
+
"-f",
|
|
190
|
+
"--func",
|
|
191
|
+
type=click.Choice(
|
|
192
|
+
[
|
|
193
|
+
"check_broken_paths",
|
|
194
|
+
"check_broken_urls",
|
|
195
|
+
"check_paths_tracking",
|
|
196
|
+
"check_urls_tracking",
|
|
197
|
+
"check_urls_locale",
|
|
198
|
+
]
|
|
199
|
+
),
|
|
200
|
+
help="Function to be executed.",
|
|
201
|
+
required=True,
|
|
202
|
+
)
|
|
161
203
|
@click.option(
|
|
162
204
|
"-ext",
|
|
163
205
|
"--extensions",
|
|
206
|
+
cls=ListOfStrings,
|
|
164
207
|
type=list[str],
|
|
165
208
|
default=[".md", ".ipynb"],
|
|
166
209
|
help="File extensions to filter the files.",
|
|
167
|
-
required=
|
|
210
|
+
required=False,
|
|
168
211
|
)
|
|
169
212
|
@click.option(
|
|
170
213
|
"-td",
|
|
171
214
|
"--tracking-domains",
|
|
215
|
+
cls=ListOfStrings,
|
|
172
216
|
type=list[str],
|
|
173
217
|
default=["github.com", "microsoft.com", "visualstudio.com", "aka.ms", "azure.com"],
|
|
174
218
|
help="List of tracking domains to check.",
|
|
175
|
-
required=
|
|
219
|
+
required=False,
|
|
176
220
|
)
|
|
177
221
|
@click.option(
|
|
178
222
|
"-sf",
|
|
179
223
|
"--skip-files",
|
|
224
|
+
cls=ListOfStrings,
|
|
180
225
|
type=list[str],
|
|
181
226
|
default=[
|
|
182
227
|
"CODE_OF_CONDUCT.md",
|
|
183
228
|
"SECURITY.md",
|
|
184
229
|
],
|
|
185
230
|
help="List of file names to skip check.",
|
|
186
|
-
required=
|
|
231
|
+
required=False,
|
|
187
232
|
)
|
|
188
233
|
@click.option(
|
|
189
234
|
"-sd",
|
|
190
235
|
"--skip-domains",
|
|
236
|
+
cls=ListOfStrings,
|
|
191
237
|
type=list[str],
|
|
192
238
|
default=[],
|
|
193
239
|
help="List of domains to skip check.",
|
|
@@ -196,37 +242,23 @@ def detect_issues(
|
|
|
196
242
|
@click.option(
|
|
197
243
|
"-suc",
|
|
198
244
|
"--skip-urls-containing",
|
|
245
|
+
cls=ListOfStrings,
|
|
199
246
|
type=list[str],
|
|
200
247
|
default=["https://www.microsoft.com/en-us/security/blog", "video-embed.html"],
|
|
201
248
|
help="List of urls to skip check.",
|
|
202
249
|
required=False,
|
|
203
250
|
)
|
|
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
251
|
@click.option(
|
|
220
252
|
"-gu",
|
|
221
253
|
"--guide-url",
|
|
222
254
|
type=str,
|
|
223
255
|
help="Full url of your contributing guide.",
|
|
224
|
-
required=
|
|
256
|
+
required=False,
|
|
225
257
|
)
|
|
226
258
|
@click.option(
|
|
227
259
|
"-to",
|
|
228
260
|
"--timeout",
|
|
229
|
-
type=
|
|
261
|
+
type=click.IntRange(0, 50),
|
|
230
262
|
default=10,
|
|
231
263
|
help="Timeout in seconds for the requests.",
|
|
232
264
|
required=False,
|
|
@@ -234,7 +266,7 @@ def detect_issues(
|
|
|
234
266
|
@click.option(
|
|
235
267
|
"-rt",
|
|
236
268
|
"--retries",
|
|
237
|
-
type=
|
|
269
|
+
type=click.IntRange(0, 10),
|
|
238
270
|
default=3,
|
|
239
271
|
help="Number of retries for the requests.",
|
|
240
272
|
required=False,
|
|
@@ -245,12 +277,12 @@ def detect_issues(
|
|
|
245
277
|
type=str,
|
|
246
278
|
default="comment",
|
|
247
279
|
help="Name of the output file.",
|
|
248
|
-
required=
|
|
280
|
+
required=False,
|
|
249
281
|
)
|
|
250
282
|
@click.argument(
|
|
251
283
|
"src",
|
|
252
284
|
nargs=-1,
|
|
253
|
-
type=click.Path(exists=True, file_okay=True, dir_okay=True, readable=True),
|
|
285
|
+
type=click.Path(path_type=Path, exists=True, file_okay=True, dir_okay=True, readable=True),
|
|
254
286
|
is_eager=True,
|
|
255
287
|
metavar="SRC ...",
|
|
256
288
|
required=False,
|
|
@@ -259,23 +291,22 @@ def detect_issues(
|
|
|
259
291
|
message=(f"%(prog)s, %(version)s\n" f"Python ({platform.python_implementation()}) {platform.python_version()}"),
|
|
260
292
|
)
|
|
261
293
|
def main(
|
|
262
|
-
src: tuple[
|
|
263
|
-
dir:
|
|
294
|
+
src: tuple[Path, ...],
|
|
295
|
+
dir: Path,
|
|
264
296
|
func: str,
|
|
265
|
-
guide_url: str,
|
|
297
|
+
guide_url: Union[str, None],
|
|
266
298
|
extensions: list[str],
|
|
267
299
|
skip_files: list[str],
|
|
268
300
|
skip_domains: list[str],
|
|
269
301
|
skip_urls_containing: list[str],
|
|
302
|
+
tracking_domains: list[str],
|
|
270
303
|
timeout: int,
|
|
271
304
|
retries: int,
|
|
272
|
-
tracking_domains: list[str],
|
|
273
305
|
output_file_name: str,
|
|
274
306
|
) -> None:
|
|
275
307
|
"""A markdown link validation reporting tool."""
|
|
276
|
-
_ =
|
|
277
|
-
|
|
278
|
-
_, files_paths = get_files_paths_list(Path(dir), extensions)
|
|
308
|
+
_ = src or (Path("./"),) # default to current directory
|
|
309
|
+
_, files_paths = get_files_paths_list(dir, extensions)
|
|
279
310
|
|
|
280
311
|
# remove files from skip_files list
|
|
281
312
|
files_paths = [file_path for file_path in files_paths if file_path.name not in skip_files]
|
|
@@ -1,31 +1,29 @@
|
|
|
1
1
|
import pathlib
|
|
2
|
+
from typing import Union
|
|
2
3
|
|
|
3
4
|
from markdown_checker.reports.generator_base import GeneratorBase
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
class MarkdownGenerator(GeneratorBase):
|
|
7
8
|
current_dir = pathlib.Path(__file__).parent
|
|
8
|
-
check_broken_paths_template = open(current_dir / "templates/paths/broken.md").read()
|
|
9
|
-
check_broken_urls_template = open(current_dir / "templates/urls/broken.md").read()
|
|
10
|
-
check_paths_tracking_template = open(current_dir / "templates/paths/tracking.md").read()
|
|
11
|
-
check_urls_tracking_template = open(current_dir / "templates/urls/tracking.md").read()
|
|
12
|
-
check_urls_locale_template = open(current_dir / "templates/urls/locale.md").read()
|
|
13
|
-
templates = {
|
|
14
|
-
"check_broken_paths": check_broken_paths_template,
|
|
15
|
-
"check_broken_urls": check_broken_urls_template,
|
|
16
|
-
"check_paths_tracking": check_paths_tracking_template,
|
|
17
|
-
"check_urls_tracking": check_urls_tracking_template,
|
|
18
|
-
"check_urls_locale": check_urls_locale_template,
|
|
19
|
-
}
|
|
20
9
|
|
|
21
10
|
def __init__(
|
|
22
11
|
self,
|
|
12
|
+
contributing_guide_url: Union[str, None] = None,
|
|
23
13
|
output_file_name: str = "comment",
|
|
24
|
-
contributing_guide_url: str = "https://github.com/john0isaac/markdown-checker/blob/main/CONTRIBUTING.md",
|
|
25
14
|
) -> None:
|
|
15
|
+
self.templates = {
|
|
16
|
+
"check_broken_paths": open(self.current_dir / "templates/paths/broken.md").read(),
|
|
17
|
+
"check_broken_urls": open(self.current_dir / "templates/urls/broken.md").read(),
|
|
18
|
+
"check_paths_tracking": open(self.current_dir / "templates/paths/tracking.md").read(),
|
|
19
|
+
"check_urls_tracking": open(self.current_dir / "templates/urls/tracking.md").read(),
|
|
20
|
+
"check_urls_locale": open(self.current_dir / "templates/urls/locale.md").read(),
|
|
21
|
+
}
|
|
26
22
|
self.output_file_name = output_file_name
|
|
27
23
|
self.contributing_guide_line = (
|
|
28
|
-
f" For more details, check our [Contributing Guide]({contributing_guide_url}).\n\n"
|
|
24
|
+
(f" For more details, check our [Contributing Guide]({contributing_guide_url}).\n\n")
|
|
25
|
+
if contributing_guide_url
|
|
26
|
+
else "\n\n"
|
|
29
27
|
)
|
|
30
28
|
|
|
31
29
|
def _write_file(self, generated_text: str) -> None:
|
|
@@ -60,8 +58,3 @@ class MarkdownGenerator(GeneratorBase):
|
|
|
60
58
|
"""
|
|
61
59
|
generated_text = self._generate_text(function_name=function_name, formatted_output=formatted_output)
|
|
62
60
|
self._write_file(generated_text)
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
if __name__ == "__main__":
|
|
66
|
-
md_generator = MarkdownGenerator()
|
|
67
|
-
md_generator.generate("check_broken_paths", "This is a test")
|
|
@@ -43,9 +43,10 @@ class MarkdownURL(MarkdownLinkBase):
|
|
|
43
43
|
response = requests.head(self.link, timeout=timeout, allow_redirects=True)
|
|
44
44
|
if response.status_code == 200:
|
|
45
45
|
return True
|
|
46
|
-
|
|
46
|
+
else:
|
|
47
47
|
response = requests.get(self.link, timeout=timeout, allow_redirects=True)
|
|
48
|
-
|
|
48
|
+
if response.status_code == 200:
|
|
49
|
+
return True
|
|
49
50
|
except requests.RequestException:
|
|
50
51
|
continue
|
|
51
52
|
time.sleep(1)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{markdown_checker-0.2.0 → markdown_checker-0.2.2}/src/markdown_checker/markdown_link_base.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{markdown_checker-0.2.0 → markdown_checker-0.2.2}/src/markdown_checker/reports/generator_base.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{markdown_checker-0.2.0 → markdown_checker-0.2.2}/src/markdown_checker/utils/extract_links.py
RENAMED
|
File without changes
|
{markdown_checker-0.2.0 → markdown_checker-0.2.2}/src/markdown_checker/utils/format_output.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{markdown_checker-0.2.0 → markdown_checker-0.2.2}/src/markdown_checker.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{markdown_checker-0.2.0 → markdown_checker-0.2.2}/src/markdown_checker.egg-info/entry_points.txt
RENAMED
|
File without changes
|
{markdown_checker-0.2.0 → markdown_checker-0.2.2}/src/markdown_checker.egg-info/requires.txt
RENAMED
|
File without changes
|
{markdown_checker-0.2.0 → markdown_checker-0.2.2}/src/markdown_checker.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|