mirror of
https://github.com/lkddi/nexusphp.git
synced 2026-04-14 12:30:49 +08:00
[update] auto download source code
This commit is contained in:
@@ -53,7 +53,10 @@ class Test extends Command
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
|
||||
$time = '2021-06-16T04:03:35Z';
|
||||
$date = Carbon::parse($time);
|
||||
$date->tz = 'Asia/Shanghai';
|
||||
dd($date->toDateTimeString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -287,16 +287,19 @@ class Install
|
||||
$table = '<div class="table w-full text-left">';
|
||||
$table .= '<div class="table-row-group">';
|
||||
$table .= '<div class="table-row">';
|
||||
foreach ($header as $value) {
|
||||
$table .= '<div class="table-cell bg-gray-400 text-gray-700 px-4 py-2">' . $value . '</div>';
|
||||
foreach ($header as $text) {
|
||||
$table .= '<div class="table-cell bg-gray-400 text-gray-700 px-4 py-2">' . $text . '</div>';
|
||||
}
|
||||
$table .= '</div>';
|
||||
foreach ($data as $value) {
|
||||
$table .= '<div class="table-row">';
|
||||
$table .= '<div class="table-cell bg-gray-200 text-gray-700 px-4 py-2 text-sm">' . $value['label'] . '</div>';
|
||||
$table .= '<div class="table-cell bg-gray-200 text-gray-700 px-4 py-2 text-sm">' . $value['required'] . '</div>';
|
||||
$table .= '<div class="table-cell bg-gray-200 text-gray-700 px-4 py-2 text-sm">' . $value['current'] . '</div>';
|
||||
$table .= '<div class="table-cell bg-' . ($value['result'] == 'YES' ? 'green' : 'red') . '-200 text-gray-700 px-4 py-2 text-sm">' . $value['result'] . '</div>';
|
||||
foreach ($header as $name => $text) {
|
||||
$color = 'gray';
|
||||
if ($name == 'result' && in_array($value[$name], ['YES', 'NO'])) {
|
||||
$color = $value[$name] == 'YES' ? 'green' : 'red';
|
||||
}
|
||||
$table .= '<div class="table-cell bg-gray-200 text-' . $color . '-700 px-4 py-2 text-sm">' . $value[$name] . '</div>';
|
||||
}
|
||||
$table .= '</div>';
|
||||
}
|
||||
$table .= '</div>';
|
||||
|
||||
@@ -9,13 +9,14 @@ use App\Models\ExamUser;
|
||||
use App\Models\Icon;
|
||||
use App\Models\Setting;
|
||||
use App\Repositories\ExamRepository;
|
||||
use GuzzleHttp\Client;
|
||||
use Illuminate\Support\Str;
|
||||
use Nexus\Database\NexusDB;
|
||||
|
||||
class Update extends Install
|
||||
{
|
||||
|
||||
protected $steps = ['环境检测', '添加 .env 文件', '修改&创建数据表', '导入数据'];
|
||||
protected $steps = ['环境检测', '选择版本安装', '更新 .env 文件', '更新配置'];
|
||||
|
||||
|
||||
public function getLogFile()
|
||||
@@ -143,4 +144,84 @@ class Update extends Install
|
||||
|
||||
}
|
||||
|
||||
public function listVersions()
|
||||
{
|
||||
$client = new Client();
|
||||
$url = "https://api.github.com/repos/xiaomlove/nexusphp/releases";
|
||||
$response = $client->get($url, ['timeout' => 10,]);
|
||||
if (($statusCode = $response->getStatusCode()) != 200) {
|
||||
throw new \RuntimeException("获取版本列表失败,状态码:$statusCode");
|
||||
}
|
||||
if ($response->getBody()->getSize() <= 0) {
|
||||
throw new \RuntimeException("获取版本列表失败,结果为空");
|
||||
}
|
||||
$bodyString = $response->getBody()->getContents();
|
||||
$this->doLog("[LIST_VERSION_RESPONSE]: $bodyString");
|
||||
$versions = json_decode($bodyString, true);
|
||||
if (empty($versions) || !is_array($versions)) {
|
||||
throw new \RuntimeException("获取版本列表结果异常");
|
||||
}
|
||||
return array_reverse($versions);
|
||||
}
|
||||
|
||||
public function downAndExtractCode($url)
|
||||
{
|
||||
$arr = explode('/', $url);
|
||||
$basename = last($arr);
|
||||
$suffix = '.tar.gz';
|
||||
$filename = sprintf('%s/nexusphp-%s-%s%s', sys_get_temp_dir(), $basename, date('YmdHis'), $suffix);
|
||||
$client = new Client();
|
||||
$response = $client->request('GET', $url, ['sink' => $filename]);
|
||||
if (($statusCode = $response->getStatusCode()) != 200) {
|
||||
throw new \RuntimeException("下载错误,状态码:$statusCode");
|
||||
}
|
||||
if (($bodySize = $response->getBody()->getSize()) <= 0) {
|
||||
throw new \RuntimeException("下载错误,文件体积:$bodySize");
|
||||
}
|
||||
if (!file_exists($filename)) {
|
||||
throw new \RuntimeException("下载错误,文件不存在:$filename");
|
||||
}
|
||||
if (filesize($filename) <= 0) {
|
||||
throw new \RuntimeException("下载错误,文件大小为0");
|
||||
}
|
||||
$this->doLog('SUCCESS_DOWNLOAD');
|
||||
$extractDir = str_replace($suffix, "", $filename);
|
||||
$command = "mkdir -p $extractDir";
|
||||
$result = exec($command, $output, $result_code);
|
||||
$this->doLog(sprintf(
|
||||
"command: %s, output: %s, result_code: %s, result: %s",
|
||||
$command, json_encode($output), $result_code, $result
|
||||
));
|
||||
if ($result_code != 0) {
|
||||
throw new \RuntimeException("创建解压目录:$extractDir 失败, result_code: $result_code");
|
||||
}
|
||||
|
||||
$command = "tar -xf $filename -C $extractDir";
|
||||
$result = exec($command, $output, $result_code);
|
||||
$this->doLog(sprintf(
|
||||
"command: %s, output: %s, result_code: %s, result: %s",
|
||||
$command, json_encode($output), $result_code, $result
|
||||
));
|
||||
if ($result_code != 0) {
|
||||
throw new \RuntimeException("解压文件:$filename 到:$extractDir 失败, result_code: $result_code");
|
||||
}
|
||||
|
||||
foreach (glob("$extractDir/*") as $path) {
|
||||
if (is_dir($path)) {
|
||||
$command = sprintf('cp -Rf %s/* %s', $path, ROOT_PATH);
|
||||
$result = exec($command, $output, $result_code);
|
||||
$this->doLog(sprintf(
|
||||
"command: %s, output: %s, result_code: %s, result: %s",
|
||||
$command, json_encode($output), $result_code, $result
|
||||
));
|
||||
if ($result_code != 0) {
|
||||
throw new \RuntimeException("复制错误, result_code: $result_code");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
$this->doLog('SUCCESS_EXTRACT');
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,6 +23,69 @@ if ($currentStep == 1) {
|
||||
}
|
||||
|
||||
if ($currentStep == 2) {
|
||||
$tableRows = [];
|
||||
$versionTable = $versions = [];
|
||||
$cacheKkey = '__versions_' . date('Ymd_H');
|
||||
try {
|
||||
if (!empty($_SESSION[$cacheKkey])) {
|
||||
$update->doLog("get versions from session.");
|
||||
$versions = $_SESSION[$cacheKkey];
|
||||
} else {
|
||||
$versions = $update->listVersions();
|
||||
}
|
||||
} catch (\Exception $exception) {
|
||||
$error = $exception->getMessage();
|
||||
}
|
||||
$_SESSION[$cacheKkey] = $versions;
|
||||
$versionHeader = [
|
||||
'checkbox' => '选择',
|
||||
'tag_name' => '版本(标签)',
|
||||
'name' => '名称',
|
||||
'published_at' => '发布时间',
|
||||
];
|
||||
foreach ($versions as $version) {
|
||||
if ($version['draft']) {
|
||||
continue;
|
||||
}
|
||||
$time = \Carbon\Carbon::parse($version['published_at']);
|
||||
$time->tz = nexus_env('TIMEZONE');
|
||||
$versionUrl = $version['tag_name'] . '|' . $version['tarball_url'];
|
||||
$checked = !empty($_REQUEST['version_url']) && $_REQUEST['version_url'] == $versionUrl ? ' checked' : '';
|
||||
$tableRows[] = [
|
||||
'checkbox' => sprintf('<input type="radio" name="version_url" value="%s"%s/>', $versionUrl, $checked),
|
||||
'tag_name' => $version['tag_name'],
|
||||
'name' => $version['name'],
|
||||
'published_at' => $time->format('Y-m-d H:i:s'),
|
||||
];
|
||||
}
|
||||
while ($isPost) {
|
||||
try {
|
||||
if (empty($_REQUEST['version_url'])) {
|
||||
throw new \RuntimeException("没有选择版本");
|
||||
}
|
||||
$versionUrlArr = explode('|', $_REQUEST['version_url']);
|
||||
$version = strtolower($versionUrlArr[0]);
|
||||
$downloadUrl = $versionUrlArr[1];
|
||||
if (\Illuminate\Support\Str::startsWith($version, 'v')) {
|
||||
$version = substr($version, 1);
|
||||
}
|
||||
$update->doLog("version: $version, downloadUrl: $downloadUrl, currentVersion: " . VERSION_NUMBER);
|
||||
if (version_compare($version, VERSION_NUMBER, '<=')) {
|
||||
throw new \RuntimeException("必须选择一个高于当前版本(" . VERSION_NUMBER . ")的");
|
||||
}
|
||||
$update->downAndExtractCode($downloadUrl);
|
||||
|
||||
$update->nextStep();
|
||||
} catch (\Exception $exception) {
|
||||
$update->doLog($exception->getMessage() . $exception->getTraceAsString());
|
||||
$error = $exception->getMessage();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($currentStep == 3) {
|
||||
$envExampleFile = $rootpath . ".env.example";
|
||||
// $dbstructureFile = $rootpath . "_db/dbstructure_v1.6.sql";
|
||||
$envExampleData = readEnvFile($envExampleFile);
|
||||
@@ -56,74 +119,6 @@ if ($currentStep == 2) {
|
||||
$pass = empty($fails);
|
||||
}
|
||||
|
||||
if ($currentStep == 3) {
|
||||
// $createTables = $update->listAllTableCreate();
|
||||
$createTables = $update->listAllTableCreateFromMigrations();
|
||||
$existsTables = $update->listExistsTable();
|
||||
$tableRows = [];
|
||||
$toCreateTable = $toAlterTable = $toUpdateTable = [];
|
||||
foreach ($createTables as $table => $tableCreate) {
|
||||
//Table not exists
|
||||
if (!in_array($table, $existsTables)) {
|
||||
$tableRows[] = [
|
||||
"label" => "Table: $table",
|
||||
"required" => "exists",
|
||||
"current" => "",
|
||||
"result" => 'NO',
|
||||
];
|
||||
$toCreateTable[$table] = $tableCreate;
|
||||
continue;
|
||||
}
|
||||
$tableHaveFields = $update->listTableFieldsFromDb($table);
|
||||
foreach ($tableHaveFields as $field => $fieldInfo) {
|
||||
if ($fieldInfo['Type'] == 'datetime' && $fieldInfo['Default'] == '0000-00-00 00:00:00') {
|
||||
$tableRows[] = [
|
||||
'label' => "Field: $table.$field",
|
||||
'required' => 'default null',
|
||||
'current' => '0000-00-00 00:00:00',
|
||||
'result' => 'NO',
|
||||
];
|
||||
$toAlterTable[$table][$field] = "modify $field datetime default null";
|
||||
$toUpdateTable[$table][$field] = "null";
|
||||
}
|
||||
}
|
||||
}
|
||||
while ($isPost) {
|
||||
try {
|
||||
sql_query('SET sql_mode=(SELECT REPLACE(@@sql_mode,"NO_ZERO_DATE", ""))');
|
||||
$command = "php " . ROOT_PATH . "artisan migrate --force";
|
||||
$result = exec($command, $output, $result_code);
|
||||
$update->doLog(sprintf('command: %s, result_code: %s, result: %s', $command, $result_code, $result));
|
||||
$update->doLog("output: " . json_encode($output));
|
||||
if ($result_code != 0) {
|
||||
throw new \RuntimeException(json_encode($output));
|
||||
} else {
|
||||
$update->doLog("[MIGRATE] success.");
|
||||
}
|
||||
foreach ($toAlterTable as $table => $modies) {
|
||||
$query = "alter table $table " . implode(', ', $modies);
|
||||
$update->doLog("[ALTER TABLE] $query");
|
||||
sql_query($query);
|
||||
}
|
||||
foreach ($toUpdateTable as $table => $updates) {
|
||||
foreach ($updates as $field => $fieldUpdate) {
|
||||
$query = sprintf("update %s set %s = %s where %s = '0000-00-00 00:00:00'", $table, $field, $fieldUpdate, $field);
|
||||
$update->doLog("[UPDATE TABLE] $query, affectedRows: " . mysql_affected_rows());
|
||||
sql_query($query);
|
||||
}
|
||||
}
|
||||
|
||||
$update->runExtraQueries();
|
||||
|
||||
$update->nextStep();
|
||||
} catch (\Exception $exception) {
|
||||
$update->doLog($exception->getMessage() . $exception->getTraceAsString());
|
||||
$error = $exception->getMessage();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($currentStep == 4) {
|
||||
$settingTableRows = $update->listSettingTableRows();
|
||||
@@ -135,6 +130,7 @@ if ($currentStep == 4) {
|
||||
try {
|
||||
$update->createSymbolicLinks($symbolicLinks);
|
||||
$update->saveSettings($settings);
|
||||
$update->runExtraQueries();
|
||||
$update->nextStep();
|
||||
} catch (\Exception $e) {
|
||||
$error = $e->getMessage();
|
||||
@@ -166,20 +162,25 @@ if (!empty($error)) {
|
||||
<input type="hidden" name="step" value="<?php echo $currentStep?>">
|
||||
<?php
|
||||
echo'<div class="step-' . $currentStep . ' text-center">';
|
||||
$header = ['项目', '要求', '当前', '结果'];
|
||||
$header = [
|
||||
'label' => '项目',
|
||||
'require' => '要求',
|
||||
'current'=> '当前',
|
||||
'result'=> '结果'
|
||||
];
|
||||
if ($currentStep == 1) {
|
||||
echo $update->renderTable($header, $requirements['table_rows']);
|
||||
} elseif ($currentStep == 2) {
|
||||
} elseif ($currentStep == 3) {
|
||||
echo $update->renderTable($header, $tableRows);
|
||||
echo '<div class="text-gray-700 p-4 text-red-400">若 Redis 不启用,相关项目留空</div>';
|
||||
echo $update->renderForm($envFormControls);
|
||||
|
||||
} elseif ($currentStep == 3) {
|
||||
echo '<h1 class="mb-4 text-lg font-bold">需要修改或创建以下数据表(字段)</h1>';
|
||||
} elseif ($currentStep == 2) {
|
||||
echo '<h1 class="mb-4 text-lg font-bold">选择目标版本(注意必须选择比当前版本(' . VERSION_NUMBER. ')高的)</h1>';
|
||||
if (empty($tableRows)) {
|
||||
echo '<div class="text-green-600 text-center">恭喜,需要的表(字段)均符合要求!</div>';
|
||||
echo '<div class="text-green-600 text-center">抱歉,暂无任何版可以选择!</div>';
|
||||
} else {
|
||||
echo $update->renderTable($header, $tableRows);
|
||||
echo $update->renderTable($versionHeader, $tableRows);
|
||||
}
|
||||
} elseif ($currentStep == 4) {
|
||||
echo $update->renderTable($header, $tableRows);
|
||||
|
||||
Reference in New Issue
Block a user