Completed
Pull Request — master (#9)
by ANTHONIUS
02:26
created

CommandContext::loadPharAutoload()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 15
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 15
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 10
nc 3
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the dotfiles project.
7
 *
8
 *     (c) Anthonius Munthi <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Dotfiles\Behat\Context;
15
16
use Behat\Behat\Context\Context;
17
use Symfony\Component\Console\Helper\DebugFormatterHelper;
18
use Symfony\Component\Console\Output\OutputInterface;
19
use Symfony\Component\Console\Output\StreamOutput;
20
use Symfony\Component\Dotenv\Dotenv;
21
use Symfony\Component\Process\Process;
22
use Webmozart\Assert\Assert;
23
24
class CommandContext implements Context
25
{
26
    private $commandPrefix;
27
28
    private $output;
29
30
    private $stream;
31
32
    public function __construct(string $commandPrefix)
33
    {
34
        $this->commandPrefix = $commandPrefix;
35
    }
36
37
    /**
38
     * @BeforeSuite
39
     *
40
     * @throws \Exception when not in docker environment
41
     */
42
    public static function beforeSuite(): void
43
    {
44
        if (!is_file('/.dockerenv')) {
45
            throw new \Exception('You must run behat test in docker-environment');
46
        }
47
48
        static::loadDotEnv();
49
        static::loadPharAutoload();
50
    }
51
52
    /**
53
     * @Given I execute add command with :exec argument
54
     * @Given I execute add command with :exec
55
     *
56
     * @param string $path
57
     */
58
    public function iExecuteAddCommand(string $path): void
59
    {
60
        $this->resetStream();
61
        $this->runCommand('add '.$path);
62
    }
63
64
    /**
65
     * @Given I execute restore command
66
     */
67
    public function iExecuteRestoreCommand(): void
68
    {
69
        $this->resetStream();
70
        $this->runCommand('restore');
71
    }
72
73
    /**
74
     * @Then I should see :text
75
     */
76
    public function iShouldSee($text): void
77
    {
78
        rewind($this->output->getStream());
79
        $display = stream_get_contents($this->output->getStream());
80
        //$display = str_replace(PHP_EOL, "\n", $display);
81
        Assert::contains($display, $text);
82
    }
83
84
    private static function loadDotEnv(): void
85
    {
86
        putenv('DOTFILES_TEMP_DIR='.sys_get_temp_dir().'/dotfiles');
87
        $files = array(
88
            __DIR__.'/../Resources/default.env',
89
        );
90
91
        if (is_file($file = getenv('HOME').'/.dotfiles_profile')) {
92
            $files[] = $file;
93
        }
94
95
        $env = new Dotenv();
96
        foreach ($files as $file) {
97
            $env->load($file);
98
        }
99
    }
100
101
    private static function loadPharAutoload(): void
102
    {
103
        if (false !== ($pharFile = getenv('DOTFILES_PHAR_FILE'))) {
0 ignored issues
show
Unused Code introduced by
The assignment to $pharFile is dead and can be removed.
Loading history...
104
            $path = realpath(__DIR__.'/../build/dotfiles.phar');
105
            $phar = 'phar://'.$path;
106
107
            $autoloadFile = $phar.'/vendor/autoload.php';
108
            $contents = file_get_contents($autoloadFile);
109
110
            $pattern = '/ComposerAutoloaderInit[a-z|0-9]+/im';
111
            preg_match($pattern, $contents, $matches);
112
            $class = $matches[0];
113
114
            if (!class_exists($class)) {
115
                include_once $autoloadFile;
116
            }
117
        }
118
    }
119
120
    private function resetStream(): void
121
    {
122
        if (is_resource($this->stream)) {
123
            fclose($this->stream);
124
        }
125
        $this->stream = fopen('php://memory', 'w');
126
        $this->output = new StreamOutput($this->stream);
0 ignored issues
show
Bug introduced by
It seems like $this->stream can also be of type false; however, parameter $stream of Symfony\Component\Consol...amOutput::__construct() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

126
        $this->output = new StreamOutput(/** @scrutinizer ignore-type */ $this->stream);
Loading history...
127
        $this->output->setVerbosity(OutputInterface::VERBOSITY_DEBUG);
128
    }
129
130
    private function runCommand($command): void
131
    {
132
        $cmd = $this->commandPrefix.' -vvv '.$command;
133
        $output = $this->output;
134
        $helper = new DebugFormatterHelper();
135
136
        $process = new Process($cmd, getcwd());
137
        $process->run(function ($type, $buffer) use ($output,$helper,$process): void {
138
            $contents = $helper->start(
139
                spl_object_hash($process),
140
                $buffer,
141
                Process::ERR === $type
142
            );
143
            $output->writeln($contents);
144
        });
145
    }
146
}
147