Skip to content

Commit 2f09ace

Browse files
committed
Add LinuxToolCheck
1 parent d3b0f5d commit 2f09ace

File tree

1 file changed

+147
-0
lines changed

1 file changed

+147
-0
lines changed
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace StaticPHP\Doctor\Item;
6+
7+
use StaticPHP\Attribute\Doctor\CheckItem;
8+
use StaticPHP\Attribute\Doctor\FixItem;
9+
use StaticPHP\Doctor\CheckResult;
10+
use StaticPHP\Exception\EnvironmentException;
11+
use StaticPHP\Util\System\LinuxUtil;
12+
13+
class LinuxToolCheck
14+
{
15+
public const TOOLS_ALPINE = [
16+
'make', 'bison', 're2c', 'flex',
17+
'git', 'autoconf', 'automake', 'gettext-dev',
18+
'tar', 'unzip', 'gzip',
19+
'bzip2', 'cmake', 'gcc',
20+
'g++', 'patch', 'binutils-gold',
21+
'libtoolize', 'which',
22+
'patchelf',
23+
];
24+
25+
public const TOOLS_DEBIAN = [
26+
'make', 'bison', 're2c', 'flex',
27+
'git', 'autoconf', 'automake', 'autopoint',
28+
'tar', 'unzip', 'gzip', 'gcc', 'g++',
29+
'bzip2', 'cmake', 'patch',
30+
'xz', 'libtoolize', 'which',
31+
'patchelf',
32+
];
33+
34+
public const TOOLS_RHEL = [
35+
'perl', 'make', 'bison', 're2c', 'flex',
36+
'git', 'autoconf', 'automake',
37+
'tar', 'unzip', 'gzip', 'gcc', 'g++',
38+
'bzip2', 'cmake', 'patch', 'which',
39+
'xz', 'libtool', 'gettext-devel',
40+
'patchelf', 'file',
41+
];
42+
43+
public const TOOLS_ARCH = [
44+
'base-devel', 'cmake',
45+
];
46+
47+
private const PROVIDED_COMMAND = [
48+
'perl' => '/usr/share/perl5/FindBin.pm',
49+
'binutils-gold' => 'ld.gold',
50+
'base-devel' => 'automake',
51+
'gettext-devel' => 'gettextize',
52+
'gettext-dev' => 'gettextize',
53+
'perl-IPC-Cmd' => '/usr/share/perl5/vendor_perl/IPC/Cmd.pm',
54+
'perl-Time-Piece' => '/usr/lib64/perl5/Time/Piece.pm',
55+
];
56+
57+
/** @noinspection PhpUnused */
58+
#[CheckItem('if necessary tools are installed', limit_os: 'Linux', level: 999)]
59+
public function checkCliTools(): ?CheckResult
60+
{
61+
$distro = LinuxUtil::getOSRelease();
62+
63+
$required = match ($distro['dist']) {
64+
'alpine' => self::TOOLS_ALPINE,
65+
'redhat' => self::TOOLS_RHEL,
66+
'centos' => array_merge(self::TOOLS_RHEL, ['perl-IPC-Cmd', 'perl-Time-Piece']),
67+
'arch' => self::TOOLS_ARCH,
68+
default => self::TOOLS_DEBIAN,
69+
};
70+
$missing = [];
71+
foreach ($required as $package) {
72+
if (LinuxUtil::findCommand(self::PROVIDED_COMMAND[$package] ?? $package) === null) {
73+
$missing[] = $package;
74+
}
75+
}
76+
if (!empty($missing)) {
77+
return CheckResult::fail(implode(', ', $missing) . ' not installed on your system', 'install-linux-tools', [$distro, $missing]);
78+
}
79+
return CheckResult::ok();
80+
}
81+
82+
#[CheckItem('if cmake version >= 3.22', limit_os: 'Linux')]
83+
public function checkCMakeVersion(): ?CheckResult
84+
{
85+
$ver = get_cmake_version();
86+
if ($ver === null) {
87+
return CheckResult::fail('Failed to get cmake version');
88+
}
89+
if (version_compare($ver, '3.22.0') < 0) {
90+
return CheckResult::fail('cmake version is too low (' . $ver . '), please update it manually!');
91+
}
92+
return CheckResult::ok($ver);
93+
}
94+
95+
/** @noinspection PhpUnused */
96+
#[CheckItem('if necessary linux headers are installed', limit_os: 'Linux')]
97+
public function checkSystemOSPackages(): ?CheckResult
98+
{
99+
if (LinuxUtil::isMuslDist()) {
100+
// check linux-headers installation
101+
if (!file_exists('/usr/include/linux/mman.h')) {
102+
return CheckResult::fail('linux-headers not installed on your system', 'install-linux-tools', [LinuxUtil::getOSRelease(), ['linux-headers']]);
103+
}
104+
}
105+
return CheckResult::ok();
106+
}
107+
108+
#[FixItem('install-linux-tools')]
109+
public function fixBuildTools(array $distro, array $missing): bool
110+
{
111+
$install_cmd = match ($distro['dist']) {
112+
'ubuntu', 'debian', 'Deepin', 'neon' => 'apt-get install -y',
113+
'alpine' => 'apk add',
114+
'redhat' => 'dnf install -y',
115+
'centos' => 'yum install -y',
116+
'arch' => 'pacman -S --noconfirm',
117+
default => null,
118+
};
119+
if ($install_cmd === null) {
120+
// try family
121+
$family = explode(' ', strtolower($distro['family']));
122+
if (in_array('debian', $family)) {
123+
$install_cmd = 'apt-get install -y';
124+
} elseif (in_array('rhel', $family) || in_array('fedora', $family)) {
125+
$install_cmd = 'dnf install -y';
126+
} else {
127+
throw new EnvironmentException(
128+
"Current linux distro [{$distro['dist']}] does not have an auto-install script for packages yet.",
129+
'You can submit an issue to request support: https://github.com/crazywhalecc/static-php-cli/issues'
130+
);
131+
}
132+
}
133+
$prefix = '';
134+
if (($user = exec('whoami')) !== 'root') {
135+
$prefix = 'sudo ';
136+
logger()->warning("Current user ({$user}) is not root, using sudo for running command (may require password input)");
137+
}
138+
139+
$is_debian = LinuxUtil::isDebianDist();
140+
$to_install = $is_debian ? str_replace('xz', 'xz-utils', $missing) : $missing;
141+
// debian, alpine libtool -> libtoolize
142+
$to_install = str_replace('libtoolize', 'libtool', $to_install);
143+
shell()->exec($prefix . $install_cmd . ' ' . implode(' ', $to_install));
144+
145+
return true;
146+
}
147+
}

0 commit comments

Comments
 (0)