Skip to content

Instantly share code, notes, and snippets.

@klim2020
Forked from grey-dev-0/vqmod_create.php
Created April 8, 2022 18:42
Show Gist options
  • Save klim2020/17aaeae80a659a89c93b29376de0413b to your computer and use it in GitHub Desktop.
Save klim2020/17aaeae80a659a89c93b29376de0413b to your computer and use it in GitHub Desktop.
vQmod xml creation and merge from git diff output
<?php
// Creates vQmod xml file from git diff output stored in a text file "git.txt"
// NOTE: Works only with SINGLE line changes.
$diffs = fopen('diffs.txt', 'r');
$modifications = "<modification>";
$fileIsOpen = $operationIsOpen = $searchIsOpen = false;
while($line = fgets($diffs)){
if(preg_match('/^diff --git ([^ ]+) ([^ ]+)/', $line, $files)){
if($operationIsOpen){
$modifications .= "</operation>\n";
$operationIsOpen = false;
}
if($fileIsOpen)
$modifications .= "</file>\n";
$count = 1;
$files[2] = str_replace("\n", '', $files[2]);
$files[2] = str_replace('b/', '', $files[2], $count);
$modifications .= "<file path=\"$files[2]\" name=\"\" >\n";
$fileIsOpen = true;
for($i = 0; $i < 3; $i++)
fgets($diffs);
} elseif(preg_match('/^@@ /', $line)){
if($operationIsOpen)
$modifications .= "</operation>\n";
$modifications .= "<operation>\n";
$operationIsOpen = true;
} elseif(preg_match('/^-(.*)/', $line, $search)){
if(!$searchIsOpen){
$offset = 0;
$count = 1;
$toBeReplaced = str_replace('-', '', $search[0], $count)."\n";
$searchIsOpen = true;
} else
$offset += 1;
} elseif(preg_match('/^\+(.*)/', $line, $add)){
$count = 1;
$toBeAdded = str_replace('+', '', $add[0], $count)."\n";
if(isset($offset)){
for($i = 0; $i < $offset; $i++){
if(preg_match('/^\+(.*)/', fgets($diffs), $add))
$toBeAdded .= str_replace('+', '', $add[0], $count)."\n";
}
if(isset($toBeReplaced)){
$modifications .= '<search position="replace"'.(($offset > 0)? " offset=\"$offset\"" : '')
."><![CDATA[\n$toBeReplaced]]></search>\n<add><![CDATA[\n$toBeAdded]]></add>\n";
$searchIsOpen = false;
}
}
}
}
$modifications .= "</file></modification>";
fclose($diffs);
file_put_contents('mod.xml', $modifications);
<?php
// Merges the generated vQmod xml with another chosen by the user.
$originalXml = new DOMDocument();
$originalXml->loadXML(file_get_contents(__DIR__."/../vqmod/xml/$argv[1]"));
$modXml = new DOMDocument();
$modXml->loadXML(file_get_contents(__DIR__.'/mod.xml'));
$xpath = new DOMXPath($originalXml);
$files = $modXml->getElementsByTagName('file');
foreach($files as $file){
/**
* @var DOMElement $file
*/
$filename = $file->getAttribute('path');
$originalFile = $xpath->query("//file[@path='$filename']");
$newOperations = $file->getElementsByTagName('operation');
if($originalFile->length > 0){
foreach($newOperations as $operation){
/**
* @var DOMElement $operation
*/
$existingOperations = $originalFile->item(0)->getElementsByTagName('operation');
foreach($existingOperations as $existingOperation){
/**
* @var DOMElement $existingOperation
*/
if($operation->getElementsByTagName('search')->item(0)->textContent ==
$existingOperation->getElementsByTagName('search')->item(0)->textContent)
$existingOperation->parentNode->removeChild($existingOperation);
}
$originalFile->item(0)->appendChild($originalXml->importNode($operation, true));
}
} else{
$newFile = $originalXml->createElement('file');
$newFile->setAttribute('path', $filename);
$newFile->setAttribute('name', '');
foreach($newOperations as $operation)
$newFile->appendChild($originalXml->importNode($operation, true));
$originalXml->getElementsByTagName('modification')->item(0)->appendChild($newFile);
}
}
$originalXml->save(__DIR__."/../vqmod/xml/$argv[1]");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment