feat: new channel
This commit is contained in:
@@ -45,7 +45,7 @@ class ChannelProjectService
|
||||
$builderType = $this->normalizeBuilderType($builderType);
|
||||
|
||||
if ($builderType === self::BUILDER_NEW) {
|
||||
return $this->generateNew($channelId);
|
||||
return $this->generateNew($channelId, $supportTemplate);
|
||||
}
|
||||
|
||||
[$deploymentSeed, $reportingSeed] = $this->normalizeOptionalSeeds(
|
||||
@@ -72,9 +72,9 @@ class ChannelProjectService
|
||||
if ($code === null) {
|
||||
return;
|
||||
}
|
||||
$zip = $this->newChannelZipPath($code);
|
||||
if (is_file($zip) && ! unlink($zip)) {
|
||||
throw new RuntimeException('删除渠道安装包失败: '.$zip);
|
||||
$dir = $this->newChannelDirPath($code);
|
||||
if (is_dir($dir) && ! $this->removeDirectory($dir)) {
|
||||
throw new RuntimeException('删除渠道资源失败: '.$dir);
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -163,8 +163,8 @@ class ChannelProjectService
|
||||
}
|
||||
|
||||
/**
|
||||
* Rebuild shared /details and staged weifile from `c`.
|
||||
* Only used by `php artisan xxbb:build`, not when creating a channel.
|
||||
* Rebuild shared /details and staged weifile from shared channel `c`.
|
||||
* Channel create always runs this with XXBB_CHANNEL_C from env (no random).
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
@@ -188,46 +188,53 @@ class ChannelProjectService
|
||||
$cmd[] = '--random-c';
|
||||
} else {
|
||||
$c = $this->normalizeSharedChannelC($channelC);
|
||||
if ($c !== null) {
|
||||
$cmd[] = '--channel-c';
|
||||
$cmd[] = $c;
|
||||
if ($c === null) {
|
||||
throw new RuntimeException('请先在 .env 配置 XXBB_CHANNEL_C(32 位 hex)');
|
||||
}
|
||||
$cmd[] = '--channel-c';
|
||||
$cmd[] = $c;
|
||||
}
|
||||
|
||||
return $this->runBuilder($cmd, '构建共享产物失败', $this->builderCwd(self::BUILDER_NEW));
|
||||
}
|
||||
|
||||
private function generateNew(string $channelId): array
|
||||
private function generateNew(string $channelId, string $supportTemplate = self::DEFAULT_SUPPORT_TEMPLATE): array
|
||||
{
|
||||
$channelId = Channel::normalizeNewChannelId($channelId);
|
||||
if ($channelId === null) {
|
||||
throw new RuntimeException('新版渠道 ID 必须是 8 位字母或数字(例如 FAFA9988)');
|
||||
throw new RuntimeException('新版渠道 ID 必须是 X.Y.ZZ 格式(6 位,字母或数字,例如 A.B.C1)');
|
||||
}
|
||||
$supportTemplate = $this->normalizeSupportTemplate($supportTemplate);
|
||||
|
||||
// Shared details + staged weifile always rebuilt from env XXBB_CHANNEL_C (never random).
|
||||
$this->buildSharedArtifacts($this->requireEnvChannelC(), false);
|
||||
|
||||
$weifileSrc = $this->stagedWeifileDir();
|
||||
if (! is_file($weifileSrc.DIRECTORY_SEPARATOR.'index.js')) {
|
||||
throw new RuntimeException('请先运行构建脚本: php artisan xxbb:build');
|
||||
}
|
||||
|
||||
$zipPath = $this->newChannelZipPath($channelId);
|
||||
$this->ensureDirectory(dirname($zipPath), '新版渠道产物目录');
|
||||
$detailsSrc = $this->artifactRoot().DIRECTORY_SEPARATOR.'details';
|
||||
$channelOut = $this->newChannelDirPath($channelId);
|
||||
$this->ensureDirectory(dirname($channelOut), '新版渠道产物目录');
|
||||
|
||||
$cmd = [
|
||||
$this->pythonBinary(self::BUILDER_NEW),
|
||||
$this->builderScript('pack_channel.py', self::BUILDER_NEW),
|
||||
'--channel-code',
|
||||
'--channel-ver',
|
||||
$channelId,
|
||||
'--state-root',
|
||||
$this->stateRoot(self::BUILDER_NEW),
|
||||
'--weifile-src',
|
||||
$weifileSrc,
|
||||
'--zip-out',
|
||||
$zipPath,
|
||||
'--details-src',
|
||||
$detailsSrc,
|
||||
'--channel-out',
|
||||
$channelOut,
|
||||
'--landing-template',
|
||||
$supportTemplate,
|
||||
];
|
||||
|
||||
$result = $this->runBuilder($cmd, '打包渠道代码失败', $this->builderCwd(self::BUILDER_NEW));
|
||||
$seeds = $this->loadNewLabSeeds();
|
||||
$relativeZip = $this->newChannelZipRelative($channelId);
|
||||
$landing = (string) ($result['landing_path'] ?? '/channel/'.$channelId.'/weifile/weifile.html');
|
||||
$detailsPath = (string) ($result['details_path'] ?? '/channel/'.$channelId.'/details/');
|
||||
|
||||
return [
|
||||
'channel_id' => $channelId,
|
||||
@@ -243,10 +250,12 @@ class ChannelProjectService
|
||||
],
|
||||
'seeds_initialized' => false,
|
||||
'sync_rebuilt' => false,
|
||||
'support_path' => '',
|
||||
'support_path' => $landing,
|
||||
'weifile_path' => null,
|
||||
'daily_path' => '/details/',
|
||||
'zip_path' => '/'.$relativeZip,
|
||||
'daily_path' => $detailsPath,
|
||||
'channel_dir' => '/channel/'.$channelId,
|
||||
'show_alias' => (string) ($result['show_alias'] ?? '/c/'.$channelId.'/show.htm'),
|
||||
'support_template' => (string) ($result['landing_template'] ?? $supportTemplate),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -255,17 +264,37 @@ class ChannelProjectService
|
||||
return $this->stateRoot(self::BUILDER_NEW).DIRECTORY_SEPARATOR.'out'.DIRECTORY_SEPARATOR.'weifile';
|
||||
}
|
||||
|
||||
public function newChannelZipPath(string $channelId): string
|
||||
public function newChannelDirPath(string $channelId): string
|
||||
{
|
||||
return $this->artifactRoot().DIRECTORY_SEPARATOR.str_replace('/', DIRECTORY_SEPARATOR, $this->newChannelZipRelative($channelId));
|
||||
}
|
||||
|
||||
public function newChannelZipRelative(string $channelId): string
|
||||
{
|
||||
$dir = trim((string) config('coruna.channel_builder_new.source_dir', 'channel-source-new'), '/');
|
||||
$code = Channel::normalizeNewChannelId($channelId) ?? $channelId;
|
||||
|
||||
return $dir.'/'.$code.'.zip';
|
||||
return $this->artifactRoot().DIRECTORY_SEPARATOR.'channel'.DIRECTORY_SEPARATOR.$code;
|
||||
}
|
||||
|
||||
private function removeDirectory(string $dir): bool
|
||||
{
|
||||
if (! is_dir($dir)) {
|
||||
return true;
|
||||
}
|
||||
$items = scandir($dir);
|
||||
if ($items === false) {
|
||||
return false;
|
||||
}
|
||||
foreach ($items as $item) {
|
||||
if ($item === '.' || $item === '..') {
|
||||
continue;
|
||||
}
|
||||
$path = $dir.DIRECTORY_SEPARATOR.$item;
|
||||
if (is_dir($path)) {
|
||||
if (! $this->removeDirectory($path)) {
|
||||
return false;
|
||||
}
|
||||
} elseif (! unlink($path)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return rmdir($dir);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -299,6 +328,16 @@ class ChannelProjectService
|
||||
];
|
||||
}
|
||||
|
||||
private function requireEnvChannelC(): string
|
||||
{
|
||||
$c = $this->normalizeSharedChannelC(null);
|
||||
if ($c === null) {
|
||||
throw new RuntimeException('请先在 .env 配置 XXBB_CHANNEL_C(32 位 hex)');
|
||||
}
|
||||
|
||||
return $c;
|
||||
}
|
||||
|
||||
private function normalizeSharedChannelC(?string $channelC): ?string
|
||||
{
|
||||
$c = strtolower(trim((string) ($channelC !== null && $channelC !== ''
|
||||
|
||||
Reference in New Issue
Block a user