Passed
Push — stage ( f7313c...f5f9eb )
by Jon
07:29
created

Git::tagDir()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 13
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 7
nc 2
nop 3
1
<?php
2
3
/** Created by PhpStorm,  User: jonphipps,  Date: 2018-02-15,  Time: 4:19 PM */
4
5
namespace App\Services\Publish;
6
7
use App\Jobs\GenerateRdf;
8
use App\Models\Project;
9
use App\Models\Release;
10
use GitWrapper\GitException;
11
use GitWrapper\GitWorkingCopy;
12
use GitWrapper\GitWrapper;
13
use Illuminate\Support\Facades\Storage;
14
15
class Git
16
{
17
    /**
18
     * @param \App\Models\Project $project
19
     * @param                     $message
20
     * @param string              $disk
21
     *
22
     * @return void
23
     * @throws GitException
24
     */
25
    public static function commitDir(Project $project, $message, $disk = GenerateRdf::REPO_ROOT): void
26
    {
27
        $projectPath = self::getProjectPath($project->id);
28
        $dir         = Storage::disk($disk)->path($projectPath);
29
30
        /** @var GitWrapper $wrapper */
31
        $wrapper = static::getWrapper();
32
        $git     = $wrapper->workingCopy($dir);
33
34
        if ($git->hasChanges()) {
35
            $git->add('.');
36
            $git->commit($message);
37
        }
38
    }
39
40
    /**
41
     * @param \App\Models\Project $project
42
     * @param string              $disk
43
     *
44
     * @return void
45
     * @throws \League\Flysystem\RootViolationException
46
     * @throws GitException
47
     */
48
    public static function initDir(Project $project, $disk = GenerateRdf::REPO_ROOT): void
49
    {
50
        $projectPath = self::getProjectPath($project->id);
51
        $repo        = self::getProjectRepo($project);
52
        $dir         = Storage::disk($disk)->path($projectPath);
53
        /** @var GitWrapper $wrapper */
54
        $wrapper = static::getWrapper();
55
56
        //this is what happens when the working directory exists (published), but has never been synced with a github remote
57
        if (Storage::disk($disk)->exists($projectPath) && $repo) {
58
            $git = $wrapper->workingCopy($dir);
59
            if (empty($git->getRemotes())) {
60
                //todo: this is much too heavy-handed. There may be previously published vocabs that aren't being published now
61
                //delete the dir
62
                Storage::disk($disk)->deleteDir($projectPath);
0 ignored issues
show
Bug introduced by
The method deleteDir() does not exist on Illuminate\Contracts\Filesystem\Filesystem. Did you maybe mean delete()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

62
                Storage::disk($disk)->/** @scrutinizer ignore-call */ deleteDir($projectPath);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
63
            }
64
        }
65
        if (! Storage::disk($disk)->exists($projectPath)) {
66
            if ($repo) {
67
                $git = $wrapper->cloneRepository($repo, $dir);
68
                if (! $git->isCloned()) {
69
                    throw new GitException($git);
70
                }
71
            } else {
72
                Storage::disk($disk)->createDir($projectPath);
0 ignored issues
show
Bug introduced by
The method createDir() does not exist on Illuminate\Contracts\Filesystem\Filesystem. It seems like you code against a sub-type of said class. However, the method does not exist in Illuminate\Contracts\Filesystem\Cloud. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

72
                Storage::disk($disk)->/** @scrutinizer ignore-call */ createDir($projectPath);
Loading history...
73
                $wrapper->init($dir);
74
            }
75
        }
76
    }
77
78
    public static function getProjectPath(int $projectId): string
79
    {
80
        return GenerateRdf::PROJECT_ROOT . "/{$projectId}/";
81
    }
82
83
    public static function getProjectRepo(Project $project): ?string
84
    {
85
        $repo   = $project->repo;
86
        $access = '';
87
88
        if ($repo) {
89
            if (auth()->user()->githubToken) {
90
                $token    = auth()->user()->githubToken;
91
                $nickname = auth()->user()->nickname;
92
                $access   = "{$nickname}:{$token}@";
93
            }
94
95
            return "https://{$access}github.com/{$repo}.git";
96
        }
97
98
        return null;
99
    }
100
101
    /**
102
     * @return GitWrapper
103
     * @throws GitException
104
     */
105
    public static function getWrapper(): GitWrapper
106
    {
107
        try {
108
            $wrapper = new GitWrapper();
109
        }
110
        catch (GitException $e) {
111
            //we couldn't find the default and have to use the config
112
            $wrapper = new GitWrapper(config('app.git_executable'));
113
        }
114
115
        //$wrapper->setEnvVar('GIT_SSH_COMMAND', 'ssh -o StrictHostKeyChecking=no');
116
        return $wrapper;
117
    }
118
119
    /**
120
     * @param \App\Models\Project $project
121
     * @param                     $tag
122
     * @param string              $disk
123
     *
124
     * @return void
125
     */
126
    public static function tagDir(Project $project, $tag, $disk = GenerateRdf::REPO_ROOT)
127
    {
128
        $projectPath = self::getProjectPath($project->id);
129
        $dir         = Storage::disk($disk)->path($projectPath);
130
131
        /** @var GitWrapper $wrapper */
132
        $wrapper = static::getWrapper();
133
        $git     = $wrapper->workingCopy($dir);
134
135
        try {
136
            $git->tag($tag, '-f');
137
        }
138
        catch (GitException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
139
        }
140
    }
141
142
    /**
143
     * @param \App\Models\Release $release
144
     * @param string              $disk
145
     *
146
     * @return void
147
     * @throws \GitWrapper\GitException
148
     */
149
    public static function updateRemote(Release $release, $disk = GenerateRdf::REPO_ROOT): void
150
    {
151
        $projectId   = $release->project_id;
152
        $tag         = $release->tag_name;
0 ignored issues
show
Unused Code introduced by
The assignment to $tag is dead and can be removed.
Loading history...
153
        $projectPath = self::getProjectPath($projectId);
154
        $dir         = Storage::disk($disk)->path($projectPath);
155
156
        /** @var GitWrapper $wrapper */
157
        $wrapper = static::getWrapper();
158
        $git     = $wrapper->workingCopy($dir);
159
160
        try {
161
            if ($git->hasRemote('origin')) {
162
                self::pushToGitHub($git);
163
            }
164
        }
165
        catch (GitException $e) {
166
            if (str_contains($e->getMessage(), 'fatal: No such remote')) {
167
                $repo = $release->project->repo;
168
                if ($repo) {
169
                    $url = 'https://github.com/' . $repo . '.git';
170
                    $git->addRemote('origin', $url);
171
                    self::pushToGitHub($git);
172
                }
173
            }
174
        }
175
    }
176
177
    /**
178
     * @param $git
179
     *
180
     * @throws \GitWrapper\GitException
181
     */
182
    private static function pushToGitHub(GitWorkingCopy $git): void
183
    {
184
        $git->push('origin', 'master');
185
    }
186
}
187