[TASK] Replace validateRstFiles.sh with PHP version 84/56484/2
authorSybille Peters <sypets@gmx.de>
Sun, 11 Mar 2018 09:52:19 +0000 (10:52 +0100)
committerChristian Kuhn <lolli@schwarzbu.ch>
Thu, 29 Mar 2018 16:47:49 +0000 (18:47 +0200)
Resolves: #84197
Releases: master,8.7
Change-Id: Ie0dcb29243a0852baa1b0de104b2e357edd0ab36
Reviewed-on: https://review.typo3.org/56484
Reviewed-by: Frank Naegler <frank.naegler@typo3.org>
Tested-by: Frank Naegler <frank.naegler@typo3.org>
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
Build/Scripts/test/rstFiles/data/test1/Changelog/master/Feature-12345-Test1.rst [new file with mode: 0644]
Build/Scripts/test/rstFiles/data/test2/Changelog/master/Feature-12345-Test2.rst [new file with mode: 0644]
Build/Scripts/test/rstFiles/data/test3/Changelog/master/Feature-12345-Test3.rst [new file with mode: 0644]
Build/Scripts/test/rstFiles/data/test4/Changelog/master/Deprecation-12345-Test4.rst [new file with mode: 0644]
Build/Scripts/test/rstFiles/testValidateRstFiles.sh [new file with mode: 0755]
Build/Scripts/validateRstFiles.php [new file with mode: 0755]
Build/Scripts/validateRstFiles.sh [deleted file]
Build/bamboo/src/main/java/core/AbstractCoreSpec.java
typo3/sysext/core/Documentation/Changelog/8.0/Breaking-72405-RemovedTraditionalBEModulesHandling.rst
typo3/sysext/core/Documentation/Changelog/8.1/Feature-72923-ConfigurableFileListSize.rst
typo3/sysext/core/Documentation/Changelog/8.5/Deprecation-78668-TypoScriptOptionConfigmainScript.rst

