Coverage for /builds/ahmed.baizid.0/gtk-doc/gtkdoc/check.py: 11%
85 statements
« prev ^ index » next coverage.py v6.5.0, created at 2024-11-05 19:25 +0000
« prev ^ index » next coverage.py v6.5.0, created at 2024-11-05 19:25 +0000
1# -*- python; coding: utf-8 -*-
2#
3# gtk-doc - GTK DocBook documentation generator.
4# Copyright (C) 2007 David Nečas
5# 2007-2017 Stefan Sauer
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 2 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20#
22"""
23The check tool runs various tests on built documentation and outputs test
24results. Can be run druring make check, by adding this to the documentations
25Makefile.am: TESTS = $(GTKDOC_CHECK).
26"""
28import argparse
29import os
30import re
31from glob import glob
33from . import config
35class FileFormatError(Exception):
36 pass
39def grep(regexp, lines, what):
40 pattern = re.compile(regexp)
41 for line in lines:
42 for match in re.finditer(pattern, line):
43 return match.group(1)
44 raise FileFormatError(what)
47def check_empty(filename):
48 with open(filename, "rb") as f:
49 count = sum(1 for line in f if line.strip())
50 return count
53def read_file(filename):
54 with open(filename, 'r', encoding='utf-8') as f:
55 return f.read().splitlines()
58def check_includes(filename):
59 # Check that each XML file in the xml directory is included in doc_main_file
60 lines = read_file(filename)
61 num_missing = 0
62 for include in glob('xml/*.xml'):
63 try:
64 next(line for line in lines if include in line)
65 except StopIteration:
66 num_missing += 1
67 print('%s:1:E: doesn\'t appear to include "%s"' % (filename, include))
69 return num_missing
72def get_variable(env, lines, variable):
73 value = env.get(variable, None)
74 if value is None:
75 value = grep(r'^\s*' + variable + r'\s*=\s*(\S+)', lines, variable)
76 return value
79def run_tests(workdir, doc_module, doc_main_file):
80 checks = 4
82 print('Running suite(s): gtk-doc-' + doc_module)
84 # Test #1
85 statusfilename = os.path.join(workdir, doc_module + '-undocumented.txt')
86 statusfile = read_file(statusfilename)
87 try:
88 undocumented = int(grep(r'^(\d+)\s+not\s+documented\.\s*$',
89 statusfile, 'number of undocumented symbols'))
90 incomplete = int(grep(r'^(\d+)\s+symbols?\s+incomplete\.\s*$',
91 statusfile, 'number of incomplete symbols'))
92 except FileFormatError as e:
93 print('Cannot find %s in %s' % (str(e), statusfilename))
94 return checks # consider all failed
96 total = undocumented + incomplete
97 if total:
98 print(doc_module + '-undocumented.txt:1:E: %d undocumented or incomplete symbols' % total)
100 # Test #2
101 undeclared = check_empty(os.path.join(workdir, doc_module + '-undeclared.txt'))
102 if undeclared:
103 print(doc_module + '-undeclared.txt:1:E: %d undeclared symbols\n' % undeclared)
105 # Test #3
106 unused = check_empty(os.path.join(workdir, doc_module + '-unused.txt'))
107 if unused:
108 print(doc_module + '-unused.txt:1:E: %d unused documentation entries\n' % unused)
110 # Test #4
111 missing_includes = check_includes(os.path.join(workdir, doc_main_file))
113 # Test Summary
114 failed = (total > 0) + (undeclared != 0) + (unused != 0) + (missing_includes != 0)
115 rate = 100.0 * (checks - failed) / checks
116 print("%.1f%%: Checks %d, Failures: %d" % (rate, checks, failed))
117 return failed
120def run(options=None):
121 """Runs the tests.
123 Returns:
124 int: a system exit code.
125 """
127 # Get parameters from test env, if not there try to grab them from the makefile
128 # We like Makefile.am more but builddir does not necessarily contain one.
129 makefilename = 'Makefile.am'
130 if not os.path.exists(makefilename):
131 makefilename = 'Makefile'
132 makefile = []
133 try:
134 makefile = read_file(makefilename)
135 except (OSError, IOError):
136 pass
138 # For historic reasons tests are launched in srcdir
139 workdir = os.environ.get('BUILDDIR', None)
140 if not workdir:
141 workdir = '.'
143 try:
144 doc_module = get_variable(os.environ, makefile, 'DOC_MODULE')
145 doc_main_file = get_variable(os.environ, makefile, 'DOC_MAIN_SGML_FILE')
146 except FileFormatError as e:
147 print('Cannot find %s in %s' % (str(e), makefilename))
148 return 1
150 doc_main_file = doc_main_file.replace('$(DOC_MODULE)', doc_module)
152 return run_tests(workdir, doc_module, doc_main_file)
155def new_args_parser():
156 parser = argparse.ArgumentParser(
157 description="gtkdoc-check version {config.version} - run documentation unit tests"
158 )
159 parser.add_argument("--version", action="version", version=config.version)
160 return parser