Completed
Push — master ( 492e98...69b246 )
by Basil
03:16
created

EnvController::getGitWrapper()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
cc 2
eloc 5
nc 2
nop 0
1
<?php
2
3
namespace luya\dev;
4
5
use Curl\Curl;
6
use GitWrapper\GitWrapper;
7
use yii\console\widgets\Table;
8
use yii\console\Markdown;
9
use yii\helpers\Console;
10
11
/**
12
 * Dev Env cloning and updating.
13
 * 
14
 * Provdes functions to clone and update the repos.
15
 * 
16
 * @author Basil Suter <[email protected]>
17
 */
18
class EnvController extends BaseDevCommand
19
{
20
    public $repos = [
21
        'luya',
22
        'luya-module-admin',
23
        'luya-module-cms',
24
    ];
25
    
26
    public $text = <<<EOT
27
28
**CLONE REPOS**
29
30
We've detected that you don't have all module repos forked to your account. You can only push changes to the forked repos, all others are **READ ONLY**.
31
32
If you want to work on a specific repo, make sure that repo is forked to your Github account.
33
34
You can also skip this command, fork the repos and rerun this command again.
35
36
**FORK ME**
37
EOT;
38
    
39
    private $_gitWrapper;
40
    
41
    /**
42
     * @return \GitWrapper\GitWrapper
43
     */
44
    protected function getGitWrapper()
45
    {
46
        if ($this->_gitWrapper === null) {
47
            $this->_gitWrapper = new GitWrapper();
48
            $this->_gitWrapper->setTimeout(300);
49
        }
50
        
51
        return $this->_gitWrapper;
52
    }
53
    
54
    private function summaryItem($repo, $isFork, $exists)
55
    {
56
        return [$repo, $exists, $isFork];
57
    }
58
    
59
    private function getFilesystemRepoPath($repo)
60
    {
61
        return 'repos' . DIRECTORY_SEPARATOR . $repo;
62
    }
63
64
    private function forkExists($username, $repo)
65
    {
66
        return (new Curl())->get('https://api.github.com/repos/'.$username.'/'.$repo)->isSuccess(); 
67
    }
68
    
69
    private function markdown($text, $paragraph = false)
70
    {
71
        $parser = new Markdown();
72
        
73
        if ($paragraph) {
74
            return $parser->parseParagraph($text);
75
        }
76
        
77
        return $parser->parse($text);
78
    }
79
    
80
    public function actionInit()
81
    {
82
        // username
83
        $username = $this->getConfig('username');
84
        if (!$username) {
85
            $username = $this->prompt('Whats your Github username?');
86
            $this->saveConfig('username', $username);
87
        }
88
        
89
        // clonetype
90
        $cloneType = $this->getConfig('cloneType');
91
        if (!$cloneType) {
92
            $cloneType = $this->select('Are you connected via ssh or https?', ['ssh' => 'ssh', 'http' => 'http']);
93
            $this->saveConfig('cloneType', $cloneType);
94
        }
95
        
96
        $summary = [];
97
        $itemWithoutFork = false;
98
        
99
        // generate summary overview
100
        foreach ($this->repos as $repo) {
101
            $newRepoHome = $this->getFilesystemRepoPath($repo);
102
            if (file_exists($newRepoHome . DIRECTORY_SEPARATOR . '.git')) {
103
                $summary[] = $this->summaryItem($repo, false, true);
104
            } elseif ($this->forkExists($username, $repo)) {
105
                $summary[] = $this->summaryItem($repo, true, false);
106
            } else {
107
                $itemWithoutFork = true;
108
                $summary[] = $this->summaryItem($repo, false, false);
109
            }
110
        }
111
        
112
        if ($itemWithoutFork) {
113
            Console::clearScreen();
114
            $this->outputInfo($this->markdown($this->text));
115
            foreach ($summary as $sum) {
116
                if (!$sum[2] && !$sum[1]) {
117
                    $this->outputInfo($this->markdown("**{$sum[0]}**: https://github.com/luyadev/{$sum[0]}/fork", true));
118
                }
119
            }
120
            echo (new Table())->setHeaders(['Repo', 'Already initialized', 'Fork exists'])->setRows($summary)->run();
121
            $this->outputError("Repos without fork detected. Those repos will be initialized as READ ONLY. It means you can not push any changes to them.");
122
            
123
            if (!$this->confirm("Continue?")) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->confirm('Continue?') of type boolean|null is loosely compared to false; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.

If an expression can have both false, and null as possible values. It is generally a good practice to always use strict comparison to clearly distinguish between those two values.

$a = canBeFalseAndNull();

// Instead of
if ( ! $a) { }

// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
Loading history...
124
                return $this->outputError('Abort by User.');
125
            }
126
        }
127
        
128
        // foreach summary and clone
0 ignored issues
show
Unused Code Comprehensibility introduced by
38% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
129
        foreach ($summary as $sum) {
130
            $repo = $sum[0];
131
            $hasFork = $sum[2];
132
            $exists = $sum[1];
133
            
134
            // continue already initialized repos.
135
            if ($exists) {
136
                continue;
137
            }
138
            
139
            $newRepoHome = $this->getFilesystemRepoPath($repo);
140
            
141
            if ($hasFork) {
142
                $cloneUrl = ($cloneType == 'ssh') ? "[email protected]:{$username}/{$repo}.git" : "https://github.com/{$username}/{$repo}.git";
143
            } else {
144
                $cloneUrl = ($cloneType == 'ssh') ? "[email protected]:luyadev/{$repo}.git" : "https://github.com/{$username}/{$repo}.git";
145
            }
146
            
147
            $this->cloneRepo($repo, $cloneUrl, $newRepoHome);
148
        }
149
        
150
        return $this->outputSuccess("init complete.");
151
    }
152
    
153
    private function cloneRepo($repo, $cloneUrl, $newRepoHome)
154
    {
155
        $this->outputSuccess("{$repo}: cloning ...");
156
        $this->getGitWrapper()->cloneRepository($cloneUrl, $newRepoHome);
157
        $this->getGitWrapper()->git('remote add upstream https://github.com/luyadev/'.$repo.'.git',  $newRepoHome);
158
        $this->outputSuccess("{$repo}: ✔ complete");
159
    }
160
    
161
    public function actionUpdate()
162
    {
163
        $wrapper = new GitWrapper();
164
        
165
        foreach ($this->repos as $repo) {
166
            $wrapper->git('checkout master',  'repos' . DIRECTORY_SEPARATOR . $repo);
167
            $this->outputInfo("{$repo}: checkout master ✔");
168
            
169
            $wrapper->git('fetch upstream',  'repos' . DIRECTORY_SEPARATOR . $repo);
170
            $this->outputInfo("{$repo}: fetch upstream ✔");
171
            
172
            $wrapper->git('rebase upstream/master master',  'repos' . DIRECTORY_SEPARATOR . $repo);
173
            $this->outputInfo("{$repo}: rebase master ✔");
174
        }
175
    }
176
}
177