Completed
Push — dev ( ac6c81...67f8de )
by Antonio
03:26 queued 37s
created

GitHooksInstaller::removeGitHooks()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 17
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 17
ccs 0
cts 12
cp 0
rs 9.2
cc 4
eloc 9
nc 4
nop 2
crap 20
1
<?php
2
3
namespace Ams\Composer\GitHooks\Installer;
4
5
use Ams\Composer\GitHooks\Config;
6
use Ams\Composer\GitHooks\GitHooks;
7
use Ams\Composer\GitHooks\Plugin;
8
use Composer\Installer\LibraryInstaller;
9
use Composer\Package\PackageInterface;
10
use Composer\Repository\InstalledRepositoryInterface;
11
use Composer\Util\Silencer;
12
13
class GitHooksInstaller extends LibraryInstaller
14
{
15
    /**
16
     * @inheritdoc
17
     */
18 2
    public function supports($packageType)
19
    {
20 2
        return $packageType == Plugin::PACKAGE_TYPE;
21
    }
22
23
    /**
24
     * {@inheritDoc}
25
     */
26 View Code Duplication
    public function install(InstalledRepositoryInterface $repo, PackageInterface $package)
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
27
    {
28
        parent::install($repo, $package);
29
30
        $gitRootPath = realpath($this->getGitRootPath());
31
        if (!is_dir($gitRootPath) || !file_exists($gitRootPath)) {
32
            $this->io->writeError(sprintf('    <warning>Skipped installation of %s: Not a git repository found on "git-root" path %s</warning>', $package->getName(), $gitRootPath));
33
            return;
34
        }
35
36
        $originPath = $this->getInstallPath($package);
37
        $targetPath = $this->getGitHooksInstallPath();
38
39
        if ($this->io->isVerbose()) {
40
            $this->io->write(sprintf('    Installing git hooks from %s into %s', $originPath, $targetPath));
41
        }
42
43
        // throws exception if one of both paths doesn't exists or couldn't be created
44
        $this->filesystem->ensureDirectoryExists($originPath);
45
        $this->filesystem->ensureDirectoryExists($targetPath);
46
47
        $this->copyGitHooks($originPath, $targetPath);
48
    }
49
50
    /**
51
     * {@inheritDoc}
52
     */
53 View Code Duplication
    public function update(InstalledRepositoryInterface $repo, PackageInterface $initial, PackageInterface $target)
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
54
    {
55
        parent::update($repo, $initial, $target);
56
57
        $gitRootPath = realpath($this->getGitRootPath());
58
        if (!is_dir($gitRootPath)) {
59
            $this->io->writeError(sprintf('    <warning>Skipped update of %s: Not a git repository found on "git-root" path %s</warning>', $target->getName(), $gitRootPath));
60
            return;
61
        }
62
63
        $originPath = $this->getInstallPath($initial);
64
        $targetPath = $this->getGitHooksInstallPath();
65
66
        if ($this->io->isVerbose()) {
67
            $this->io->write(sprintf('    Updating git hooks from %s into %s', $originPath, $targetPath));
68
        }
69
70
        // throws exception if one of both paths doesn't exists or couldn't be created
71
        $this->filesystem->ensureDirectoryExists($originPath);
72
        $this->filesystem->ensureDirectoryExists($targetPath);
73
74
        $this->copyGitHooks($originPath, $targetPath, true);
75
    }
76
77
    /**
78
     * {@inheritDoc}
79
     */
80
    public function uninstall(InstalledRepositoryInterface $repo, PackageInterface $package)
81
    {
82
        parent::uninstall($repo, $package);
83
84
        $gitRootPath = realpath($this->getGitRootPath());
85
        if (!is_dir($gitRootPath)) {
86
            $this->io->writeError(sprintf('    Skipped update of %s: Not a git repository found on "git-root" path %s', $package->getName(), $gitRootPath));
87
            return;
88
        }
89
90
        $originPath = $this->getInstallPath($package);
91
        $targetPath = $this->getGitHooksInstallPath();
92
93
        if ($this->io->isVerbose()) {
94
            $this->io->write(sprintf('    Uninstalling git hooks from %s into %s', $originPath, $targetPath));
95
        }
96
97
        $this->removeGitHooks($originPath, $targetPath);
98
    }
99
100
    /**
101
     * @param string $sourcePath
102
     * @param string $targetPath
103
     * @param bool   $isUpdate
104
     */
105
    private function copyGitHooks($sourcePath, $targetPath, $isUpdate = false)
106
    {
107
        $i = new \FilesystemIterator($sourcePath);
108
109
        foreach ($i as $githook) {
110
            // ignore all files not matching a git hook name
111
            if (!array_search($githook->getFilename(), GitHooks::$hookFilename)) {
112
                continue;
113
            }
114
115
            $newPath = $targetPath . '/' . $githook->getFilename();
116
117
            // check if .sample version exists in that case rename it
118
            if (file_exists($newPath . GitHooks::SAMPLE)) {
119
                rename($newPath . GitHooks::SAMPLE, $newPath . GitHooks::SAMPLE . '.bk');
120
            }
121
122
            // check if there is already a git hook with same name do nothing
123
            if (file_exists($newPath) && !$isUpdate) {
124
                $this->io->write(sprintf('    Found already existing %s git hook. Doing nothing.', $githook->getFilename()));
125
                continue;
126
            }
127
128
            // if hook already exist but anything changed update it
129
            if (file_exists($newPath) && $isUpdate && sha1_file($githook->getPathname()) === sha1_file($newPath)) {
130
                continue;
131
            }
132
133
            $this->io->write(sprintf('    Installing git hook %s', $githook->getFilename()));
134
            $this->filesystem->relativeSymlink($githook->getPathname(), $newPath);
135
            Silencer::call('chmod', $newPath, 0777 & ~umask());
136
        }
137
    }
138
139
    /**
140
     * @param string $sourcePath
141
     * @param string $targetPath
142
     */
143
    private function removeGitHooks($sourcePath, $targetPath)
144
    {
145
        $i = new \FilesystemIterator($sourcePath);
146
147
        foreach ($i as $githook) {
148
            // ignore all files not matching a git hook name
149
            if (!array_search($githook->getFilename(), GitHooks::$hookFilename)) {
150
                continue;
151
            }
152
153
            $newPath = $targetPath . '/' . $githook->getFilename();
154
            if (file_exists($newPath)) {
155
                $this->io->write(sprintf('   Removing git hook %s', $githook->getFilename()));
156
                unlink($newPath);
157
            }
158
        }
159
    }
160
161
    /**
162
     * Returns the installation path of the Git hooks
163
     *
164
     * @return string
165
     */
166
    private function getGitHooksInstallPath()
167
    {
168
        return $this->getGitRootPath() . '/hooks';
169
    }
170
171
    /**
172
     * Returns the git root path
173
     *
174
     * @return string
175
     */
176
    private function getGitRootPath()
177
    {
178
        $config = $this->composer->getPackage()->getExtra();
179
        $relPath = array_key_exists(Config::GIT_ROOT_DIR_KEY, $config) ? ('/' . $config[Config::GIT_ROOT_DIR_KEY]) : '';
180
181
        return $this->vendorDir . $relPath . '/../.git';
182
    }
183
}
184