-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature #101 Use git last commit date for a file as default last modi…
…fied date (ogizanagi) This PR was squashed before being merged into the 0.x-dev branch. Discussion ---------- Use git last commit date for a file as default last modified date Fixes #98⚠️ small BC inside => use `\DateTimeInterface` or `\DateTimeImmutable` on your model objects, since this processor now returns a `DateTimeImmutable` now (before was `\DateTime`). Commits ------- 4d87d57 Use a consistent file order for the fs provider, independent from fs 324c8d2 Extract git last modified fetcher e3d1acb Use DateTimeImmutable 41fcd86 Use git last commit date for a file as default last modified date
- Loading branch information
Showing
10 changed files
with
306 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the "StenopePHP/Stenope" bundle. | ||
* | ||
* @author Thomas Jarrand <[email protected]> | ||
*/ | ||
|
||
namespace Stenope\Bundle\Service\Git; | ||
|
||
use Psr\Log\LoggerInterface; | ||
use Psr\Log\NullLogger; | ||
use Symfony\Component\Process\Exception\ProcessFailedException; | ||
use Symfony\Component\Process\Process; | ||
use Symfony\Contracts\Service\ResetInterface; | ||
|
||
class LastModifiedFetcher implements ResetInterface | ||
{ | ||
/** Git executable path on the system / PATH used to get the last commit date for the file, or null to disable. */ | ||
private ?string $gitPath; | ||
private LoggerInterface $logger; | ||
|
||
private static ?bool $gitAvailable = null; | ||
|
||
public function __construct( | ||
?string $gitPath = 'git', | ||
?LoggerInterface $logger = null | ||
) { | ||
$this->gitPath = $gitPath; | ||
$this->logger = $logger ?? new NullLogger(); | ||
} | ||
|
||
/** | ||
* @throws ProcessFailedException | ||
*/ | ||
public function __invoke(string $filePath): ?\DateTimeImmutable | ||
{ | ||
if (null === $this->gitPath || false === self::$gitAvailable) { | ||
// Don't go further if the git command is not available or the git feature is disabled | ||
return null; | ||
} | ||
|
||
$executable = explode(' ', $this->gitPath); | ||
|
||
if (null === self::$gitAvailable) { | ||
// Check once if the git command is available | ||
$process = new Process([...$executable, '--version']); | ||
$process->run(); | ||
|
||
if (!$process->isSuccessful()) { | ||
self::$gitAvailable = false; | ||
|
||
$this->logger->warning('Git was not found at path "{gitPath}". Check the binary path is correct or part of your PATH.', [ | ||
'gitPath' => $this->gitPath, | ||
'output' => $process->getOutput(), | ||
'err_output' => $process->getErrorOutput(), | ||
]); | ||
|
||
return null; | ||
} | ||
|
||
self::$gitAvailable = true; | ||
} | ||
|
||
$process = new Process([...$executable, 'log', '-1', '--format=%cd', '--date=iso', $filePath]); | ||
$process->run(); | ||
|
||
if (!$process->isSuccessful()) { | ||
throw new ProcessFailedException($process); | ||
} | ||
|
||
if ($output = $process->getOutput()) { | ||
return new \DateTimeImmutable(trim($output)); | ||
} | ||
|
||
return null; | ||
} | ||
|
||
public function reset(): void | ||
{ | ||
self::$gitAvailable = null; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the "StenopePHP/Stenope" bundle. | ||
* | ||
* @author Thomas Jarrand <[email protected]> | ||
*/ | ||
|
||
namespace Stenope\Bundle\Tests\Unit\Processor; | ||
|
||
use PHPUnit\Framework\TestCase; | ||
use Prophecy\Argument; | ||
use Prophecy\PhpUnit\ProphecyTrait; | ||
use Stenope\Bundle\Content; | ||
use Stenope\Bundle\Processor\LastModifiedProcessor; | ||
use Stenope\Bundle\Provider\Factory\LocalFilesystemProviderFactory; | ||
use Stenope\Bundle\Service\Git\LastModifiedFetcher; | ||
|
||
class LastModifiedProcessorTest extends TestCase | ||
{ | ||
use ProphecyTrait; | ||
|
||
public function testFromContent(): void | ||
{ | ||
$processor = new LastModifiedProcessor('lastModified'); | ||
|
||
$data = []; | ||
$content = new Content('slug', 'type', 'content', 'format', new \DateTimeImmutable('2021-06-14 10:25:47 +0200')); | ||
|
||
$processor->__invoke($data, $content); | ||
|
||
self::assertInstanceOf(\DateTimeImmutable::class, $data['lastModified']); | ||
self::assertEquals($content->getLastModified(), $data['lastModified']); | ||
} | ||
|
||
public function testFromGit(): void | ||
{ | ||
$gitFetcher = $this->prophesize(LastModifiedFetcher::class); | ||
$gitFetcher->__invoke(Argument::type('string')) | ||
->willReturn($expectedDate = new \DateTimeImmutable('2021-05-10 10:00:00 +0000')) | ||
->shouldBeCalledOnce() | ||
; | ||
|
||
$processor = new LastModifiedProcessor('lastModified', $gitFetcher->reveal()); | ||
|
||
$data = []; | ||
$content = new Content('slug', 'type', 'content', 'format', new \DateTimeImmutable('2021-06-14 10:25:47 +0200'), new \DateTimeImmutable(), [ | ||
'provider' => LocalFilesystemProviderFactory::TYPE, | ||
'path' => 'some-path.md', | ||
]); | ||
|
||
$processor->__invoke($data, $content); | ||
|
||
self::assertInstanceOf(\DateTimeImmutable::class, $data['lastModified']); | ||
self::assertEquals($expectedDate, $data['lastModified']); | ||
} | ||
|
||
public function testWontUseGitOnNonFilesProvider(): void | ||
{ | ||
$gitFetcher = $this->prophesize(LastModifiedFetcher::class); | ||
$gitFetcher->__invoke(Argument::type('string'))->shouldNotBeCalled(); | ||
|
||
$processor = new LastModifiedProcessor('lastModified', $gitFetcher->reveal()); | ||
|
||
$data = []; | ||
$content = new Content('slug', 'type', 'content', 'format', new \DateTimeImmutable('2021-06-14 10:25:47 +0200')); | ||
|
||
$processor->__invoke($data, $content); | ||
|
||
self::assertInstanceOf(\DateTimeImmutable::class, $data['lastModified']); | ||
self::assertEquals($content->getLastModified(), $data['lastModified']); | ||
} | ||
} |
Oops, something went wrong.