Initial import
[lttng-docs.git] / tools / checkdocs.py
1 #!/usr/bin/env python3
2
3 # The MIT License (MIT)
4 #
5 # Copyright (c) 2014 Philippe Proulx <eepp.ca>
6 # Copyright (c) 2014 The LTTng Project <lttng.org>
7 #
8 # Permission is hereby granted, free of charge, to any person obtaining a copy
9 # of this software and associated documentation files (the "Software"), to deal
10 # in the Software without restriction, including without limitation the rights
11 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 # copies of the Software, and to permit persons to whom the Software is
13 # furnished to do so, subject to the following conditions:
14 #
15 # The above copyright notice and this permission notice shall be included in
16 # all copies or substantial portions of the Software.
17 #
18 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 # THE SOFTWARE.
25
26 import re
27 import os
28 import sys
29 from termcolor import colored
30
31
32 TOC_PATH = 'toc/docs.yml'
33 CONTENTS_ROOT_PATH = 'contents'
34
35
36 def _perror(filename, msg):
37 s = '{} {} {}'.format(filename, colored('Error:', 'red'),
38 colored(msg, 'red', attrs=['bold']))
39 print(s)
40
41
42 def _pwarn(filename, msg):
43 s = '{} {} {}'.format(filename, colored('Warning:', 'yellow'),
44 colored(msg, 'yellow', attrs=['bold']))
45 print(s)
46
47
48 def _get_files(root):
49 files = []
50
51 for dirpath, dirnames, filenames in os.walk(root):
52 for f in filenames:
53 files.append(os.path.join(dirpath, f))
54
55 return sorted(files)
56
57
58 def _get_toc_ids(path):
59 p = re.compile(r'id\s*:\s*(.+)$', flags=re.M)
60
61 with open(path) as f:
62 orig_ids = p.findall(f.read())
63
64 ids = set(orig_ids)
65
66 if len(ids) != len(orig_ids):
67 _perror(path, 'Duplicate IDs')
68 return None
69
70 return ids
71
72
73 def _check_file_links(toc_ids, path, c):
74 ilinkp = re.compile(r'\[[^\]]+\]\(([^)]+)\)', flags=re.M)
75 elinkp = re.compile(r'href="([^"]+)"')
76
77 ret = True
78
79 ilinks = ilinkp.findall(c)
80 elinks = elinkp.findall(c)
81
82 for link in ilinks:
83 if not link.startswith('#doc-'):
84 s = 'Internal link does not start with "#doc-": "{}"'.format(link)
85 _perror(path, s)
86 ret = False
87 continue
88
89 sid = link[5:]
90
91 if sid not in toc_ids:
92 _perror(path, 'Dead internal link: "{}"'.format(link))
93 ret = False
94
95 for link in elinks:
96 if link.startswith('#'):
97 _pwarn(path, 'External link starts with #: "{}"'.format(link))
98 ret = False
99
100 return ret
101
102
103 def _check_contents(toc_ids, contents_files):
104 ret = True
105
106 for path in contents_files:
107 with open(path) as f:
108 c = f.read()
109
110 ret &= _check_file_links(toc_ids, path, c)
111
112 return ret
113
114
115 def _check_non_md(files):
116 ret = True
117
118 for f in files:
119 if not f.endswith('.md'):
120 _perror(f, 'Wrong, non-Markdown file')
121 ret = False
122
123 return ret
124
125
126 def checkdocs():
127 toc_ids = _get_toc_ids(TOC_PATH)
128
129 if toc_ids is None:
130 return False
131
132 contents_files = _get_files(CONTENTS_ROOT_PATH)
133
134 if not _check_non_md(contents_files):
135 return False
136
137 if not _check_contents(toc_ids, contents_files):
138 return False
139
140 return True
141
142
143 if __name__ == '__main__':
144 sys.exit(0 if checkdocs() else 1)
This page took 0.032033 seconds and 4 git commands to generate.