From 5259ff9862565f6b993653399a831df280a916fb Mon Sep 17 00:00:00 2001
From: xiaomlove <353856593@qq.com>
Date: Thu, 17 Jun 2021 20:07:22 +0800
Subject: [PATCH] [update] auto download source code
---
app/Console/Commands/Test.php | 5 +-
nexus/Install/Install.php | 15 ++--
nexus/Install/Update.php | 83 +++++++++++++++++-
nexus/Install/update/update.php | 149 ++++++++++++++++----------------
4 files changed, 170 insertions(+), 82 deletions(-)
diff --git a/app/Console/Commands/Test.php b/app/Console/Commands/Test.php
index 415434a2..34b2f025 100644
--- a/app/Console/Commands/Test.php
+++ b/app/Console/Commands/Test.php
@@ -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());
}
}
diff --git a/nexus/Install/Install.php b/nexus/Install/Install.php
index a4f7f1a7..73a455cc 100644
--- a/nexus/Install/Install.php
+++ b/nexus/Install/Install.php
@@ -287,16 +287,19 @@ class Install
$table = '
';
$table .= '
';
$table .= '
';
- foreach ($header as $value) {
- $table .= '
' . $value . '
';
+ foreach ($header as $text) {
+ $table .= '
' . $text . '
';
}
$table .= '
';
foreach ($data as $value) {
$table .= '
';
- $table .= '
' . $value['label'] . '
';
- $table .= '
' . $value['required'] . '
';
- $table .= '
' . $value['current'] . '
';
- $table .= '
' . $value['result'] . '
';
+ foreach ($header as $name => $text) {
+ $color = 'gray';
+ if ($name == 'result' && in_array($value[$name], ['YES', 'NO'])) {
+ $color = $value[$name] == 'YES' ? 'green' : 'red';
+ }
+ $table .= '
' . $value[$name] . '
';
+ }
$table .= '
';
}
$table .= '
';
diff --git a/nexus/Install/Update.php b/nexus/Install/Update.php
index af8782cc..d54d710c 100644
--- a/nexus/Install/Update.php
+++ b/nexus/Install/Update.php
@@ -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;
+ }
+
}
diff --git a/nexus/Install/update/update.php b/nexus/Install/update/update.php
index 2ce7dfe6..cfbe0dc9 100644
--- a/nexus/Install/update/update.php
+++ b/nexus/Install/update/update.php
@@ -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('
', $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)) {
';
- $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 '
若 Redis 不启用,相关项目留空
';
echo $update->renderForm($envFormControls);
- } elseif ($currentStep == 3) {
- echo '
需要修改或创建以下数据表(字段)
';
+ } elseif ($currentStep == 2) {
+ echo '
选择目标版本(注意必须选择比当前版本(' . VERSION_NUMBER. ')高的)
';
if (empty($tableRows)) {
- echo '
恭喜,需要的表(字段)均符合要求!
';
+ echo '
抱歉,暂无任何版可以选择!
';
} else {
- echo $update->renderTable($header, $tableRows);
+ echo $update->renderTable($versionHeader, $tableRows);
}
} elseif ($currentStep == 4) {
echo $update->renderTable($header, $tableRows);