Skip to content

Commit

Permalink
Command line tool for XML sync testing between languages: attributes (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
alfsb authored Feb 6, 2025
1 parent 07b4806 commit 1768961
Show file tree
Hide file tree
Showing 8 changed files with 611 additions and 1 deletion.
4 changes: 3 additions & 1 deletion configure.php
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,7 @@ function getFileModificationHistory(): array {
$ac["TRANSLATION_ONLY_INCL_END"] = "-->";
}
checkvalue($ac['LANG']);
file_put_contents( __DIR__ . "/temp/lang" , $ac['LANG'] );

checking("whether the language is supported");
$LANGDIR = "{$ac['rootdir']}/{$ac['LANG']}";
Expand Down Expand Up @@ -850,8 +851,9 @@ function dom_saveload( DOMDocument $dom , string $filename = "" ) : string

if ( dom_load( $dom , "{$ac['srcdir']}/{$ac["INPUT_FILENAME"]}" ) )
{
echo "1 ";
dom_saveload( $dom ); // correct file/line/column on error messages
echo "done.\n";
echo "2 done.\n";
}
else
{
Expand Down
142 changes: 142 additions & 0 deletions scripts/translation/libqa/OutputBuffer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
<?php /*
+----------------------------------------------------------------------+
| Copyright (c) 1997-2025 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| https://www.php.net/license/3_01.txt. |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net, so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: André L F S Bacci <ae php.net> |
+----------------------------------------------------------------------+
# Description
This class caches formatted output, and calculates if this output is not
previously marked as ignored, before printing it. */

class OutputBuffer
{
private string $filename = "";
private string $header = "";
private array $matter = [];
private array $footer = [];

private OutputIgnore $ignore;
private string $options;

public function __construct( string $header , string $filename , OutputIgnore $ignore )
{
$filename = str_replace( "/./" , "/" , $filename );

$this->header = $header . ": " . $filename . "\n\n";
$this->filename = $filename;
$this->ignore = $ignore;

$copy = $ignore->residualArgv;
array_shift( $copy );
$this->options = implode( " " , $copy );
}

public function add( string $text )
{
$this->matter[] = $text;
}

public function addDiff( string $text , int $sourceCount , int $targetCount )
{
if ( $sourceCount == $targetCount )
return;
$prefix = "* ";
$suffix = " -{$targetCount} +{$sourceCount}";
if ( $sourceCount == 0 )
{
$prefix = "- ";
$suffix = $targetCount == 1 ? "" : " -{$targetCount}";
}
if ( $targetCount == 0 )
{
$prefix = "+ ";
$suffix = $sourceCount == 1 ? "" : " +{$sourceCount}";
}
$this->add( "{$prefix}{$text}{$suffix}\n" );
}

public function addFooter( string $text )
{
$this->footer[] = $text;
}

public function addLine()
{
if ( count( $this->matter ) > 0 && end( $this->matter ) != "\n" )
$this->add( "\n" );
}

public function print( bool $useAlternatePrinting = false )
{
if ( count( $this->matter ) == 0 && count( $this->footer ) == 0 )
return;

$hashHead = $this->hash( false );
$hashFull = $this->hash( true );

if ( $this->ignore->shouldIgnore( $this , $this->filename , $hashHead , $hashFull ) )
return;

print $this->header;

if ( $useAlternatePrinting )
$this->printMatterAlternate();
else
foreach( $this->matter as $text )
print $text;

if ( count( $this->matter ) )
print "\n";

foreach( $this->footer as $text )
print $text;

if ( count( $this->footer ) )
print "\n";
}

private function printMatterAlternate() : void
{
$add = array();
$del = array();
$rst = array();

foreach( $this->matter as $text )
{
if ( $text[0] == '+' ) $add[] = $text;
elseif ( $text[0] == '-' ) $del[] = $text;
else $rst[] = $text;
}

for ( $idx = 0 ; $idx < count( $this->matter ) ; $idx++ )
{
if ( isset( $add[ $idx ] ) ) print $add[ $idx ];
if ( isset( $del[ $idx ] ) ) print $del[ $idx ];
}

foreach( $rst as $text )
print $text;
}

private function hash( bool $withContents ) : string
{
$text = $this->header . $this->options;
if ( $withContents )
$text .= implode( "" , $this->matter );
$text = str_replace( " " , "" , $text );
$text = str_replace( "\n" , "" , $text );
$text = str_replace( "\r" , "" , $text );
$text = str_replace( "\t" , "" , $text );
return hash( "crc32b" , $text );
}
}
124 changes: 124 additions & 0 deletions scripts/translation/libqa/OutputIgnore.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
<?php /*
+----------------------------------------------------------------------+
| Copyright (c) 1997-2025 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| https://www.php.net/license/3_01.txt. |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net, so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: André L F S Bacci <ae php.net> |
+----------------------------------------------------------------------+
# Description
This class process commands for ignoring outputs, and complement non
ignored outputs with these commands. */

class OutputIgnore
{
public array $residualArgv;

private bool $appendIgnores = true;
private bool $showIgnore = true;
private string $filename = ".syncxml.ignores";
private string $argv0 = "";

public function __construct( array & $argv )
{
$this->argv0 = escapeshellarg( $argv[0] );

foreach( $argv as $key => $arg )
{
if ( str_starts_with( $arg , "--add-ignore=" ) )
{
$list = $this->loadIgnores();
$line = substr( $arg , 13 );
if ( ! in_array( $line , $list ) )
{
$list[] = $line;
$this->saveIgnores( $list );
}
exit;
}

if ( str_starts_with( $arg , "--del-ignore=" ) )
{
$list = $this->loadIgnores();
$line = substr( $arg , 13 );
$dels = 0;
while ( in_array( $line , $list ) )
{
$key = array_search( $line , $list );
unset( $list[$key] );
$dels++;
}
if ( $dels == 0 )
print "Ignore mark not found.\n";
else
$this->saveIgnores( $list );
exit;
}

if ( $arg == "--disable-ignore" )
{
$this->showIgnore = false;
unset( $argv[$key] );
}
}

$this->residualArgv = $argv;
}

private function loadIgnores()
{
if ( ! file_exists( $this->filename ) )
return [];
$data = file_get_contents( $this->filename );
return unserialize( gzdecode( $data ) );
}

public function saveIgnores( $data )
{
$contents = gzencode( serialize( $data ) );
file_put_contents( $this->filename , $contents );
}

public function shouldIgnore( OutputBuffer $output , string $filename , string $hashHeader , string $hashMatter )
{
$ret = false;

$prefix = "{$filename}:{$hashHeader}:";
$ignore = "{$filename}:{$hashHeader}:{$hashMatter}";
$marks = $this->loadIgnores();

// --add-ignore command

if ( in_array( $ignore , $marks ) )
$ret = true; // is already ignored
else //
if ( $this->showIgnore ) // show add command
$output->addFooter( " php {$this->argv0} --add-ignore=$ignore\n" );

// Remove valid ignores, leaves outdated ones for listing

while ( in_array( $ignore , $marks ) )
{
$key = array_search( $ignore , $marks );
unset( $marks[$key] );
}

// --del-ignore command

if ( $this->showIgnore ) // show del commands (for this file/prefix)
foreach ( $marks as $mark )
if ( $mark != null )
if ( str_starts_with( $mark , $prefix ) )
$output->addFooter( " php {$this->argv0} --del-ignore=$mark\n" );

return $ret;
}
}
27 changes: 27 additions & 0 deletions scripts/translation/libqa/SyncFileItem.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php /*
+----------------------------------------------------------------------+
| Copyright (c) 1997-2025 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| https://www.php.net/license/3_01.txt. |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net, so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: André L F S Bacci <ae php.net> |
+----------------------------------------------------------------------+
# Description
Holds file related data for synq XML tools. */

require_once __DIR__ . '/all.php';

class SyncFileItem
{
public string $sourceDir;
public string $targetDir;
public string $file;
}
65 changes: 65 additions & 0 deletions scripts/translation/libqa/SyncFileList.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php /*
+----------------------------------------------------------------------+
| Copyright (c) 1997-2025 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| https://www.php.net/license/3_01.txt. |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net, so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: André L F S Bacci <ae php.net> |
+----------------------------------------------------------------------+
# Description
Generates (and caches) the list of files with TranslatedOk status. */

require_once __DIR__ . '/all.php';

class SyncFileList
{
static function load()
{
$file = __DIR__ . "/../../../temp/lang";
if ( ! file_exists( $file ) )
{
fwrite( STDERR , "Language file not found, run 'doc-base/configure.php'.\n" );
exit();
}

$lang = trim( file_get_contents( $file ) );
$cache = __DIR__ . "/../../../temp/$lang.oklist";

if ( file_exists( $cache ) )
{
$data = file_get_contents( $cache );
return unserialize( gzdecode( $data ) );
}

require_once __DIR__ . '/../lib/all.php';

$revcheck = new RevcheckRun( 'en' , $lang );
$revdata = $revcheck->revData;
$list = [];

foreach( $revdata->fileDetail as $file )
{
if ( $file->status != RevcheckStatus::TranslatedOk )
continue;

$item = new SyncFileItem();
$item->sourceDir = $revcheck->sourceDir;
$item->targetDir = $revcheck->targetDir;
$item->file = $file->path . '/' . $file->name;
$list[] = $item;
}

$contents = gzencode( serialize( $list ) );
file_put_contents( $cache , $contents );

return $list;
}
}
Loading

0 comments on commit 1768961

Please sign in to comment.