Skip to content

Commit

Permalink
Add the new moodle.FilesLangFilesOrdering sniff
Browse files Browse the repository at this point in the history
This sniff examines exclusively lang files, only for Moodle 4.4 and up,
and has the following features:
 - Detect "groups" of lang strings, (normal, deprecated) within the
   lang file, checking for correct order within each group.
 - If other comments, different from the deprecated ones, are found,
   for safety the sniff will stop fixing strings after that point,
   although it will continue reporting them as out of order.
 - Detect wrong variable names (different from `$string`).
 - Detect duplicate strings within each lang file group.
 - Detect strings with incorrect trailing contents after it (php code,
   invalid comment...).
 - Detect strings out of order within each lang file group and fix them.

Notes about the fixing:
 - Due to CodeSniffer fixing limits, this has been the really complex
   thing to implement and to guarantee that the fixer works also for
   "big" lang files (say error.php and similar ones).
 - To do so, instead of fixing every case 1 by 1, while we are
   checking the file... we have to accumulate all the changes
   in custom structure and then, apply everything together as
   a big changeset.
 - As said above, for safety, if an unexpected comment is found,
   the fixer stops applying any change after that line. In order to
   allow it to continue fixing, the comment must be removed. Only
   comments allowed are the "^// Deprecated since " ones, used to
   detect the groups of strings.
  • Loading branch information
stronk7 committed Mar 4, 2024
1 parent cc7a974 commit be8a451
Show file tree
Hide file tree
Showing 8 changed files with 671 additions and 0 deletions.
340 changes: 340 additions & 0 deletions moodle/Sniffs/Files/LangFilesOrderingSniff.php

Large diffs are not rendered by default.

97 changes: 97 additions & 0 deletions moodle/Tests/Sniffs/Files/LangFilesOrderingTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<?php

// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.

namespace MoodleHQ\MoodleCS\moodle\Tests\Files;

use MoodleHQ\MoodleCS\moodle\Tests\MoodleCSBaseTestCase;

