Skip to content

Commit

Permalink
refactor: エンジンとパッケージ情報の取得メソッドを改善し、型定義を更新
Browse files Browse the repository at this point in the history
  • Loading branch information
Hiroshiba committed Nov 10, 2024
1 parent 973a5a5 commit cee971a
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 51 deletions.
41 changes: 19 additions & 22 deletions src/backend/electron/engineAndVvppController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,12 @@ import {
EngineSettingType,
} from "@/type/preload";
import {
EngineVariant,
PackageInfo,
fetchLatestDefaultEngineInfo,
getSuitableVariant,
} from "@/domain/defaultEngine/latetDefaultEngine";
import {
EnvEngineInfoType,
loadEnvEngineInfos,
} from "@/domain/defaultEngine/envEngineInfo";
import { loadEnvEngineInfos } from "@/domain/defaultEngine/envEngineInfo";
import { UnreachableError } from "@/type/utility";

/**
* エンジンとVVPP周りの処理の流れを制御するクラス。
Expand Down Expand Up @@ -143,22 +141,19 @@ export class EngineAndVvppController {
}

/**
* インストールが必要なデフォルトエンジンの情報とパッケージの情報を取得する
* インストール可能なデフォルトエンジンの情報とパッケージの情報を取得する
*/
async fetchEngineAndPackageInfosToInstall(): Promise<
{
envEngineInfo: EnvEngineInfoType;
packageInfo: EngineVariant;
}[]
async fetchInsallablePackageInfos(): Promise<
{ engineName: string; packageInfo: PackageInfo }[]
> {
// .envのデフォルトエンジン情報のうち、downloadVvppなものを集める
// ダウンロード可能なVVPPのうち、未インストールのものを返す
const targetInfos = [];
for (const envEngineInfo of loadEnvEngineInfos()) {
if (envEngineInfo.type != "downloadVvpp") {
continue;
}

// 更新情報を取得
// 最新情報を取得
const latestUrl = envEngineInfo.latestUrl;
if (latestUrl == undefined) throw new Error("latestUrl is undefined");

Expand All @@ -168,20 +163,18 @@ export class EngineAndVvppController {
continue;
}

// 実行環境に合うパッケージを取得
const packageInfo = getSuitableVariant(latestInfo);
log.info(`Latest default engine version: ${packageInfo.version}`);

// インストール済みだった場合はスキップ
// FIXME: より新しいバージョンであれば更新する
// FIXME: より新しいバージョンがあれば更新できるようにする
if (this.engineInfoManager.hasEngineInfo(envEngineInfo.uuid)) {
log.info(`Default engine ${envEngineInfo.uuid} is already installed.`);
continue;
}

targetInfos.push({
envEngineInfo,
packageInfo,
});
targetInfos.push({ engineName: envEngineInfo.name, packageInfo });
}

return targetInfos;
Expand All @@ -190,12 +183,16 @@ export class EngineAndVvppController {
/** VVPPパッケージをダウンロードし、インストールする */
async downloadAndInstallVvppEngine(
downloadDir: string,
packageInfo: EngineVariant,
packageInfo: PackageInfo,
) {
if (packageInfo.packages.length === 0) {
throw new UnreachableError("No packages to download");
}

// ダウンロード
const downloadedPaths = new Array<string>(packageInfo.packages.length);
const downloadedPaths: string[] = [];
await Promise.all(
packageInfo.packages.map(async (p, index) => {
packageInfo.packages.map(async (p) => {
const { url, name, size } = p;

log.info(`Download ${name} from ${url}, size: ${size}`);
Expand All @@ -206,7 +203,7 @@ export class EngineAndVvppController {
await fs.promises.writeFile(downloadPath, Buffer.from(buffer));
log.info(`Downloaded ${name} to ${downloadPath}`);

downloadedPaths[index] = downloadPath;
downloadedPaths.push(downloadPath);

// TODO: ハッシュチェック
}),
Expand Down
10 changes: 5 additions & 5 deletions src/backend/electron/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -932,15 +932,15 @@ app.on("ready", async () => {
}

// VVPPがデフォルトエンジンに指定されていたらインストールする
// NOTE: 工事中。参照: https://github.com/VOICEVOX/voicevox/issues/1194
const engineAndPackageInfosToInstall =
await engineAndVvppController.fetchEngineAndPackageInfosToInstall();
for (const { envEngineInfo, packageInfo } of engineAndPackageInfosToInstall) {
// NOTE: この機能は工事中。参照: https://github.com/VOICEVOX/voicevox/issues/1194
const engineAndPackageInfos =
await engineAndVvppController.fetchInsallablePackageInfos();
for (const { engineName, packageInfo } of engineAndPackageInfos) {
// インストールするか確認
const result = dialog.showMessageBoxSync(win, {
type: "info",
title: "デフォルトエンジンのインストール",
message: `デフォルトエンジン ${envEngineInfo.name} をインストールしますか?`,
message: `${engineName} をインストールしますか?`,
buttons: ["インストール", "キャンセル"],
cancelId: 1,
});
Expand Down
2 changes: 0 additions & 2 deletions src/backend/electron/manager/engineInfoManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import {
minimumEngineManifestSchema,
} from "@/type/preload";
import { AltPortInfos } from "@/store/type";
import { UnreachableError } from "@/type/utility";
import { loadEnvEngineInfos } from "@/domain/defaultEngine/envEngineInfo";
import { failure, Result, success } from "@/type/result";

Expand Down Expand Up @@ -84,7 +83,6 @@ export class EngineInfoManager {
return this.envEngineInfos
.filter((engineInfo) => engineInfo.type != "downloadVvpp")
.map((engineInfo) => {
if (engineInfo.type == "downloadVvpp") throw new UnreachableError();
const { protocol, hostname, port, pathname } = new URL(engineInfo.host);
return {
...engineInfo,
Expand Down
34 changes: 22 additions & 12 deletions src/domain/defaultEngine/envEngineInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,28 @@ import { z } from "zod";
import { engineIdSchema } from "@/type/preload";

/** .envに書くデフォルトエンジン情報のスキーマ */
export const envEngineInfoSchema = z.object({
uuid: engineIdSchema,
host: z.string(),
name: z.string(),
executionEnabled: z.boolean(), // FIXME: typeがurlのときのみ必要
executionFilePath: z.string(), // FIXME: typeがpathのときは必須
executionArgs: z.array(z.string()),
path: z.string().optional(), // FIXME: typeがpathで、アンインストール可能なときは必須
type: z.union([z.literal("path"), z.literal("downloadVvpp")]).default("path"),
latestUrl: z.string().optional(), // FIXME: typeがdownloadVvppのときは必須
});
export type EnvEngineInfoType = z.infer<typeof envEngineInfoSchema>;
const envEngineInfoSchema = z
.object({
uuid: engineIdSchema,
host: z.string(),
name: z.string(),
executionEnabled: z.boolean(),
executionArgs: z.array(z.string()),
})
.and(
z.union([
z.object({
type: z.literal("path").default("path"),
executionFilePath: z.string(),
path: z.string().optional(),
}),
z.object({
type: z.literal("downloadVvpp"),
latestUrl: z.string(),
}),
]),
);
type EnvEngineInfoType = z.infer<typeof envEngineInfoSchema>;

/** .envからデフォルトエンジン情報を読み込む */
export function loadEnvEngineInfos(): EnvEngineInfoType[] {
Expand Down
20 changes: 10 additions & 10 deletions src/domain/defaultEngine/latetDefaultEngine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import { z } from "zod";

/** パッケージ情報のスキーマ */
const engineVariantSchema = z.object({
const packageInfoSchema = z.object({
version: z.string(),
packages: z
.object({
Expand All @@ -16,29 +16,29 @@ const engineVariantSchema = z.object({
})
.array(),
});
export type EngineVariant = z.infer<typeof engineVariantSchema>;
export type PackageInfo = z.infer<typeof packageInfoSchema>;

/** デフォルトエンジンの最新情報のスキーマ */
const latestDefaultEngineInfoSchema = z.object({
formatVersion: z.number(),
windows: z.object({
x64: z.object({
CPU: engineVariantSchema,
"GPU/CPU": engineVariantSchema,
CPU: packageInfoSchema,
"GPU/CPU": packageInfoSchema,
}),
}),
macos: z.object({
x64: z.object({
CPU: engineVariantSchema,
CPU: packageInfoSchema,
}),
arm64: z.object({
CPU: engineVariantSchema,
CPU: packageInfoSchema,
}),
}),
linux: z.object({
x64: z.object({
CPU: engineVariantSchema,
"GPU/CPU": engineVariantSchema,
CPU: packageInfoSchema,
"GPU/CPU": packageInfoSchema,
}),
}),
});
Expand All @@ -51,11 +51,11 @@ export const fetchLatestDefaultEngineInfo = async (url: string) => {

/**
* 実行環境に合うパッケージを取得する。GPU版があればGPU版を返す。
* FIXME: どのデバイス版にするかはユーザーが選べるようにするべき。
* TODO: どのデバイス版にするかはユーザーが選べるようにするべき。
*/
export const getSuitableVariant = (
updateInfo: z.infer<typeof latestDefaultEngineInfoSchema>,
): EngineVariant => {
): PackageInfo => {
const platform = process.platform;
const arch = process.arch;

Expand Down

0 comments on commit cee971a

Please sign in to comment.