Files
2026Technology-Competition/docs/superpowers/specs/implementation-steps/19-phase6.2-tool-scripts.md
T

3.1 KiB

Step 19 — Phase 6.2: 工具脚本

依赖: Step 18
参考设计: §15, §17

目标

实现 PMD JAR 下载脚本和生产打包脚本。

文件变更

# 文件 操作 说明
1 scripts/download-pmd.mjs 新建 下载 PMD 7.26.0 JAR 依赖
2 scripts/package-prod.mjs 新建 生产打包脚本
3 package.json 修改 添加 download-pmd / package-prod 脚本

前置准备

npm install --save-dev @vscode/vsce@^3.9.2

1. scripts/download-pmd.mjs

import { execSync } from 'child_process';
import { existsSync, mkdirSync, createWriteStream } from 'fs';
import { resolve, dirname } from 'path';
import { fileURLToPath } from 'url';
import { get } from 'https';
import { unlinkSync, readdirSync } from 'fs';

const __dirname = dirname(fileURLToPath(import.meta.url));
const rootDir = resolve(__dirname, '..');
const libDir = resolve(rootDir, 'jars', 'pmd', 'lib');

const PMD_VERSION = '7.26.0';
const PMD_JARS = [
  `pmd-core-${PMD_VERSION}.jar`,
  `pmd-java-${PMD_VERSION}.jar`,
  `pmd-javascript-${PMD_VERSION}.jar`,
  `pmd-jsp-${PMD_VERSION}.jar`,
];

const MAVEN_BASE = `https://repo1.maven.org/maven2/net/sourceforge/pmd`;

function downloadFile(url, dest) {
  return new Promise((resolve, reject) => {
    const file = createWriteStream(dest);
    get(url, (response) => {
      if (response.statusCode === 302 || response.statusCode === 301) {
        downloadFile(response.headers.location, dest).then(resolve).catch(reject);
        return;
      }
      response.pipe(file);
      file.on('finish', () => { file.close(); resolve(); });
      file.on('error', (err) => { unlinkSync(dest); reject(err); });
    }).on('error', (err) => { unlinkSync(dest); reject(err); });
  });
}

if (!existsSync(libDir)) {
  mkdirSync(libDir, { recursive: true });
}

for (const jar of PMD_JARS) {
  const moduleName = jar.replace(`-${PMD_VERSION}.jar`, '').replace('pmd-', '');
  const url = `${MAVEN_BASE}/pmd-${moduleName}/${PMD_VERSION}/${jar}`;
  const dest = resolve(libDir, jar);

  if (existsSync(dest)) {
    console.log(`Skip: ${jar} (exists)`);
    continue;
  }

  console.log(`Downloading: ${url}`);
  await downloadFile(url, dest);
  console.log(`Done: ${jar}`);
}

console.log('PMD JARs download complete.');

2. scripts/package-prod.mjs

import { execSync } from 'child_process';
import { resolve, dirname } from 'path';
import { fileURLToPath } from 'url';

const __dirname = dirname(fileURLToPath(import.meta.url));
const rootDir = resolve(__dirname, '..');

execSync('node scripts/build.mjs', { cwd: rootDir, stdio: 'inherit' });
execSync('npx vsce package', { cwd: rootDir, stdio: 'inherit' });

console.log('Production package complete.');

3. package.json 脚本更新

{
  "scripts": {
    "download-pmd": "node scripts/download-pmd.mjs",
    "package-prod": "node scripts/package-prod.mjs"
  }
}

验收

  • npm run download-pmd 成功下载 PMD JAR 到 jars/pmd/lib/
  • npm run package-prod 成功生成 .vsix 文件
  • .vsix 可安装到 VSCode