/**
* Test the LangFilesOrderingSniff sniff.
*
* @copyright 2024 onwards Eloy Lafuente (stronk7) {@link https://stronk7.com}
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*
* @covers \MoodleHQ\MoodleCS\moodle\Sniffs\Files\LangFilesOrderingSniff
*/
class LangFilesOrderingTest extends MoodleCSBaseTestCase
{
/**
* @dataProvider filesOrderingProvider
*/
public function testLangFilesOrdering(
string $fixture,
array $warnings,
array $errors
) {
$this->setStandard('moodle');
$this->setSniff('moodle.Files.LangFilesOrdering');
$this->setFixture(__DIR__ . '/fixtures/langFilesOrdering/' . $fixture);
$this->setWarnings($warnings);
$this->setErrors($errors);

$this->verifyCsResults();
}

/**
* Data provider for testLangFilesOrdering tests.
*
* @return array
*/
public static function filesOrderingProvider(): array {
return [
'processed correct' => [
'lang/en/correct.php',
[],
[],
],
'processed with problems' => [
'lang/en/withWarningsAndErrors.php',
[
27 => '"modvisiblewithstealth_help" is not in the correct order',
30 => 1,
34 => 1,
37 => 1,
38 => 1,
45 => 1,
46 => 1,
47 => 1,
51 => 1,
60 => 'Unexpected comment found. Auto-fixing will not work after this',
61 => 1,
63 => 1,
64 => 1,
],
[
31 => 'Variable "$anothervar" is not expected',
33 => 'Unexpected string syntax, it should be',
40 => 'The string key "yourself" is duplicated',
42 => 'Unexpected string end',
],
],
'without strings' => [
'lang/en/withoutLangStrings.php',
[],
[],
],
'not processed' => [
'lang/en@wrong/incorrectLangDir.php',
[],
[],
],
];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.

/**
* A fixture lang-like file in correct place to test the LangFilesOrderingSniff.
*
* @package core
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

// This lang file is perfect!
$string['aaaa'] = 'aaaa';
$string['bbbb'] = 'bbbb';
$string['cccc'] = 'cccc';
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.

/**
* A fixture lang-like file in correct place to test the LangFilesOrderingSniff.
*
* @package core
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

// This lang file is perfect!
$string['aaaa'] = 'aaaa';
$string['bbbb'] = 'bbbb';
$string['cccc'] = 'cccc';
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.

/**
* A fixture lang-like file in correct place to test the LangFilesOrderingSniff.
*
* @package core
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

$string['abouttobeinstalled'] = 'about to be installed';
$string['yourlastlogin'] = 'Your last login was';
$string['modvisiblewithstealth_help'] = '* Show on course page: Available to students (subject to any access restrictions which may be set).
* Hide on course page: Not available to students.
* Make available but don\'t show on course page: Available to students if you provide a link. Activities will still appear in the gradebook and other reports.';
$string['action'] = 'Action';
$anothervar['choco'] = 'kk';
$string['youneedtoenrol'] = 'To perform that action you need to enrol in this course.';
$string['bad' ] = 'Bad';
$string['actionchoice'] = 'What do you want to do with the file \'{$a}\'?';
$string['actions'] = 'Actions';
$string['moodlenet:sharesuccesstext'] = "Almost done! Visit your drafts in MoodleNet to finish sharing your content.";
$string['actionsmenu2'] = "Actions menu2";
$string["actionsmenu"] = 'Actions menu';
$string['yourself'] = 'yourself';
$string['yourself'] = 'yourself';
$string['yourteacher'] = 'your {$a}';
$string['withoutlinefeed'] = 'Without line feed'; echo 'I should not be here. Not fixable';
$string['yourwordforx'] = 'Your word for \'{$a}\'';
$string['zippingbackup'] = 'Zipping backup';
$string['deprecatedeventname'] = '{$a} (no longer in use)';
$string['accept'] = 'Accept';
$string['1111'] = '1111';

// Deprecated since Moodle 4.0.
$string['cupplyinfo'] = 'More details';
$string['bcreateuserandpass'] = 'Choose your username and password';

// Deprecated since Moodle 4.3.
$string['clicktochangeinbrackets'] = '{$a} (Click to change)';

// Deprecated since Moodle 4.4.
$string['asocialheadline'] = 'Social forum - latest topics';
$string['topicshow'] = 'Show this topic to {$a}';

$string['zzzz'] = 'zzzz'; // This comment shouldn't be here. No more auto-fixing after this line.
$string['yyyy'] = 'yyyy';

$string['bbbb'] = 'bbbb';
$string['aaaa'] = 'aaaa';
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.

/**
* A fixture lang-like file in correct place to test the LangFilesOrderingSniff.
*
* @package core
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

$string['1111'] = '1111';
$string['abouttobeinstalled'] = 'about to be installed';
$string['accept'] = 'Accept';
$string['action'] = 'Action';
$string['actionchoice'] = 'What do you want to do with the file \'{$a}\'?';
$string['actions'] = 'Actions';
$string["actionsmenu"] = 'Actions menu';
$string['actionsmenu2'] = "Actions menu2";
$string['deprecatedeventname'] = '{$a} (no longer in use)';
$string['modvisiblewithstealth_help'] = '* Show on course page: Available to students (subject to any access restrictions which may be set).
* Hide on course page: Not available to students.
* Make available but don\'t show on course page: Available to students if you provide a link. Activities will still appear in the gradebook and other reports.';
$string['moodlenet:sharesuccesstext'] = "Almost done! Visit your drafts in MoodleNet to finish sharing your content.";
$string['youneedtoenrol'] = 'To perform that action you need to enrol in this course.';
$string['yourlastlogin'] = 'Your last login was';
$anothervar['choco'] = 'kk';
$string['bad' ] = 'Bad';
$string['yourself'] = 'yourself';
$string['yourself'] = 'yourself';
$string['yourteacher'] = 'your {$a}';
$string['withoutlinefeed'] = 'Without line feed'; echo 'I should not be here. Not fixable';
$string['yourwordforx'] = 'Your word for \'{$a}\'';
$string['zippingbackup'] = 'Zipping backup';

// Deprecated since Moodle 4.0.
$string['bcreateuserandpass'] = 'Choose your username and password';
$string['cupplyinfo'] = 'More details';

// Deprecated since Moodle 4.3.
$string['clicktochangeinbrackets'] = '{$a} (Click to change)';

// Deprecated since Moodle 4.4.
$string['asocialheadline'] = 'Social forum - latest topics';
$string['topicshow'] = 'Show this topic to {$a}';

$string['zzzz'] = 'zzzz'; // This comment shouldn't be here. No more auto-fixing after this line.
$string['yyyy'] = 'yyyy';

$string['bbbb'] = 'bbbb';
$string['aaaa'] = 'aaaa';
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.

/**
* A fixture lang-like file in correct place to test the LangFilesOrderingSniff.
*
* @package core
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

// Surprise, surprise, this lang file does not have any string.
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.

/**
* A fixture lang-like file in incorrect place to test the LangFilesOrderingSniff.
*
* @package core
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

$string['wedontneedmany'] = 'As far as this file is not going to be processed (wrong location), one string is enough.';

0 comments on commit be8a451

Please sign in to comment.