Skip to content

Commit 7622734

Browse files
haszihaszi
andauthored
Add file modification history update script (#121)
* Add file modification history update script * Make documentation and history file paths command line arguments --------- Co-authored-by: haszi <[email protected]>
1 parent 642cf7b commit 7622734

File tree

1 file changed

+219
-0
lines changed

1 file changed

+219
-0
lines changed

scripts/updateModHistory.php

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
<?php
2+
3+
$commandLineOptions = getopt("", ["docs-path:", "history-path::"]);
4+
5+
verifyCommandLineOptions($commandLineOptions);
6+
7+
$documentationPath = realpath($commandLineOptions["docs-path"]);
8+
$modHistoryFile = realpath($commandLineOptions["history-path"]);
9+
10+
$runningInGithubActions = (getenv("GITHUB_ACTIONS") !== false);
11+
12+
$head = $runningInGithubActions ? "\$GITHUB_SHA" : "HEAD";
13+
14+
$modHistoryArray = [];
15+
if (file_exists($modHistoryFile)) {
16+
echo timeStamp() . " - Loading modification history file... ";
17+
$modHistoryArray = include $modHistoryFile;
18+
if (!is_array($modHistoryArray)) {
19+
echo "file is corrupted (not an array)\n";
20+
exit(1);
21+
}
22+
echo "done\n";
23+
} else {
24+
echo timeStamp() . " - Modification history file doesn't exist\n";
25+
}
26+
27+
echo timeStamp() . " - Switching to documentation directory... ";
28+
chdir($documentationPath);
29+
echo "done\n";
30+
31+
if (isset($modHistoryArray["last commit hash"]) && $modHistoryArray["last commit hash"] !== "") {
32+
echo timeStamp() . " - Found last commit hash: " . $modHistoryArray["last commit hash"] . "\n";
33+
echo timeStamp() . " - Retrieving hash of the common ancestor of HEAD and the last commit... ";
34+
$cmd = "git merge-base " . $modHistoryArray["last commit hash"] . " $head";
35+
if (exec($cmd, $commonAncestor, $exitCode) === false
36+
|| $exitCode > 0) {
37+
echo "failed\n";
38+
exit(1);
39+
}
40+
$commonAncestorHash = implode("", $commonAncestor);
41+
echo "done: ";
42+
} else {
43+
echo timeStamp() . " - Last commit hash not found. Using empty git tree hash: ";
44+
// since there is no modification history, generate it for all commits since the inital one
45+
// 4b825dc642cb6eb9a060e54bf8d69288fbee4904 is the SHA1 of the empty git tree
46+
$commonAncestorHash = "4b825dc642cb6eb9a060e54bf8d69288fbee4904";
47+
}
48+
echo $commonAncestorHash . "\n";
49+
50+
echo timeStamp() . " - Retrieving number of files with a diff... ";
51+
$cmd = "git diff --name-only $commonAncestorHash $head | wc -l";
52+
if (exec($cmd, $numOfFilesWithDiff, $exitCode) === false
53+
|| $exitCode > 0) {
54+
echo "failed\n";
55+
exit(1);
56+
}
57+
$numOfFilesWithDiff = implode("", $numOfFilesWithDiff);
58+
echo "done (" . $numOfFilesWithDiff . ")\n";
59+
60+
if ($numOfFilesWithDiff === "0") {
61+
echo timeStamp() . " - No changes since last commit. Exiting...\n";
62+
exit(0);
63+
}
64+
65+
$modifiedFilescommand = <<<COMMAND
66+
#!/usr/bin/env bash
67+
echo "last commit hash:"
68+
echo "$(git rev-parse $head)"
69+
git diff --name-only $commonAncestorHash $head | while read -r filename; do
70+
echo "filename:"
71+
echo "\$filename"
72+
echo "modified:"
73+
echo "$(git log -1 --format='%aI' -- \$filename)"
74+
echo "contributors:"
75+
git log --format='%an' -- \$filename|awk '!a[$0]++'
76+
done
77+
COMMAND;
78+
79+
echo timeStamp() . " - Retrieving commit authors and last commit date/time of modified files... \n";
80+
81+
$modifiedFiles = [];
82+
83+
$proc = popen($modifiedFilescommand, 'rb');
84+
while (($line = fgets($proc)) !== false) {
85+
processGitDiffLine(rtrim($line, "\n\r"), $modifiedFiles);
86+
if (! $runningInGithubActions) {
87+
$fileCounter = max(count($modifiedFiles) - 1, 0);
88+
fwrite(
89+
STDERR,
90+
sprintf("\033[0G{$fileCounter} of {$numOfFilesWithDiff} files read...", "", "")
91+
);
92+
}
93+
}
94+
pclose($proc);
95+
96+
echo " done\n";
97+
98+
$s = ($modifiedFiles > 2) ? "s" : "";
99+
echo timeStamp() . " - Retrieved author$s and last commit date$s/time$s for " . (count($modifiedFiles) - 1) . " file$s\n";
100+
if (count($modifiedFiles) === 1) {
101+
// there will always be at least 1 entry with the last commit hash
102+
exit(1);
103+
}
104+
105+
$mergedModHistory = array_merge($modHistoryArray, $modifiedFiles);
106+
107+
echo timeStamp() . " - Writing modification history file... ";
108+
109+
$fp = fopen($modHistoryFile, "w");
110+
fwrite($fp, "<?php\n\n/* This is a generated file */\n\nreturn [\n");
111+
foreach ($mergedModHistory as $fileName => $fileProps) {
112+
if ($fileName === "last commit hash") {
113+
fwrite($fp, " \"last commit hash\" => \"" . implode("", $fileProps) . "\",\n");
114+
continue;
115+
}
116+
$newModHistoryString = ' "' . $fileName . "\" => [\n";
117+
$newModHistoryString .= " \"modified\" => \"" . ($fileProps["modified"] ?? "") . "\",\n";
118+
$newModHistoryString .= " \"contributors\" => [\n";
119+
if (isset($fileProps["contributors"])) {
120+
if (!is_array($fileProps["contributors"])) {
121+
exit("Non-array contributors list\n");
122+
}
123+
foreach ($fileProps["contributors"] as $contributor) {
124+
$newModHistoryString .= " \"" . $contributor . "\",\n";
125+
}
126+
}
127+
$newModHistoryString .= " ],\n";
128+
$newModHistoryString .= " ],\n";
129+
fwrite($fp, $newModHistoryString);
130+
}
131+
fwrite($fp, "];\n");
132+
fclose($fp);
133+
134+
echo "done at " . date('H:i:s') . "\n";
135+
136+
function timeStamp(): string {
137+
return "[" . date('H:i:s') . "]";
138+
}
139+
140+
function processGitDiffLine($line, &$modifiedFiles): void {
141+
static $currentType = "";
142+
static $currentFile = "";
143+
144+
switch ($line) {
145+
case "filename:":
146+
$currentType = "filename";
147+
return;
148+
case "modified:":
149+
$currentType = "modDateTime";
150+
return;
151+
case "contributors:":
152+
$currentType = "contributors";
153+
return;
154+
case "last commit hash:":
155+
$currentType = "commitHash";
156+
return;
157+
}
158+
if ($currentType === "") {
159+
return;
160+
}
161+
162+
switch ($currentType) {
163+
case "filename":
164+
$currentFile = $line;
165+
break;
166+
case "modDateTime":
167+
if ($currentFile === "") {
168+
return;
169+
}
170+
$modifiedFiles[$currentFile]["modified"] = $line;
171+
break;
172+
case "contributors":
173+
if ($currentFile === "") {
174+
return;
175+
}
176+
$modifiedFiles[$currentFile]["contributors"][] = htmlspecialchars($line, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401);
177+
break;
178+
case "commitHash":
179+
$modifiedFiles["last commit hash"][] = $line;
180+
break;
181+
}
182+
}
183+
184+
function verifyCommandLineOptions($commandLineOptions): void {
185+
$output = timeStamp() . " - Parsing command line arguments... ";
186+
echo $output;
187+
if ($commandLineOptions === false
188+
|| !isset($commandLineOptions["docs-path"])) {
189+
echo "\"--docs-path\" is a required argument\n";
190+
exit(1);
191+
}
192+
echo "documentation path supplied\n";
193+
if (isset($commandLineOptions["history-path"])) {
194+
printf("%*smod history file path supplied\n", strlen($output), " ");
195+
}
196+
197+
$output = timeStamp() . " - Verifying command line arguments... ";
198+
echo $output;
199+
if (!file_exists($commandLineOptions["docs-path"])) {
200+
echo "documentation path \"" . $commandLineOptions["docs-path"] . "\" doesn't exist\n";
201+
exit(1);
202+
} else if (!is_dir($commandLineOptions["docs-path"])) {
203+
echo "documentation path \"" . $commandLineOptions["docs-path"] . "\" is not a directory\n";
204+
exit(1);
205+
}
206+
echo "documentation path verified\n";
207+
208+
if (isset($commandLineOptions["history-path"])) {
209+
printf("\n%*smod history file path ", strlen($output), " ");
210+
if (!file_exists($commandLineOptions["history-path"])) {
211+
echo "\"" . $commandLineOptions["history-path"] . "\" doesn't exist\n";
212+
exit(1);
213+
} else if (!is_file($commandLineOptions["history-path"])) {
214+
echo "\"" . $commandLineOptions["history-path"] . "\" is not a file\n";
215+
exit(1);
216+
}
217+
echo "verified\n";
218+
}
219+
}

0 commit comments

Comments
 (0)