Skip to content

Commit 45c0bbb

Browse files
committed
Add a helper script to clean up deleted phrases
Closes #6493
1 parent deec333 commit 45c0bbb

File tree

2 files changed

+163
-0
lines changed

2 files changed

+163
-0
lines changed

extra/_generateDeletedPhrases.php

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
<?php
2+
3+
namespace wcf\extra;
4+
5+
if (\PHP_SAPI !== 'cli') {
6+
exit(1);
7+
}
8+
9+
// This code makes a few assumptions about the appearance of the XML file for
10+
// the sake of simplicity.
11+
//
12+
// It’s also the most awful way to edit XML but enables us to generate the
13+
// <delete> block without messing with any (manual) formatting currently
14+
// present.
15+
//
16+
// Most important, this generates small diffs by only touching the parts that
17+
// actually change.
18+
19+
if ($argc !== 2) {
20+
echo "Usage: {$argv[0]} <pathname>\n";
21+
echo "\tPayload expected via stdin\n";
22+
exit(1);
23+
}
24+
25+
$pathname = $argv[1];
26+
27+
$data = \file_get_contents('php://stdin');
28+
29+
// The data received from stdin is the old branch.
30+
$xml = getXmlFromData($data);
31+
$expectedIdentifiers = getIdentifiers($xml);
32+
33+
$data = \file_get_contents($pathname);
34+
$xml = getXmlFromData($data);
35+
$actualIdentifiers = getIdentifiers($xml);
36+
37+
$missingIdentifiers = \array_diff($expectedIdentifiers, $actualIdentifiers);
38+
39+
$hasDeleteBlock = $xml->xpath('/ns:language/ns:delete');
40+
\assert(\is_array($hasDeleteBlock));
41+
$hasDeleteBlock = $hasDeleteBlock !== [];
42+
43+
if ($missingIdentifiers === [] && $hasDeleteBlock) {
44+
return;
45+
}
46+
47+
$noIndentation = \substr_count($data, "\n<import>\n");
48+
$indented = \substr_count($data, "\n\t<import>\n");
49+
50+
if (($noIndentation !== 1 && $indented !== 1) || $noIndentation === $indented) {
51+
echo "Unable to determine the indentation of <import>, found {$noIndentation}/{$indented} (not indented/indented)!\n";
52+
exit(1);
53+
}
54+
55+
$indentation = $noIndentation ? "" : "\t";
56+
57+
\sort($missingIdentifiers, \SORT_NATURAL);
58+
$missingIdentifiers = \array_map(
59+
static fn($identifier) => "{$indentation}\t<item name=\"{$identifier}\"/>",
60+
$missingIdentifiers
61+
);
62+
63+
if ($hasDeleteBlock) {
64+
// Find the position of {$indentation}<delete> and {$indentation}</delete>
65+
$startTag = "\n{$indentation}<delete>\n";
66+
$start = \mb_strpos($data, $startTag);
67+
$endTag = "\n{$indentation}</delete>\n";
68+
$end = \mb_strpos($data, $endTag);
69+
70+
if ($start === false || $end === false) {
71+
echo "Could not find the start and end positions.\n";
72+
exit(1);
73+
}
74+
75+
$before = \mb_substr($data, 0, $start + \mb_strlen($startTag));
76+
$after = \mb_substr($data, $end);
77+
78+
\file_put_contents("{$pathname}", $before . \implode("\n", $missingIdentifiers) . $after);
79+
} else {
80+
// Find the position of the closing {$indentation}</import>
81+
$endTag = "\n{$indentation}</import>\n";
82+
$end = \mb_strpos($data, $endTag);
83+
84+
if ($end === false) {
85+
echo "Could not find the end position.\n";
86+
exit(1);
87+
}
88+
89+
$before = \mb_substr($data, 0, $end + \mb_strlen($endTag));
90+
$after = \mb_substr($data, $end + \mb_strlen($endTag));
91+
92+
$deleteStart = "{$indentation}<delete>\n";
93+
$deleteEnd = "\n{$indentation}</delete>\n";
94+
95+
\file_put_contents("{$pathname}", $before . $deleteStart . \implode("\n", $missingIdentifiers) . $deleteEnd . $after);
96+
}
97+
98+
/**
99+
* @return list<string>
100+
*/
101+
function getIdentifiers(\SimpleXMLElement $xml): array
102+
{
103+
$identifiers = [];
104+
foreach ($xml->xpath('/ns:language/ns:import/ns:category/ns:item') as $item) {
105+
foreach ($item->attributes() as $name => $value) {
106+
if ($name === 'name') {
107+
$identifiers[] = (string)$value;
108+
break;
109+
}
110+
}
111+
}
112+
113+
\assert($identifiers !== []);
114+
115+
return $identifiers;
116+
}
117+
118+
function getXmlFromData(string $data): \SimpleXMLElement
119+
{
120+
$xml = \simplexml_load_string($data);
121+
\assert($xml !== false);
122+
123+
$xml->registerXPathNamespace('ns', 'http://www.woltlab.com');
124+
125+
return $xml;
126+
}

extra/generateDeletedPhrases.sh

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
6+
7+
if [[ "$#" -ne 3 ]]; then
8+
echo "$0 <repository> <fromBranch> <toBranch>"
9+
exit 1
10+
fi
11+
12+
REPOSITORY=$(echo "$1" |sed 's#[^/]$#&/#')
13+
FROM_BRANCH="$2"
14+
TO_BRANCH="$3"
15+
16+
if [[ ! -d "${REPOSITORY}.git/" ]]; then
17+
echo "The directory ${REPOSITORY} is not a git repository."
18+
exit 1
19+
fi
20+
21+
if [[ -d "${REPOSITORY}com.woltlab.wcf/" ]]; then
22+
DIRECTORY="${REPOSITORY}wcfsetup/install/lang/"
23+
else
24+
DIRECTORY="${REPOSITORY}language/"
25+
fi
26+
27+
ABSOLUTE_PATH=$(realpath "${DIRECTORY}")
28+
29+
pushd "${DIRECTORY}" > /dev/null
30+
31+
for FILENAME in *.xml; do
32+
php "${SCRIPT_DIR}/_generateDeletedPhrases.php" "${ABSOLUTE_PATH}/${FILENAME}" <<< $(git show "${FROM_BRANCH}:./${FILENAME}")
33+
done
34+
35+
popd > /dev/null
36+
37+
echo "Done"

0 commit comments

Comments
 (0)