Skip to content

Commit

Permalink
Merge 4a74bfd into ecd056d
Browse files Browse the repository at this point in the history
  • Loading branch information
siad007 authored Apr 5, 2021
2 parents ecd056d + 4a74bfd commit 2783423
Show file tree
Hide file tree
Showing 7 changed files with 131 additions and 23 deletions.
15 changes: 15 additions & 0 deletions build/build-file-linter.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="build-file-linter" default="lint" basedir=".">

<fileset id="build-files" dir="..">
<include name="**/build.xml"/>
</fileset>

<target name="lint">
<xmllint haltonfailure="false"
schema="../etc/phing-grammar.rng"
useRNG="true"
><fileset refid="build-files"/></xmllint>
</target>

</project>
1 change: 0 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@
"require-dev": {
"ext-curl": "*",
"ext-iconv": "*",
"ext-json": "*",
"ext-pdo_sqlite": "*",
"ext-simplexml": "*",
"roave/security-advisories": "dev-master",
Expand Down
11 changes: 5 additions & 6 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion etc/default.tasks.properties
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,11 @@ pdo=Phing\Task\System\Pdo\PDOSQLExecTask
pdosqlexec=Phing\Task\System\Pdo\PDOSQLExecTask
pharpackage=Phing\Task\System\PharPackageTask
phardata=Phing\Task\System\PharDataTask
xmllint=Phing\Task\System\XmlLintTask
xmlproperty=Phing\Task\System\XmlPropertyTask

; "ext" tasks
mail=Phing\Task\Optional\MailTask
xmllint=Phing\Task\Optional\XmlLintTask
jsllint=Phing\Task\Optional\JslLintTask
phpcs=Phing\Task\Optional\PhpCSTask
patch=Phing\Task\Optional\PatchTask
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
* <http://phing.info>.
*/

namespace Phing\Task\Optional;
namespace Phing\Task\System;

use DOMDocument;
use Phing\Exception\BuildException;
Expand All @@ -45,15 +45,16 @@ class XmlLintTask extends Task
/**
* File to be performed syntax check on.
*/
public function setFile(File $file)
public function setFile(File $file): void
{
$this->file = $file;
}

/**
* XML Schema Description file to validate against.
* @param File $schema
*/
public function setSchema(File $schema)
public function setSchema(File $schema): void
{
$this->schema = $schema;
}
Expand All @@ -63,15 +64,16 @@ public function setSchema(File $schema)
*
* @param bool $bool
*/
public function setUseRNG($bool)
public function setUseRNG(bool $bool): void
{
$this->useRNG = (bool) $bool;
$this->useRNG = $bool;
}

/**
* Sets the haltonfailure attribute.
* @param bool $haltonfailure
*/
public function setHaltonfailure(bool $haltonfailure)
public function setHaltonfailure(bool $haltonfailure): void
{
$this->haltonfailure = $haltonfailure;
}
Expand All @@ -85,10 +87,11 @@ public function setHaltonfailure(bool $haltonfailure)
*/
public function main()
{
libxml_use_internal_errors(true);
if (isset($this->schema) && !file_exists($this->schema->getPath())) {
throw new BuildException('Schema file not found: ' . $this->schema->getPath());
}
if (!isset($this->file) and 0 == count($this->filesets)) {
if (!isset($this->file) && 0 === count($this->filesets)) {
throw new BuildException("Missing either a nested fileset or attribute 'file' set");
}

Expand Down Expand Up @@ -118,7 +121,7 @@ public function main()
* @param int $line
* @param mixed $context
*/
public function errorHandler($level, $message, $file, $line, $context)
public function errorHandler($level, $message, $file, $line, $context): void
{
$matches = [];
preg_match('/^.*\(\): (.*)$/', $message, $matches);
Expand All @@ -130,7 +133,7 @@ public function errorHandler($level, $message, $file, $line, $context)
*
* @throws BuildException
*/
protected function logError($message)
protected function logError($message): void
{
if ($this->haltonfailure) {
throw new BuildException($message);
Expand All @@ -144,33 +147,34 @@ protected function logError($message)
*
* @param string $file
*/
protected function lint($file)
protected function lint($file): void
{
if (file_exists($file)) {
if (is_readable($file)) {
$dom = new DOMDocument();
if (false === $dom->load($file)) {
$error = libxml_get_last_error();
$this->libxmlGetErrors();
$this->logError($file . ' is not well-formed (See messages above)');
} else {
if (isset($this->schema)) {
if ($this->useRNG) {
if ($dom->relaxNGValidate($this->schema->getPath())) {
$this->log($file . ' validated with RNG grammar', Project::MSG_INFO);
$this->log($file . ' validated with RNG grammar');
} else {
$this->libxmlGetErrors();
$this->logError($file . ' fails to validate (See messages above)');
}
} else {
if ($dom->schemaValidate($this->schema->getPath())) {
$this->log($file . ' validated with schema', Project::MSG_INFO);
$this->log($file . ' validated with schema');
} else {
$this->libxmlGetErrors();
$this->logError($file . ' fails to validate (See messages above)');
}
}
} else {
$this->log(
$file . ' is well-formed (not validated due to missing schema specification)',
Project::MSG_INFO
$file . ' is well-formed (not validated due to missing schema specification)'
);
}
}
Expand All @@ -181,4 +185,41 @@ protected function lint($file)
$this->logError('File not found: ' . $file);
}
}

private function libxmlGetErrors(): void
{
$errors = libxml_get_errors();
foreach ($errors as $error) {
[$severity, $message] = $this->libxmlGetError($error);
$this->log($message, $severity === 'error' ? Project::MSG_ERR : Project::MSG_WARN);
}
libxml_clear_errors();
}

private function libxmlGetError($error): array
{
$return = '';
$severity = '';
switch ($error->level) {
case LIBXML_ERR_WARNING:
$return .= "Warning $error->code: ";
$severity = 'warn';
break;
case LIBXML_ERR_ERROR:
$return .= "Error $error->code: ";
$severity = 'error';
break;
case LIBXML_ERR_FATAL:
$return .= "Fatal Error $error->code: ";
$severity = 'error';
break;
}
$return .= trim($error->message);
if ($error->file) {
$return .= " in $error->file";
}
$return .= " on line $error->line";

return [$severity, $return];
}
}
41 changes: 41 additions & 0 deletions tests/Phing/Task/System/XmlLintTaskTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

/**
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/

namespace Phing\Test\Task\System;

use Phing\Test\Support\BuildFileTest;

/**
* Tests the XmlLint Task.
*
* @author Siad Ardroumli <siad.ardroumli@gmail.com>
*/
class XmlLintTaskTest extends BuildFileTest
{
public function setUp(): void
{
$this->configureProject(PHING_TEST_BASE . '/etc/tasks/system/XmlLintTaskTest.xml');
}

public function testXml(): void
{
$this->expectLogContaining(__FUNCTION__, 'validation end');
}
}
13 changes: 13 additions & 0 deletions tests/etc/tasks/system/XmlLintTaskTest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="XmlLintTaskTest" default="testXml" basedir=".">

<target name="testXml">
<xmllint haltonfailure="false"
schema="../../../../etc/phing-grammar.rng"
file="${phing.file}"
useRNG="true"
/>
<echo msg="validation end"/>
</target>

</project>

0 comments on commit 2783423

Please sign in to comment.