Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
 
17
/**
18
 * Check that, as in the coding guidelines, every to-do comment links to a tracker issue.
19
 *
20
 * As required by https://moodledev.io/general/development/policies/codingstyle.
21
 *
22
 * @package    core
23
 * @copyright  2009 Tim Hunt
24
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25
 */
26
 
27
require(__DIR__ . '/../../../config.php');
28
 
29
require_login();
30
$context = context_system::instance();
31
require_capability('moodle/site:config', $context);
32
 
33
$PAGE->set_url('/lib/tests/other/todochecker.php');
34
$PAGE->set_context($context);
35
$PAGE->set_title('To-do checker');
36
$PAGE->set_heading('To-do checker');
37
 
38
$thirdparty = load_third_party_lib_list();
39
$extensionstotest = array('php');
40
$extensionsregex = '/\.(?:' . implode('|', $extensionstotest) . ')$/';
41
$patterntofind = 'TO' . 'DO'; // Make it not match the regex.
42
$found = array();
43
 
44
echo $OUTPUT->header();
45
echo $OUTPUT->heading('To-do checker', 2);
46
 
47
echo $OUTPUT->box_start();
48
echo 'Checking code ...';
49
flush();
50
recurseFolders($CFG->dirroot, 'check_to_dos', $extensionsregex, false, array_keys($thirdparty));
51
echo ' done.';
52
echo $OUTPUT->box_end();
53
 
54
if (empty($found)) {
55
    echo '<p>No to-dos found.</p>';
56
} else {
57
    $total = 0;
58
    foreach ($found as $filepath => $matches) {
59
        $total += count($matches);
60
    }
61
 
62
    echo '<p>' . $total . ' to-dos found:</p><dl>';
63
    foreach ($found as $filepath => $matches) {
64
        echo '<dt>' . $filepath . ' <b>(' . count($matches) . ')</b></dt><dd><ul>';
65
        foreach ($matches as $lineno => $line) {
66
            $url = 'http://cvs.moodle.org/moodle/' . $filepath . '?view=annotate#l' . $lineno;
67
            $error = '';
68
 
69
            // Make sure there is a tracker issue id mentioned
70
            $matches = array();
71
            if (preg_match('/\bTODO\b.*?\b(MDL-\d+)/', $line, $matches)) {
72
                $issueid = $matches[1];
73
                $issueurl = 'http://tracker.moodle.org/browse/' . $issueid;
74
 
75
                // Make sure the issue is still open.
76
                list($issueopen, $issuesummary) = issue_info($issueid);
77
                if ($issueopen) {
78
                    $issuename = $issueid;
79
                } else {
80
                    $issuename = '<strike>' . $issueid . '</strike>';
81
                    $error = 'The associated tracker issue is Resolved.';
82
                }
83
 
84
                $line = str_replace($issueid, '<a href="' . $issueurl . '" title="' . s($issuesummary) .
85
                        '">' . $issuename . '</a>', htmlspecialchars($line, ENT_COMPAT));
86
            } else {
87
                $line = htmlspecialchars($line, ENT_COMPAT);
88
                $error = 'No associated tracker issue.';
89
            }
90
 
91
            if ($error) {
92
                $error = '<span class="error">' . $error . '</span>';
93
            }
94
            echo '<li><a href="' . $url . '">' . $lineno . '</a>: ' . $line . $error . '</li>';
95
        }
96
        echo '</ul></dd>';
97
    }
98
    echo '</dl>';
99
}
100
 
101
echo $OUTPUT->footer();
102
 
103
function check_to_dos($filepath) {
104
    global $CFG, $found, $thirdparty;
105
    if (isset($thirdparty[$filepath])) {
106
        return; // Skip this file.
107
    }
108
    $lines = file($filepath);
109
    $matchesinfile = array();
110
    foreach ($lines as $lineno => $line) {
111
        if (preg_match('/(?<!->|\$)\bTODO\b/i', $line)) {
112
            $matchesinfile[$lineno] = $line;
113
        }
114
    }
115
    if (!empty($matchesinfile)) {
116
        $shortpath = str_replace($CFG->dirroot . '/', '', $filepath);
117
        $found[$shortpath] = $matchesinfile;
118
    }
119
}
120
 
121
function issue_info($issueid) {
122
    static $cache = array();
123
    if (array_key_exists($issueid, $cache)) {
124
        return $cache[$issueid];
125
    }
126
 
127
    $xmlurl = 'http://tracker.moodle.org/si/jira.issueviews:issue-xml/' . $issueid . '/' . $issueid . '.xml';
128
    $content = download_file_content($xmlurl);
129
 
130
    // Get the status.
131
    $open = preg_match('/Unresolved<\/resolution>/', $content);
132
 
133
    // Get the summary.
134
    $matches = array();
135
    preg_match('/<title>\[' . $issueid . '\]\s+(.*?)<\/title>/', $content, $matches);
136
    $summary = $matches[1];
137
    preg_match('/<assignee[^>]*>(.*?)<\/assignee>/', $content, $matches);
138
    $summary .= ' - Assignee: ' . $matches[1];
139
 
140
    $cache[$issueid] = array($open, $summary);
141
    return $cache[$issueid];
142
}
143
 
144
function load_third_party_lib_list() {
145
    global $CFG;
146
    $libs = array();
147
    $xml = simplexml_load_file($CFG->libdir . '/thirdpartylibs.xml');
148
    foreach ($xml->library as $libobject) {
149
        $libs[$CFG->libdir . '/' . $libobject->location] = 1;
150
    }
151
    return $libs;
152
}
153
 
154
function recurseFolders($path, $callback, $fileregexp = '/.*/', $exclude = false, $ignorefolders = array()) {
155
    $files = scandir($path);
156
 
157
    foreach ($files as $file) {
158
        $filepath = $path .'/'. $file;
159
        if (strpos($file, '.') === 0) {
160
            /// Don't check hidden files.
161
            continue;
162
        } else if (is_dir($filepath)) {
163
            if (!in_array($filepath, $ignorefolders)) {
164
                recurseFolders($filepath, $callback, $fileregexp, $exclude, $ignorefolders);
165
            }
166
        } else if ($exclude xor preg_match($fileregexp, $filepath)) {
167
            call_user_func($callback, $filepath);
168
        }
169
    }
170
}