Build   A
last analyzed

Complexity

Total Complexity 37

Size/Duplication

Total Lines 181
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 37
eloc 87
c 1
b 0
f 0
dl 0
loc 181
rs 9.44

11 Methods

Rating   Name   Duplication   Size   Complexity  
A getPackage() 0 3 1
A prepareSaveLog() 0 11 5
A appendPkgConfigureOptions() 0 21 5
A packLog() 0 16 5
A getLog() 0 15 5
A runCommand() 0 21 4
A log() 0 6 1
A getLogFilename() 0 13 5
A saveLog() 0 12 3
A fixEol() 0 9 2
A __construct() 0 5 1
1
<?php
2
3
/*
4
 * Pickle
5
 *
6
 *
7
 * @license
8
 *
9
 * New BSD License
10
 *
11
 * Copyright © 2015-2015, Pickle community. All rights reserved.
12
 *
13
 * Redistribution and use in source and binary forms, with or without
14
 * modification, are permitted provided that the following conditions are met:
15
 *     * Redistributions of source code must retain the above copyright
16
 *       notice, this list of conditions and the following disclaimer.
17
 *     * Redistributions in binary form must reproduce the above copyright
18
 *       notice, this list of conditions and the following disclaimer in the
19
 *       documentation and/or other materials provided with the distribution.
20
 *     * Neither the name of the Hoa nor the names of its contributors may be
21
 *       used to endorse or promote products derived from this software without
22
 *       specific prior written permission.
23
 *
24
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE
28
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34
 * POSSIBILITY OF SUCH DAMAGE.
35
 */
36
37
namespace Pickle\Base\Abstracts\Package;
38
39
use Exception;
40
use Pickle\Base\Archive;
41
use Pickle\Base\Interfaces;
42
use Pickle\Base\Interfaces\Package;
43
use Pickle\Base\Util\FileOps;
44
45
abstract class Build
46
{
47
    use FileOps;
48
49
    protected $pkg;
50
51
    protected $options;
52
53
    protected $log = [];
54
55
    protected $cwdBack;
56
57
    public function __construct(Package $pkg, $options = null)
58
    {
59
        $this->pkg = $pkg;
60
        $this->options = $options;
61
        $this->cwdBack = getcwd();
62
    }
63
64
    /**
65
     * @param int $level
66
     * @param string $msg
67
     */
68
    public function log($level, $msg, $hint = '')
69
    {
70
        $this->log[] = [
71
            'level' => $level,
72
            'msg' => $msg,
73
            'hint' => $hint,
74
        ];
75
    }
76
77
    public function getLog($hint = null)
78
    {
79
        $ret = [];
80
81
        foreach ($this->log as $item) {
82
            if (isset($hint) && $hint !== $item['hint']) {
83
                continue;
84
            }
85
            $tmp = explode("\n", $item['msg']);
86
            foreach ($tmp as $ln) {
87
                $ret[] = $item['level'] . ': ' . $ln;
88
            }
89
        }
90
91
        return implode("\n", $ret);
92
    }
93
94
    public function saveLog($path)
95
    {
96
        $logs = [];
97
        $def_fl = null;
98
99
        $this->prepareSaveLog($path, $def_fl);
100
101
        foreach ($this->log as $item) {
102
            $fname = $this->getLogFilename($path, $item, $def_fl, $logs);
103
104
            if (file_put_contents($fname, "{$item['msg']}\n", FILE_APPEND) != strlen($item['msg']) + 1) {
105
                throw new Exception("Couldn't write contents to '{$fname}'");
106
            }
107
        }
108
    }
109
110
    /* zip is default */
111
    public function packLog($path)
112
    {
113
        $zipperClass = Archive\Factory::getZipperClassName();
114
        $zip = new $zipperClass($path, Interfaces\Archive\Zipper::FLAG_CREATE_OVERWRITE);
115
        /** @var \Pickle\Base\Interfaces\Archive\Zipper $zip */
116
        $no_hint_logs = '';
117
        foreach ($this->log as $item) {
118
            $msg = $this->fixEol($item['msg']);
119
            if ((isset($item['hint']) && !empty($item['hint']))) {
120
                $zip->addFromString("{$item['hint']}.log", $msg);
121
            } else {
122
                $no_hint_logs = "{$no_hint_logs}\n\n{$msg}";
123
            }
124
        }
125
        if ($no_hint_logs) {
126
            $zip->addFromString('build.log', $this->fixEol($item['msg']));
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $item seems to be defined by a foreach iteration on line 117. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
127
        }
128
    }
129
130
    public function getPackage()
131
    {
132
        return $this->pkg;
133
    }
134
135
    protected function prepareSaveLog($path, &$def_fl)
136
    {
137
        if ($path && !is_dir($path)) {
138
            if (!mkdir($path)) {
139
                throw new EXception("Location '{$path}' could not be created, unable to save build logs");
140
            }
141
        }
142
143
        $def_fl = $path . DIRECTORY_SEPARATOR . 'build.log';
144
        if (file_exists($def_fl)) {
145
            unlink($def_fl);
146
        }
147
    }
148
149
    protected function getLogFilename($path, $log_item, $def_fl, array &$logs)
150
    {
151
        $is_hint = (isset($log_item['hint']) && !empty($log_item['hint']));
152
        $fname = $is_hint ? $path . DIRECTORY_SEPARATOR . "{$log_item['hint']}.log" : $def_fl;
153
154
        if (!in_array($fname, $logs)) {
155
            if (file_exists($fname)) {
156
                unlink($fname);
157
            }
158
            $logs[] = $fname;
159
        }
160
161
        return $fname;
162
    }
163
164
    protected function fixEol($s)
165
    {
166
        if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
167
            $ret = preg_replace(",(?!\r)\n,", "\r\n", $s);
168
        } else {
169
            $ret = $s;
170
        }
171
172
        return $ret;
173
    }
