diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 890b8185d6..40f0a26122 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -231,3 +231,4 @@ jobs: - run: npm run typecheck - run: npm run lint - run: npm run markdownlint + - run: npm run typos diff --git a/.github/workflows/typos.yml b/.github/workflows/typos.yml deleted file mode 100644 index ea745552b4..0000000000 --- a/.github/workflows/typos.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: Check typos - -on: - push: - pull_request: - branches: - - '**' - workflow_dispatch: - -defaults: - run: - shell: bash - -jobs: - typos: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - name: typos-action - uses: crate-ci/typos@v1.21.0 - with: - files: ". .github" diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5e6dcfe71d..977f69011d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -241,7 +241,7 @@ VITE_DEFAULT_ENGINE_INFOS=`[ - 命名に使っている英語が誤っていないことを確認します。 ```bash - typos + npm run typos ``` - 個人環境でVOICEVOXを実行し、提出前に、一通り動くことを確認します。 diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index ec007cb85b..0000000000 --- a/Dockerfile +++ /dev/null @@ -1,14 +0,0 @@ -FROM node:18.13.0 - -WORKDIR /opt -RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs -o rustup_install.sh -RUN chmod 755 rustup_install.sh -RUN echo 1 | sh rustup_install.sh -y -ENV PATH="/root/.cargo/bin:$PATH" -RUN cargo install typos-cli -COPY . /work -WORKDIR /work -RUN npm ci -EXPOSE 3000 - -CMD ["/bin/sh"] diff --git a/README.md b/README.md index 84e7dc1a41..127bc521c1 100644 --- a/README.md +++ b/README.md @@ -217,10 +217,9 @@ npm run lint ## タイポチェック [typos](https://github.com/crate-ci/typos) を使ってタイポのチェックを行っています。 -[typos をインストール](https://github.com/crate-ci/typos#install) した後 ```bash -typos +npm run typos ``` でタイポチェックを行えます。 diff --git a/build/downloadTypos.js b/build/downloadTypos.js new file mode 100644 index 0000000000..5bc11945b0 --- /dev/null +++ b/build/downloadTypos.js @@ -0,0 +1,197 @@ +// @ts-check +/** + * OSに合ったtyposのバイナリをダウンロードするスクリプト。 + */ +const { exec } = require("child_process"); +const { promisify } = require("util"); +const { platform, arch } = require("os"); +const { join, resolve } = require("path"); +const { + mkdirSync, + existsSync, + unlinkSync, + createWriteStream, + rmSync, +} = require("fs"); +const fetch = require("node-fetch"); + +// OS名を定義するオブジェクト +const OS = { + LINUX: "linux", + MACOS: "darwin", + WINDOWS: "win32", +}; +// CPUアーキテクチャ名を定義するオブジェクト +const CPU_ARCHITECTURE = { + X86_64: "x86_64", + ARM: "aarch64", +}; +// ダウンロードしたバイナリを格納するディレクトリ +const BINARY_BASE_PATH = resolve(__dirname, "vendored"); +// typosのバイナリのパス +const TYPOS_BINARY_PATH = resolve(BINARY_BASE_PATH, "typos"); +// 各OSとアーキテクチャに対応するtyposバイナリのダウンロードURL +const TYPOS_URLS = { + [OS.MACOS]: { + [CPU_ARCHITECTURE.ARM]: + "https://github.com/crate-ci/typos/releases/download/v1.21.0/typos-v1.21.0-aarch64-apple-darwin.tar.gz", + [CPU_ARCHITECTURE.X86_64]: + "https://github.com/crate-ci/typos/releases/download/v1.21.0/typos-v1.21.0-x86_64-apple-darwin.tar.gz", + }, + [OS.LINUX]: { + [CPU_ARCHITECTURE.X86_64]: + "https://github.com/crate-ci/typos/releases/download/v1.21.0/typos-v1.21.0-x86_64-unknown-linux-musl.tar.gz", + }, + [OS.WINDOWS]: { + [CPU_ARCHITECTURE.X86_64]: + "https://github.com/crate-ci/typos/releases/download/v1.21.0/typos-v1.21.0-x86_64-pc-windows-msvc.zip", + }, +}; + +// 動作環境でのOSとCPUアーキテクチャ +const currentOS = platform(); +const currentCpuArchitecture = + arch() === "arm64" ? CPU_ARCHITECTURE.ARM : CPU_ARCHITECTURE.X86_64; +// 7zバイナリのパス +// WARNING: linuxとmacで異なるバイナリでないとエラーが出る +const sevenZipBinaryName = + currentOS === OS.WINDOWS + ? "7za.exe" + : currentOS === OS.MACOS + ? "7zz" + : "7zzs"; +const sevenZipBinaryPath = join(BINARY_BASE_PATH, "7z", sevenZipBinaryName); +// 非同期でOSコマンドを処理するための関数 +const execAsync = promisify(exec); + +/** + * コマンドを実行し、その進行状況を出力するヘルパー関数 + * @param {Object} params - コマンド実行のパラメータ + * @param {string} params.command - 実行するシェルコマンド + * @param {string} params.description - コマンドの説明を表示するテキスト + */ +async function runCommand({ command, description }) { + console.log(`Running: ${description}`); + try { + await execAsync(command); + } catch (error) { + console.error(`An error occurred: ${error.message}`); + throw error; + } +} + +/** + * 現在のOSとアーキテクチャに基づいてバイナリのダウンロード先URLを定数のオブジェクトから取得する関数 + * @returns {string} バイナリをダウンロードするためのURL + */ +function getBinaryURL() { + const url = TYPOS_URLS[currentOS][currentCpuArchitecture]; + + if (!url) { + throw new Error( + `Unsupported OS or architecture: ${currentOS}, ${currentCpuArchitecture}`, + ); + } + + return url; +} + +/** + * バイナリをダウンロードして解凍し、実行権限を付与する関数 + * @param {Object} params - バイナリの情報を含むオブジェクト + * @param {string} params.url - ダウンロード先URL + */ +async function downloadAndUnarchive({ url }) { + const compressedFilePath = `${TYPOS_BINARY_PATH}/typos${currentOS === OS.WINDOWS ? ".zip" : ".tar.gz"}`; + + // バイナリディレクトリが存在する場合ダウンロードをスキップし、存在しない場合はディレクトリを作成する + if (existsSync(TYPOS_BINARY_PATH)) { + console.log(`typos already downloaded`); + return; + } else { + mkdirSync(TYPOS_BINARY_PATH, { recursive: true }); + } + + // node-fetchでバイナリをメモリ上にダウンロードした後、ローカルに保存する + const response = await fetch(url); + if (!response.ok) { + throw new Error(`Failed to download binary: ${response.statusText}`); + } + + const fileStream = createWriteStream(compressedFilePath); + await new Promise((resolve, reject) => { + response.body.pipe(fileStream); + response.body.on("error", reject); + fileStream.on("finish", resolve); + }); + + if (currentOS === OS.WINDOWS) { + // Windows用のZIPファイルを解凍 + await runCommand({ + command: `"${sevenZipBinaryPath}" x ${compressedFilePath} -o${TYPOS_BINARY_PATH}`, + description: `Extracting typos binary`, + }); + } else { + const archiveFilePath = `${TYPOS_BINARY_PATH}/typos.tar`; + + // .tar.gzファイルの解凍 + await runCommand({ + command: `"${sevenZipBinaryPath}" e ${compressedFilePath} -o${TYPOS_BINARY_PATH} -y`, + description: `Extracting typos.tar.gz file`, + }); + + // tarファイルの解凍 + await runCommand({ + command: `"${sevenZipBinaryPath}" x ${archiveFilePath} -o${TYPOS_BINARY_PATH} -y`, + description: `Extracting typos.tar file`, + }); + + // バイナリに実行権限を付与 + await runCommand({ + command: `chmod +x ${TYPOS_BINARY_PATH}/typos`, + description: `Granting execute permissions to typos binary`, + }); + + // 解凍後にアーカイブファイルを削除 + unlinkSync(archiveFilePath); + } + + // 解凍後に圧縮ファイルを削除 + unlinkSync(compressedFilePath); +} + +/** + * /build/vendored/typos ディレクトリから不要なファイルとディレクトリを削除する関数 + */ +function cleanupTyposDirectory() { + const typosDocDirPath = join(TYPOS_BINARY_PATH, "doc"); + const typosReadmeFilePath = join(TYPOS_BINARY_PATH, "README.md"); + + // doc ディレクトリの削除 + if (existsSync(typosDocDirPath)) { + rmSync(typosDocDirPath, { recursive: true }); + console.log(`Deleted directory: ${typosDocDirPath}`); + } + + // README.md ファイルの削除 + if (existsSync(typosReadmeFilePath)) { + unlinkSync(typosReadmeFilePath); + console.log(`Deleted file: ${typosReadmeFilePath}`); + } +} + +/** + * OSに応じてバイナリデータを処理する関数 + */ +async function main() { + const url = getBinaryURL(); + await downloadAndUnarchive({ url }); + + // 不要なファイルとディレクトリを削除 + cleanupTyposDirectory(); +} + +// main関数実行 +(async () => { + await main(); +})(); diff --git a/build/vendored/README.md b/build/vendored/README.md index 5d4a0839f5..01c2f840d9 100644 --- a/build/vendored/README.md +++ b/build/vendored/README.md @@ -2,6 +2,7 @@ このディレクトリはダウンロードしたファイルを格納するためのものです。 -| ディレクトリ名 | 内容 | ダウンローダー | -| -------------- | ------------------------------ | --------------------- | -| `7z` | [7-Zip](http://www.7-zip.org/) | `build/download7z.js` | +| ディレクトリ名 | 内容 | ダウンローダー | +| -------------- | ------------------------------------------ | ------------------------ | +| `7z` | [7-Zip](http://www.7-zip.org/) | `build/download7z.js` | +| `typos` | [typos](https://github.com/crate-ci/typos) | `build/downloadTypos.js` | diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index 77117ea2bd..0000000000 --- a/docker-compose.yml +++ /dev/null @@ -1,33 +0,0 @@ -version: '3' -services: - test: - build: . - working_dir: /work - # If you don't have node_modules, use "npm ci", install node_modules into the your directory. - # Use command bellow - # `docker-compose up -d --build` - # The container will stop automatically after install - # If you have node_modules already, you comment out '# command: "npm ci"' - - # command: "npm ci" - - - # After node_modules install, use command bellow to exec "/bin/sh" and the container will remain. - # `docker-compose up -d` - # To access container, use command bellow - # `docker exec -it voicevox_test_1 /bin/bash` - - # command: "/bin/sh" - - - # If you want test automatically (test runs when you save any files), use this command property and view logs - # Use Command bellow - # `docker logs --tail 1000 -f voicevox_test_1` - - command: "npm run test-watch:unit " - ports: - - 3000:3000 - volumes: - - .:/work:cached - tty: true - stdin_open: true diff --git a/package.json b/package.json index 7508edf019..45320e577d 100644 --- a/package.json +++ b/package.json @@ -25,11 +25,12 @@ "fmt": "eslint --ext .js,.vue,.ts *.config.* src tests build .storybook --fix", "markdownlint": "markdownlint --ignore node_modules/ --ignore dist/ --ignore dist_electron/ ./", "typecheck": "vue-tsc --noEmit", + "typos": "cross-env ./build/vendored/typos/typos", "electron:build": "cross-env VITE_TARGET=electron vite build && electron-builder --config electron-builder.config.js --publish never", "electron:serve": "cross-env VITE_TARGET=electron vite", "browser:serve": "cross-env VITE_TARGET=browser vite", "browser:build": "cross-env VITE_TARGET=browser vite build", - "postinstall": "patch-package --patch-dir build/patches && electron-builder install-app-deps && node build/download7z.js", + "postinstall": "patch-package --patch-dir build/patches && electron-builder install-app-deps && node build/download7z.js && node build/downloadTypos.js", "postuninstall": "electron-builder install-app-deps", "license:generate": "node build/generateLicenses.js", "license:merge": "node build/mergeLicenses.js",