Skip to content

Commit

Permalink
fix: create symlink when current symlink in .git/hooks folder is broken
Browse files Browse the repository at this point in the history
When upgrading from the old package, the .git/hooks folders contains broken symlinks to the removed old package location.
This PR makes sure the user does not manually need to remove these broken symlinks.
  • Loading branch information
aadmathijssen committed Jan 23, 2024
1 parent 3d56af3 commit 0b757a4
Showing 1 changed file with 29 additions and 7 deletions.
36 changes: 29 additions & 7 deletions src/GitHooks.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use function readlink;
use function sprintf;
use function symlink;
use function unlink;

class GitHooks
{
Expand Down Expand Up @@ -85,13 +86,9 @@ private function symlinkHooks(): void
$link = sprintf('%s/%s/%s', $this->projectRoot, self::GIT_HOOKS_DIRECTORY, $hook);
$relativeTarget = $this->fileSystem->getRelativePath($link, $target);

if (!is_link($link) && !file_exists($link)) {
symlink(
$relativeTarget,
$link
);
$this->setExecutablePermission($link);
$this->logger->info(sprintf('Created symlink %s -> %s', $link, $relativeTarget));
if (!file_exists($link)) {
$this->removeSymlink($link);
$this->createSymlink($link, $relativeTarget);
} elseif (!is_link($link) || readlink($link) === false || readlink($link) !== $relativeTarget) {
$this->logger->warning(sprintf('Git hook %s already exists, not using project hooks. ' .
'Consider moving your custom hook to %s.', $link, self::PROJECT_HOOKS_DIRECTORY));
Expand All @@ -107,6 +104,31 @@ private function createProjectDefaultHookDirectories(): void
}
}

private function removeSymlink(string $link): void
{
if (!is_link($link)) {
return;
}
$linkTarget = readlink($link);
if (unlink($link)) {
$this->logger->info(
sprintf('Removed symlink %s -> %s', $link, ($linkTarget !== false) ? $linkTarget : '(unknown)')
);
} else {
$this->logger->warning(sprintf('Could not remove symlink %s', $link));
}
}

private function createSymlink(string $link, string $relativeTarget): void
{
if (symlink($relativeTarget, $link)) {
$this->logger->info(sprintf('Created symlink %s -> %s', $link, $relativeTarget));
$this->setExecutablePermission($link);
} else {
$this->logger->warning(sprintf('Could not create symlink %s -> %s', $link, $relativeTarget));
}
}

private function setExecutablePermission(string $filepath): bool
{
if (chmod($filepath, 0755) === false) {
Expand Down

0 comments on commit 0b757a4

Please sign in to comment.