174
175
    /**
176
     * @param string $command
177
     *
178
     * @throws Exception
179
     *
180
     * @return bool
181
     */
182
    protected function runCommand($command)
183
    {
184
        $hint = basename(strtok($command, " \n"));
185
186
        $this->log(1, $command, $hint);
187
        $pp = popen("{$command} 2>&1", 'r');
188
        if (!$pp) {
0 ignored issues
show
introduced by
$pp is of type resource, thus it always evaluated to false.
Loading history...
189
            throw new Exception(
190
                'Failed to run the following command: ' . $command
191
            );
192
        }
193
194
        $out = [];
195
        while ($line = fgets($pp, 1024)) {
196
            $out[] = rtrim($line);
197
        }
198
        $this->log(2, implode("\n", $out), $hint);
199
200
        $exitCode = is_resource($pp) ? pclose($pp) : -1;
201
202
        return $exitCode === 0;
203
    }
204
205
    protected function appendPkgConfigureOptions(&$configureOptions)
206
    {
207
        $opt = $this->pkg->getConfigureOptions();
208
        if (isset($opt[$this->pkg->getName()])) {
209
            $extEnableOption = $opt[$this->pkg->getName()];
210
            if ($extEnableOption->type == 'enable') {
211
                $confOption = '--enable-' . $this->pkg->getName() . '=shared';
212
            } else {
213
                $confOption = '--with-' . $this->pkg->getName() . '=shared';
214
            }
215
            $configureOptions = $confOption . ' ' . $configureOptions;
216
        } else {
217
            $name = str_replace('_', '-', $this->pkg->getName());
218
            if (isset($opt[$name])) {
219
                $extEnableOption = $opt[$name];
220
                if ($extEnableOption->type == 'enable') {
221
                    $confOption = '--enable-' . $name . '=shared';
222
                } else {
223
                    $confOption = '--with-' . $name . '=shared';
224
                }
225
                $configureOptions = $confOption . ' ' . $configureOptions;
226
            }
227
        }
228
    }
229
}
230
231
/* vim: set tabstop=4 shiftwidth=4 expandtab: fdm=marker */
232