diff --git a/Build/Scripts/test/rstFiles/data/test1/Changelog/master/Feature-12345-Test1.rst b/Build/Scripts/test/rstFiles/data/test1/Changelog/master/Feature-12345-Test1.rst
new file mode 100644 (file)
index 0000000..03593ea
--- /dev/null
@@ -0,0 +1,13 @@
+
+========================
+Feature: #12345 - Test 1
+========================
+
+See :issue:`12345`
+
+Description
+===========
+
+This file should fail, because the include line in top of this file is missing.
+
+.. index:: PHP-API
diff --git a/Build/Scripts/test/rstFiles/data/test2/Changelog/master/Feature-12345-Test2.rst b/Build/Scripts/test/rstFiles/data/test2/Changelog/master/Feature-12345-Test2.rst
new file mode 100644 (file)
index 0000000..f72584e
--- /dev/null
@@ -0,0 +1,15 @@
+.. include:: ../../Includes.txt
+
+========================
+Feature: #12345 - Test 2
+========================
+
+See :issue:12345
+
+Description
+===========
+
+This file should fail, because the issue syntax is wrong.
+
+.. index:: PHP-API
+
diff --git a/Build/Scripts/test/rstFiles/data/test3/Changelog/master/Feature-12345-Test3.rst b/Build/Scripts/test/rstFiles/data/test3/Changelog/master/Feature-12345-Test3.rst
new file mode 100644 (file)
index 0000000..cbb3a13
--- /dev/null
@@ -0,0 +1,13 @@
+.. include:: ../../Includes.txt
+
+========================
+Feature: #12345 - Test 3
+========================
+
+See :issue:`76349`
+
+Description
+===========
+
+This file should fail, because the index line at the bottom is missing.
+
diff --git a/Build/Scripts/test/rstFiles/data/test4/Changelog/master/Deprecation-12345-Test4.rst b/Build/Scripts/test/rstFiles/data/test4/Changelog/master/Deprecation-12345-Test4.rst
new file mode 100644 (file)
index 0000000..922c0d5
--- /dev/null
@@ -0,0 +1,14 @@
+.. include:: ../../Includes.txt
+
+============================
+Deprecation: #12345 - Test 4
+============================
+
+See :issue:`83740`
+
+Description
+===========
+
+This file should fail, because one of the Scanned-Tags is missing
+
+.. index:: Backend, Database, PHP-API
diff --git a/Build/Scripts/test/rstFiles/testValidateRstFiles.sh b/Build/Scripts/test/rstFiles/testValidateRstFiles.sh
new file mode 100755 (executable)
index 0000000..25d838b
--- /dev/null
@@ -0,0 +1,31 @@
+#!/bin/bash
+
+###########################
+#
+# Test validateRstFiles.php
+#
+###########################
+
+# --------------
+# automatic vars
+# --------------
+savedir=$(pwd)
+scriptdir=$(dirname $0)
+cd $scriptdir
+scriptdir=$(pwd)
+progname=$(basename $0)
+
+
+ls data | while read testdir;do
+   echo "testing $testdir"
+   ../../validateRstFiles.php -d data/$testdir >/dev/null 2>/dev/null
+   if [ $? -ne 1 ];then
+      echo " "
+      echo "$progname: ERROR: test on data/$testdir should return exit code 1"
+   fi
+done
+
+echo " "
+echo "$progname: all tests ok"
+
+cd $savedir
\ No newline at end of file
diff --git a/Build/Scripts/validateRstFiles.php b/Build/Scripts/validateRstFiles.php
new file mode 100755 (executable)
index 0000000..fcbac85
--- /dev/null
@@ -0,0 +1,222 @@
+#!/usr/bin/env php
+<?php
+declare(strict_types=1);
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+require __DIR__ . '/../../vendor/autoload.php';
+
+if (PHP_SAPI !== 'cli') {
+    die('Script must be called from command line.' . chr(10));
+}
+
+use Symfony\Component\Finder\Finder;
+
+/**
+ * Check ReST files for integrity. If errors are found, they will be
+ * output on stdout and the program will exit with exit code 1.
+ *
+ * Optional arguments: -d <directory>
+ *
+ * By default, the standard path is used. You can override this for
+ * testing purposes.
+ */
+class validateRstFiles
+{
+    /**
+     * @var array
+     */
+    protected $messages;
+
+    /**
+     * @var bool
+     */
+    protected $isError;
+
+    /**
+     * @var string
+     */
+    protected $baseDir = 'typo3/sysext/core/Documentation/Changelog';
+
+    public function __construct(string $dir = '')
+    {
+        if ($dir) {
+            $this->baseDir = $dir;
+        }
+    }
+
+    public function validate()
+    {
+        printf('Searching for rst snippets in' . $this->baseDir . chr(10));
+
+        $count = 0;
+        $finder = $this->findFiles();
+        foreach ($finder as $file) {
+            $filename = (string)$file;
+            $this->clearMessages();
+            $fileContent = $file->getContents();
+            $this->validateContent($fileContent);
+            $a = explode(chr(10), trim($fileContent));
+            $lastLine = array_pop($a);
+            $this->validateLastLine($lastLine);
+            $this->validateLastLineForFilename($filename, $lastLine);
+
+            if ($this->isError) {
+                $shortPath = substr($filename, strlen($this->baseDir));
+                $shortPath = ltrim($shortPath, '/\\');
+                $count++;
+                printf(
+                    '%-10s | %-12s | %-17s | %s ' . chr(10),
+                    $this->messages['include']['title'],
+                    $this->messages['reference']['title'],
+                    $this->messages['index']['title'],
+                    $shortPath
+                );
+                if ($this->messages['include']['message']) {
+                    printf($this->messages['include']['message'] . chr(10));
+                }
+                if ($this->messages['reference']['message']) {
+                    printf($this->messages['reference']['message'] . chr(10));
+                }
+                if ($this->messages['index']['message']) {
+                    printf($this->messages['index']['message'] . chr(10));
+                }
+            }
+        }
+
+        if ($count > 0) {
+            fwrite(STDERR, 'Found ' . $count . ' rst files with errors, check full log for details.' . chr(10));
+            exit(1);
+        }
+        exit(0);
+    }
+
+    public function findFiles(): Finder
+    {
+        $finder = new Finder();
+        $finder
+            ->files()
+            ->in($this->baseDir)
+            ->name('/\.rst$/')
+            ->notName('Index.rst')
+            ->notName('Howto.rst');
+
+        return $finder;
+    }
+
+    protected function clearMessages()
+    {
+        $this->messages = [
+            'include' => [
+                'title' => '',
+                'message' => '',
+            ],
+            'reference' => [
+                'title' => '',
+                'message' => '',
+            ],
+            'index' => [
+                'title' => '',
+                'message' => '',
+            ],
+        ];
+
+        $this->isError = false;
+    }
+
+    protected function validateContent(string $fileContent)
+    {
+        $checkFor = [
+            [
+                'type' => 'include',
+                'regex' => '#^\\.\\. include:: \\.\\./\\.\\./Includes.txt#m',
+                'title' => 'no include',
+                'message' => 'insert \'.. include:: ../../Includes.txt\' in first line of the file',
+            ],
+            [
+                'type' => 'reference',
+                'regex' => '#^See :issue:`[0-9]{4,6}`#m',
+                'title' => 'no reference',
+                'message' => 'insert \'See :issue:`<issuenumber>`\' after headline',
+            ],
+        ];
+
+        foreach ($checkFor as $values) {
+            if (preg_match($values['regex'], $fileContent) !== 1) {
+                $this->messages[$values['type']]['title'] = $values['title'];
+                $this->messages[$values['type']]['message'] = $values['message'];
+                $this->isError = true;
+            }
+        }
+    }
+
+    protected function validateLastLine(string $line)
+    {
+        $checkFor = [
+            [
+                'type' => 'index',
+                'regex' => '#^\.\. index:: (?:(?:FullyScanned|PartiallyScanned|NotScanned|TypoScript|TSConfig|TCA|FlexForm|LocalConfiguration|Fluid|FAL|Database|JavaScript|PHP-API|Frontend|Backend|CLI|RTE|ext:[a-zA-Z_0-9]+)(?:,\\s|$))+#',
+                'title' => 'no or wrong index',
+                'message' => 'insert \'.. index:: <at least one valid keyword>\' at last line of the file. See Build/Scripts/validateRstFiles.php for allowed keywords',
+            ],
+        ];
+
+        foreach ($checkFor as $values) {
+            if (preg_match($values['regex'], $line) !== 1) {
+                $this->messages[$values['type']]['title'] = $values['title'];
+                $this->messages[$values['type']]['message'] = $values['message'];
+                $this->isError = true;
+            }
+        }
+    }
+
+    protected function validateLastLineForFilename(string $path, string $lastLine)
+    {
+        $checkFor = [
+            [
+                'type' => 'index',
+                'regexNotFilename' => '#
+                    Changelog[\\\\/]8\\.[0-9]+[\\\\/]|
+                    Changelog[\\\\/]8\\.7\\.x[\\\\/]|
+                    Changelog[\\\\/]7\\.[0-9]+[\\\\/]|
+                    Changelog[\\\\/]7\\.6\\.x[\\\\/]|
+                    Changelog[\\\\/](?:master|[0-9]+\\.[0-9]+)[\\\\/]Feature-|
+                    Changelog[\\\\/](?:master|[0-9]+\\.[0-9]+)[\\\\/]Important-
+                    #x',
+                'regex' => '#^\.\. index:: .*(?:FullyScanned|PartiallyScanned|NotScanned).*#',
+                'title' => 'missing FullyScanned / PartiallyScanned / NotScanned tag',
+                'message' => 'insert \'.. index:: <at least one valid keyword and either FullyScanned, PartiallyScanned or NotScanned>\' at last line of the file. See Build/Scripts/validateRstFiles.php for allowed keywords',
+            ],
+        ];
+
+        foreach ($checkFor as $values) {
+            if (preg_match($values['regexNotFilename'], $path) === 1) {
+                continue;
+            }
+            if (preg_match($values['regex'], $lastLine) !== 1) {
+                $this->messages[$values['type']]['title'] = $values['title'];
+                $this->messages[$values['type']]['message'] = $values['message'];
+                $this->isError = true;
+            }
+        }
+    }
+}
+
+$dir = '';
+$args = getopt('d:');
+if (isset($args['d'])) {
+    $dir = $args['d'];
+}
+$validator = new validateRstFiles($dir);
+$validator->validate();
diff --git a/Build/Scripts/validateRstFiles.sh b/Build/Scripts/validateRstFiles.sh
deleted file mode 100755 (executable)
index 286c278..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-#!/bin/bash
-
-#########################
-#
-# Check all rst snippets
-# in typo3/sysext/core/Documentation/Changelog
-#
-# It expects to be run from the core root.
-#
-##########################
-
-echo 'Searching for rst snippets'
-EXT=rst
-COUNT=0
-for i in `find typo3/sysext/core/Documentation/Changelog -name "*.rst" -type f`; do
-    if [[ "${i}" != "${i%.${EXT}}" && ! $i =~ 'Index.rst' &&  ! $i =~ 'Howto.rst' ]];then
-
-        fileContent=$(cat $i);
-        outputFileToStream=0;
-
-        # This regex needs to allow whitespace and/or newlines before the .. include:: ../../Includes.txt
-        # The regex itself is correct, bash doesn't like it
-        if ! [[ "$fileContent" =~ ^[[:space:]]*'.. include:: ../../Includes.txt' ]]; then
-            INCLUDE="no include"
-            include_message="insert '.. include:: ../../Includes.txt' in first line of the file"
-            outputFileToStream=1;
-        else
-            INCLUDE=""
-        fi
-
-        # This regex seems to have problems with the backtick characters.
-        # Maybe this is because it somehow interprets them from the variable $fileContent
-        if ! [[ "$fileContent" =~ 'See :issue:'\`([0-9]{4,6})\` ]]; then
-            REFERENCE="no reference"
-            reference_message="insert 'See :issue:\`<issuenumber>\`' after headline"
-            outputFileToStream=1;
-        else
-            REFERENCE=""
-        fi
-
-        # This regex needs to check that the ..index:: line a) holds valid content and b) is
-        # the last line in the checked file
-        INDEX=""
-        if ! [[ "$fileContent" =~ '.. index:: '((FullyScanned|PartiallyScanned|NotScanned|TypoScript|TSConfig|TCA|FlexForm|LocalConfiguration|Fluid|FAL|Database|JavaScript|PHP-API|Frontend|Backend|CLI|RTE|ext:([a-z|A-Z|_|0-9]*))([,|[:space:]]{2})?)+$ ]]; then
-            INDEX="no or wrong index"
-            index_message="insert '.. index:: <at least one valid keyword>' at last line of the file. See Build/Scripts/validateRstFiles.sh for allowed keywords"
-            outputFileToStream=1;
-        fi
-
-        # All Deprecation- / Breaking- files since v9 must have one of the tags FullyScanned|PartiallyScanned|NotScanned
-        if ! [[ "$i" =~ (Changelog\/8\.[0-99]+\/|Changelog\/8\.7\.x\/|Changelog\/7\.[0-99]+\/|Changelog\/7\.6\.x\/|Changelog\/master\/Feature-|Changelog\/master\/Important-|Changelog\/[0-99]+\.[0-99]+\/Feature-|Changelog\/[0-99]+\.[0-99]+\/Important-) ]]; then
-            if ! [[ "$fileContent" =~ ('.. index:: '.*(FullyScanned|PartiallyScanned|NotScanned)+.*) ]]; then
-                INDEX="missing FullyScanned / PartiallyScanned / NotScanned tag"
-                index_message="insert '.. index:: <at least one valid keyword and either FullyScanned, PartiallyScanned or NotScanned>' at last line of the file. See Build/Scripts/validateRstFiles.sh for allowed keywords"
-                outputFileToStream=1;
-            fi
-        fi
-
-        # Output filename in case any error was found
-        if [ $outputFileToStream == 1 ] ; then
-            FILE=${i/#typo3\/sysext\/core\/Documentation\/Changelog\//}
-            let COUNT++
-            printf "%-10s | %-12s | %-17s | %s \n" "$INCLUDE" "$REFERENCE" "$INDEX" "$FILE";
-            if ! [[ -z ${include_message} ]] ; then
-            echo ${include_message};
-            fi
-            if ! [[ -z ${reference_message} ]] ; then
-            echo ${reference_message};
-            fi
-            if ! [[ -z ${index_message} ]] ; then
-            echo ${index_message};
-            fi
-        fi
-    fi
-
-done
-if [[ $COUNT > 0 ]]; then
-     >&2 echo "Found $COUNT rst files with errors, check full log for details.";
-     exit 1;
-   else
-     exit 0;
-fi
index 8b04201..0eca083 100644 (file)
@@ -469,7 +469,7 @@ abstract public class AbstractCoreSpec {
                     .interpreter(ScriptTaskProperties.Interpreter.BINSH_OR_CMDEXE)
                     .inlineBody(
                         this.getScriptTaskBashInlineBody() +
-                        "./Build/Scripts/validateRstFiles.sh"
+                        "./Build/Scripts/validateRstFiles.php"
                     ),
                 new ScriptTask()
                     .description("Run path length check")