/
LastCommitTimeTask.php
144 lines (125 loc) · 4.4 KB
/
LastCommitTimeTask.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
<?php
declare(strict_types=1);
namespace SetBased\Phing\Task;
use SetBased\Helper\ProgramExecution;
/**
* Phing task for set the mtime of (source) file to the latest commit time in Git.
*/
class LastCommitTimeTask extends SetBasedTask
{
//--------------------------------------------------------------------------------------------------------------------
/**
* The number of sources files found.
*
* @var int
*/
private int $count = 0;
/**
* Array with last commit time for each file.
*
* @var array
*/
private array $lastCommitTimes = [];
/**
* The parent directory under which the mtime of (source) files must be set.
*
* @var string
*/
private string $workDirName;
//--------------------------------------------------------------------------------------------------------------------
/**
* Main method of this task.
*/
public function main()
{
$this->logInfo("Preserving last commit time under directory %s", $this->workDirName);
$this->fetchAllFilesUnderGit();
$this->fetchLastCommitTimes();
$this->setFilesMtime();
$this->logInfo("Found %d files", $this->count);
}
//--------------------------------------------------------------------------------------------------------------------
/**
* Setter for XML attribute dir.
*
* @param string $workDirName The name of the working directory.
*/
public function setDir(string $workDirName): void
{
$this->workDirName = $workDirName;
}
//--------------------------------------------------------------------------------------------------------------------
/**
* Fetches all files that are currently under git.
*/
private function fetchAllFilesUnderGit(): void
{
$command = ['git', 'ls-files'];
[$output, $return] = ProgramExecution::exec1($command, null);
if ($return!=0) $this->logError("Can not execute command %s ", implode(' ', $command));
foreach ($output as $filename)
{
$this->lastCommitTimes[$filename] = 0;
}
}
//--------------------------------------------------------------------------------------------------------------------
/**
* Fetches last commit time of each file in the Git repository.
*/
private function fetchLastCommitTimes(): void
{
// Execute command for get list with file name and mtime from GIT log.
$command = ['git', 'log', '--format=format:%ai', '--name-only'];
[$output, $return] = ProgramExecution::exec1($command, null);
if ($return!=0) $this->logError("Can not execute command %s in exec", implode(' ', $command));
// Find latest mtime for each file from $output.
// Note: Each line is either:
// * an empty line
// * a timestamp
// * a filename.
$commit_date = '';
foreach ($output as $line)
{
if ((preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} [+\-]\d{4}$/', $line)))
{
$commit_date = strtotime($line);
}
else if ($line!=='')
{
$filename = $line;
if (isset($this->lastCommitTimes[$filename]) && $this->lastCommitTimes[$filename]<$commit_date)
{
$this->lastCommitTimes[$filename] = $commit_date;
}
}
}
}
//--------------------------------------------------------------------------------------------------------------------
/**
* Set last commit time to all files in build directory.
*/
private function setFilesMtime(): void
{
$files = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->workDirName,
\FilesystemIterator::UNIX_PATHS));
foreach ($files as $full_path => $file)
{
if ($file->isFile())
{
$key = substr($full_path, strlen($this->workDirName.'/'));
if (isset($this->lastCommitTimes[$key]))
{
$this->logVerbose("Set mtime of %s to %s", $full_path, date('Y-m-d H:i:s', $this->lastCommitTimes[$key]));
$success = touch($full_path, $this->lastCommitTimes[$key]);
if (!$success)
{
$this->logError("Unable to set mtime of file %s", $full_path);
}
$this->count++;
}
}
}
}
//--------------------------------------------------------------------------------------------------------------------
}
//----------------------------------------------------------------------------------------------------------------------