From 00eec09d8db793f21dd35eb6c7912af14b7d31a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=9D=E3=82=89?= Date: Sun, 6 Oct 2024 13:41:11 +0800 Subject: [PATCH] refactor: switch scripts to esm --- .github/workflows/release.yml | 2 +- package.json | 6 +- pnpm-lock.yaml | 21 +++-- scripts/copy.mts | 17 ++++ scripts/copy.ts | 16 ---- scripts/docs.mts | 117 +++++++++++++++++++++++++ scripts/docs.ts | 116 ------------------------- scripts/release.mts | 157 ++++++++++++++++++++++++++++++++++ scripts/release.ts | 157 ---------------------------------- 9 files changed, 312 insertions(+), 297 deletions(-) create mode 100644 scripts/copy.mts delete mode 100644 scripts/copy.ts create mode 100644 scripts/docs.mts delete mode 100644 scripts/docs.ts create mode 100644 scripts/release.mts delete mode 100644 scripts/release.ts diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 53c5fa0..9ef0adc 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -44,7 +44,7 @@ jobs: run: pnpm build - name: Run release script - run: npx tsx ./scripts/release.ts + run: npx tsx ./scripts/release.mts env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} VSCE_TOKEN: ${{ secrets.VSCE_TOKEN }} diff --git a/package.json b/package.json index 565a3f0..c273dfa 100644 --- a/package.json +++ b/package.json @@ -5,8 +5,8 @@ "description": "Integrates phpfmt into VS Code", "main": "./dist/extension", "scripts": { - "build": "nr clean && tsc && tsup && tsx scripts/copy.ts", - "build:docs": "tsx scripts/docs.ts", + "build": "nr clean && tsc && tsup && tsx scripts/copy.mts", + "build:docs": "tsx scripts/docs.mts", "prebuild": "nr build:docs", "watch": "tsup --watch", "clean": "rimraf out", @@ -670,6 +670,8 @@ "@vscode/vsce": "^2.31.1", "adm-zip": "^0.5.10", "consola": "^3.2.3", + "debug": "^4.3.4", + "dirname-filename-esm": "^1.1.2", "eslint": "^8.57.0", "eslint-config-love": "^71.0.0", "eslint-config-prettier": "^9.1.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 88dffff..ad701da 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -63,6 +63,12 @@ importers: consola: specifier: ^3.2.3 version: 3.2.3 + debug: + specifier: ^4.3.4 + version: 4.3.7 + dirname-filename-esm: + specifier: ^1.1.2 + version: 1.1.2 eslint: specifier: ^8.57.0 version: 8.57.1 @@ -1032,6 +1038,9 @@ packages: resolution: {integrity: sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==} engines: {node: '>=0.3.1'} + dirname-filename-esm@1.1.2: + resolution: {integrity: sha512-mMhH2imzJN95KnX/iDAhC0QDG0VU833c88U3SXCaQzATu7YlO9YTFD/CF9Nn2xhSwFlV9iWEKb/YyGJ4TwCcPg==} + doctrine@2.1.0: resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} engines: {node: '>=0.10.0'} @@ -2933,7 +2942,7 @@ snapshots: '@kwsites/file-exists@1.1.1': dependencies: - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.7 transitivePeerDependencies: - supports-color @@ -3212,7 +3221,7 @@ snapshots: agent-base@6.0.2: dependencies: - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.7 transitivePeerDependencies: - supports-color @@ -3578,6 +3587,8 @@ snapshots: diff@5.0.0: {} + dirname-filename-esm@1.1.2: {} + doctrine@2.1.0: dependencies: esutils: 2.0.3 @@ -4214,7 +4225,7 @@ snapshots: dependencies: '@tootallnate/once': 1.1.2 agent-base: 6.0.2 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.7 transitivePeerDependencies: - supports-color @@ -4228,7 +4239,7 @@ snapshots: https-proxy-agent@5.0.1: dependencies: agent-base: 6.0.2 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.7 transitivePeerDependencies: - supports-color @@ -5080,7 +5091,7 @@ snapshots: dependencies: '@kwsites/file-exists': 1.1.1 '@kwsites/promise-deferred': 1.1.1 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.7 transitivePeerDependencies: - supports-color diff --git a/scripts/copy.mts b/scripts/copy.mts new file mode 100644 index 0000000..7cb4f53 --- /dev/null +++ b/scripts/copy.mts @@ -0,0 +1,17 @@ +import path from 'node:path'; +import fs from 'node:fs/promises'; +import phpfmt from 'phpfmt'; +import { dirname } from 'dirname-filename-esm'; + +const __dirname = dirname(import.meta); + +try { + const pkgPath = path.join(__dirname, '..'); + const distPath = path.join(pkgPath, 'dist'); + const destPath = path.join(distPath, phpfmt.v2.pharName); + const pharContent = await fs.readFile(phpfmt.v2.pharPath); + await fs.writeFile(destPath, pharContent); +} catch (err) { + console.error(err); + process.exit(1); +} diff --git a/scripts/copy.ts b/scripts/copy.ts deleted file mode 100644 index 4b7374f..0000000 --- a/scripts/copy.ts +++ /dev/null @@ -1,16 +0,0 @@ -import path from 'node:path'; -import fs from 'node:fs/promises'; -import phpfmt from 'phpfmt'; - -void (async () => { - try { - const pkgPath = path.join(__dirname, '..'); - const distPath = path.join(pkgPath, 'dist'); - const destPath = path.join(distPath, phpfmt.v2.pharName); - const pharContent = await fs.readFile(phpfmt.v2.pharPath); - await fs.writeFile(destPath, pharContent); - } catch (err) { - console.error(err); - process.exit(1); - } -})(); diff --git a/scripts/docs.mts b/scripts/docs.mts new file mode 100644 index 0000000..58a0c78 --- /dev/null +++ b/scripts/docs.mts @@ -0,0 +1,117 @@ +import path from 'node:path'; +import os from 'node:os'; +import fs from 'node:fs/promises'; +import phpfmt from 'phpfmt'; +import { dirname } from 'dirname-filename-esm'; + +const __dirname = dirname(import.meta); + +const pkgJsonPath = path.join(__dirname, '../package.json'); +const readmePath: string = path.join(__dirname, '../README.md'); + +try { + const pkg = JSON.parse(String(await fs.readFile(pkgJsonPath))); + const configuration = pkg.contributes.configuration; + + let config: string = + '| Key | Type | Description | Default |' + + os.EOL + + '| -------- | ----------- | ----------- | ----------- |' + + os.EOL; + + for (const configKey of Object.keys(configuration.properties)) { + const configValue = configuration.properties[configKey]; + config += `| ${configKey} | `; + + if (typeof configValue.type === 'string') { + config += `\`${configValue.type}\``; + } else if (Array.isArray(configValue.type)) { + config += `\`${configValue.type.join(' \\| ')}\``; + } + config += ` | ${configValue.description}`; + + if (typeof configValue.default === 'string') { + config += ` | "${configValue.default}"`; + } else if (typeof configValue.default === 'number') { + config += ` | ${configValue.default}`; + } else if ( + Array.isArray(configValue.default) || + typeof configValue.default === 'boolean' + ) { + config += ` | ${JSON.stringify(configValue.default)}`; + } else { + throw new Error('uncovered type'); + } + + config += ' | ' + os.EOL; + } + + let readmeContent = String(await fs.readFile(readmePath)); + readmeContent = readmeContent.replace( + /([\s\S]*)/, + () => { + return ( + '' + + os.EOL + + config + + os.EOL + + '' + ); + } + ); + + const { Transformation } = await import('../src/Transformation'); + const transformation = new Transformation('php', phpfmt.v2); + + const transformations = await transformation.getTransformations(); + + readmeContent = readmeContent.replace( + /([\s\S]*)/, + () => { + return ( + '' + + os.EOL + + '| Key | Description |' + + os.EOL + + '| -------- | ----------- |' + + os.EOL + + transformations + .map(item => { + let row = `| ${item.key} | `; + row += item.description; + row += ' |'; + return row; + }) + .join(os.EOL) + + os.EOL + + '' + ); + } + ); + const passes = transformation.getPasses(); + + const enums = passes.map(pass => { + const p = transformations.find(t => t.key === pass); + return { + enum: pass, + description: p?.description ?? 'Core pass' + }; + }); + + pkg.contributes.configuration.properties['phpfmt.passes'].items.enum = + enums.map(o => o.enum); + pkg.contributes.configuration.properties[ + 'phpfmt.passes' + ].items.enumDescriptions = enums.map(o => o.description); + pkg.contributes.configuration.properties['phpfmt.exclude'].items.enum = + enums.map(o => o.enum); + pkg.contributes.configuration.properties[ + 'phpfmt.exclude' + ].items.enumDescriptions = enums.map(o => o.description); + + await fs.writeFile(readmePath, readmeContent); + await fs.writeFile(pkgJsonPath, JSON.stringify(pkg, null, 2) + os.EOL); +} catch (err) { + console.error(err); + process.exit(1); +} diff --git a/scripts/docs.ts b/scripts/docs.ts deleted file mode 100644 index 6fd4e72..0000000 --- a/scripts/docs.ts +++ /dev/null @@ -1,116 +0,0 @@ -import path from 'node:path'; -import os from 'node:os'; -import fs from 'node:fs/promises'; -import phpfmt from 'phpfmt'; -import { Transformation } from '../src/Transformation'; - -const pkgJsonPath = path.join(__dirname, '../package.json'); -const readmePath: string = path.join(__dirname, '../README.md'); - -void (async () => { - try { - const pkg = JSON.parse(String(await fs.readFile(pkgJsonPath))); - const configuration = pkg.contributes.configuration; - - let config: string = - '| Key | Type | Description | Default |' + - os.EOL + - '| -------- | ----------- | ----------- | ----------- |' + - os.EOL; - - for (const configKey of Object.keys(configuration.properties)) { - const configValue = configuration.properties[configKey]; - config += `| ${configKey} | `; - - if (typeof configValue.type === 'string') { - config += `\`${configValue.type}\``; - } else if (Array.isArray(configValue.type)) { - config += `\`${configValue.type.join(' \\| ')}\``; - } - config += ` | ${configValue.description}`; - - if (typeof configValue.default === 'string') { - config += ` | "${configValue.default}"`; - } else if (typeof configValue.default === 'number') { - config += ` | ${configValue.default}`; - } else if ( - Array.isArray(configValue.default) || - typeof configValue.default === 'boolean' - ) { - config += ` | ${JSON.stringify(configValue.default)}`; - } else { - throw new Error('uncovered type'); - } - - config += ' | ' + os.EOL; - } - - let readmeContent = String(await fs.readFile(readmePath)); - readmeContent = readmeContent.replace( - /([\s\S]*)/, - () => { - return ( - '' + - os.EOL + - config + - os.EOL + - '' - ); - } - ); - - const transformation = new Transformation('php', phpfmt.v2); - - const transformations = await transformation.getTransformations(); - - readmeContent = readmeContent.replace( - /([\s\S]*)/, - () => { - return ( - '' + - os.EOL + - '| Key | Description |' + - os.EOL + - '| -------- | ----------- |' + - os.EOL + - transformations - .map(item => { - let row = `| ${item.key} | `; - row += item.description; - row += ' |'; - return row; - }) - .join(os.EOL) + - os.EOL + - '' - ); - } - ); - const passes = transformation.getPasses(); - - const enums = passes.map(pass => { - const p = transformations.find(t => t.key === pass); - return { - enum: pass, - description: p?.description ?? 'Core pass' - }; - }); - - pkg.contributes.configuration.properties['phpfmt.passes'].items.enum = - enums.map(o => o.enum); - pkg.contributes.configuration.properties[ - 'phpfmt.passes' - ].items.enumDescriptions = enums.map(o => o.description); - pkg.contributes.configuration.properties['phpfmt.exclude'].items.enum = - enums.map(o => o.enum); - pkg.contributes.configuration.properties[ - 'phpfmt.exclude' - ].items.enumDescriptions = enums.map(o => o.description); - - await fs.writeFile(readmePath, readmeContent); - await fs.writeFile(pkgJsonPath, JSON.stringify(pkg, null, 2) + os.EOL); - } catch (err) { - console.error(err); - process.exit(1); - } -})(); diff --git a/scripts/release.mts b/scripts/release.mts new file mode 100644 index 0000000..2d87b5e --- /dev/null +++ b/scripts/release.mts @@ -0,0 +1,157 @@ +/* eslint-disable n/no-sync */ +/* eslint no-console: error */ +import path from 'node:path'; +import os from 'node:os'; +import { execSync } from 'node:child_process'; +import fs from 'node:fs/promises'; +import phpfmt from 'phpfmt'; +import AdmZip from 'adm-zip'; +import md5 from 'md5'; +import * as semver from 'semver'; +import debug from 'debug'; +import { simpleGit } from 'simple-git'; +import { consola } from 'consola'; +import { dirname } from 'dirname-filename-esm'; + +const __dirname = dirname(import.meta); + +debug.enable('simple-git,simple-git:*'); + +const pkgJsonPath = path.join(__dirname, '../package.json'); +const changelogPath = path.join(__dirname, '../CHANGELOG.md'); + +const { downloadFile, exec } = await import('../src/utils'); + +try { + const pkg = JSON.parse(String(await fs.readFile(pkgJsonPath))); + const currentVersion = pkg.version; + + const vsceBin = path.join(__dirname, '../node_modules/.bin/vsce'); + const { stdout: versionListOut } = await exec( + `${vsceBin} show kokororin.vscode-phpfmt --json` + ); + const versionList = JSON.parse(versionListOut); + const latestVersion = versionList.versions[0].version; + + const pharUrl = phpfmt.v2.installUrl; + const pharVersionUrl = phpfmt.v2.installUrl.replace( + phpfmt.v2.pharName, + 'version.txt' + ); + + consola.info(`Download url: ${pharUrl}`); + + const tmpDir = path.join(os.tmpdir(), 'vscode-phpfmt'); + await fs.mkdir(tmpDir, { recursive: true }); + const currentVsixPath = path.join(tmpDir, `${latestVersion}.vsix`); + const latestPharPath = path.join(tmpDir, phpfmt.v2.pharName); + const latestPharVersionPath = path.join( + tmpDir, + `${phpfmt.v2.pharName}.version.txt` + ); + + consola.info('Downloading vsix...'); + await downloadFile( + `https://kokororin.gallery.vsassets.io/_apis/public/gallery/publisher/kokororin/extension/vscode-phpfmt/${latestVersion}/assetbyname/Microsoft.VisualStudio.Services.VSIXPackage`, + currentVsixPath + ); + + const stats = await fs.stat(currentVsixPath); + if (stats.size < 10000) { + throw new Error('Download vsix failed'); + } + + const zip = new AdmZip(currentVsixPath); + const zipEntries = zip.getEntries(); + const entry = zipEntries.find( + o => o.entryName === `extension/dist/${phpfmt.v2.pharName}` + ); + if (entry == null) { + throw new Error('Not found phar in vsix'); + } + + const currentPharData = String(entry.getData()); + const currentMd5 = md5(currentPharData); + consola.info(`Current md5: ${currentMd5}`); + + consola.info('Downloading latest phar...'); + await downloadFile(pharUrl, latestPharPath); + await downloadFile(pharVersionUrl, latestPharVersionPath); + const latestPharData = String(await fs.readFile(latestPharPath)); + const latestPharVersion = String(await fs.readFile(latestPharVersionPath)); + consola.info(`Latest phar version: ${latestPharVersion}`); + + const latestMd5 = md5(latestPharData); + consola.info(`Latest md5: ${latestMd5}`); + + if (currentMd5 === latestMd5) { + consola.info('Md5 is same'); + process.exit(0); + } + + const newVersion = semver.inc(currentVersion, 'patch'); + consola.info(`New version: ${newVersion}`); + + let changelogData = String(await fs.readFile(changelogPath)); + changelogData = `### ${newVersion} + +- Upgrade ${phpfmt.v2.pharName} [(V${latestPharVersion})](https://github.com/driade/phpfmt8/releases/tag/v${latestPharVersion}) + +${changelogData}`; + await fs.writeFile(changelogPath, changelogData); + + pkg.version = newVersion; + await fs.writeFile(pkgJsonPath, JSON.stringify(pkg, null, 2) + os.EOL); + + await fs.writeFile(phpfmt.v2.pharPath, latestPharData); + + const git = simpleGit({ + config: [ + 'credential.https://github.com/.helper="! f() { echo username=x-access-token; echo password=$GITHUB_TOKEN; };f"' + ] + }); + await git + .addConfig('user.name', 'github-actions[bot]') + .addConfig( + 'user.email', + '41898282+github-actions[bot]@users.noreply.github.com' + ) + .add('.') + .commit(`release: ${newVersion}`) + .addTag(`v${newVersion}`) + .push() + .pushTags(); + + // Publish to NPM + try { + execSync('npm publish --ignore-scripts', { + stdio: 'inherit', + env: { + NODE_AUTH_TOKEN: process.env.NODE_AUTH_TOKEN + } + }); + } catch (err) { + consola.error(err); + } + + // Publish to VSCE + try { + execSync(`vsce publish -p ${process.env.VSCE_TOKEN} --no-dependencies`, { + stdio: 'inherit' + }); + } catch (err) { + consola.error(err); + } + + // Publish to OVSX + try { + execSync(`ovsx publish -p ${process.env.OVSX_TOKEN} --no-dependencies`, { + stdio: 'inherit' + }); + } catch (err) { + consola.error(err); + } +} catch (err) { + consola.error(err); + process.exit(1); +} diff --git a/scripts/release.ts b/scripts/release.ts deleted file mode 100644 index 2dca143..0000000 --- a/scripts/release.ts +++ /dev/null @@ -1,157 +0,0 @@ -/* eslint-disable n/no-sync */ -/* eslint no-console: error */ -import path from 'node:path'; -import os from 'node:os'; -import { execSync } from 'node:child_process'; -import fs from 'node:fs/promises'; -import phpfmt from 'phpfmt'; -import AdmZip from 'adm-zip'; -import md5 from 'md5'; -import * as semver from 'semver'; -import debug from 'debug'; -import { simpleGit } from 'simple-git'; -import { consola } from 'consola'; -import { downloadFile, exec } from '../src/utils'; - -debug.enable('simple-git,simple-git:*'); - -const pkgJsonPath = path.join(__dirname, '../package.json'); -const changelogPath = path.join(__dirname, '../CHANGELOG.md'); - -void (async () => { - try { - const pkg = JSON.parse(String(await fs.readFile(pkgJsonPath))); - const currentVersion = pkg.version; - - const vsceBin = path.join(__dirname, '../node_modules/.bin/vsce'); - const { stdout: versionListOut } = await exec( - `${vsceBin} show kokororin.vscode-phpfmt --json` - ); - const versionList = JSON.parse(versionListOut); - const latestVersion = versionList.versions[0].version; - - const pharUrl = phpfmt.v2.installUrl; - const pharVersionUrl = phpfmt.v2.installUrl.replace( - phpfmt.v2.pharName, - 'version.txt' - ); - - consola.info(`Download url: ${pharUrl}`); - - const tmpDir = path.join(os.tmpdir(), 'vscode-phpfmt'); - await fs.mkdir(tmpDir, { recursive: true }); - const currentVsixPath = path.join(tmpDir, `${latestVersion}.vsix`); - const latestPharPath = path.join(tmpDir, phpfmt.v2.pharName); - const latestPharVersionPath = path.join( - tmpDir, - `${phpfmt.v2.pharName}.version.txt` - ); - - consola.info('Downloading vsix...'); - await downloadFile( - `https://kokororin.gallery.vsassets.io/_apis/public/gallery/publisher/kokororin/extension/vscode-phpfmt/${latestVersion}/assetbyname/Microsoft.VisualStudio.Services.VSIXPackage`, - currentVsixPath - ); - - const stats = await fs.stat(currentVsixPath); - if (stats.size < 10000) { - consola.error('Download vsix failed'); - return; - } - - const zip = new AdmZip(currentVsixPath); - const zipEntries = zip.getEntries(); - const entry = zipEntries.find( - o => o.entryName === `extension/dist/${phpfmt.v2.pharName}` - ); - if (entry == null) { - consola.error('Not found phar in vsix'); - return; - } - - const currentPharData = String(entry.getData()); - const currentMd5 = md5(currentPharData); - consola.info(`Current md5: ${currentMd5}`); - - consola.info('Downloading latest phar...'); - await downloadFile(pharUrl, latestPharPath); - await downloadFile(pharVersionUrl, latestPharVersionPath); - const latestPharData = String(await fs.readFile(latestPharPath)); - const latestPharVersion = String(await fs.readFile(latestPharVersionPath)); - consola.info(`Latest phar version: ${latestPharVersion}`); - - const latestMd5 = md5(latestPharData); - consola.info(`Latest md5: ${latestMd5}`); - - if (currentMd5 === latestMd5) { - consola.info('Md5 is same'); - return; - } - - const newVersion = semver.inc(currentVersion, 'patch'); - consola.info(`New version: ${newVersion}`); - - let changelogData = String(await fs.readFile(changelogPath)); - changelogData = `### ${newVersion} - -- Upgrade ${phpfmt.v2.pharName} [(V${latestPharVersion})](https://github.com/driade/phpfmt8/releases/tag/v${latestPharVersion}) - -${changelogData}`; - await fs.writeFile(changelogPath, changelogData); - - pkg.version = newVersion; - await fs.writeFile(pkgJsonPath, JSON.stringify(pkg, null, 2) + os.EOL); - - await fs.writeFile(phpfmt.v2.pharPath, latestPharData); - - const git = simpleGit({ - config: [ - 'credential.https://github.com/.helper="! f() { echo username=x-access-token; echo password=$GITHUB_TOKEN; };f"' - ] - }); - await git - .addConfig('user.name', 'github-actions[bot]') - .addConfig( - 'user.email', - '41898282+github-actions[bot]@users.noreply.github.com' - ) - .add('.') - .commit(`release: ${newVersion}`) - .addTag(`v${newVersion}`) - .push() - .pushTags(); - - // Publish to NPM - try { - execSync('npm publish --ignore-scripts', { - stdio: 'inherit', - env: { - NODE_AUTH_TOKEN: process.env.NODE_AUTH_TOKEN - } - }); - } catch (err) { - consola.error(err); - } - - // Publish to VSCE - try { - execSync(`vsce publish -p ${process.env.VSCE_TOKEN} --no-dependencies`, { - stdio: 'inherit' - }); - } catch (err) { - consola.error(err); - } - - // Publish to OVSX - try { - execSync(`ovsx publish -p ${process.env.OVSX_TOKEN} --no-dependencies`, { - stdio: 'inherit' - }); - } catch (err) { - consola.error(err); - } - } catch (err) { - consola.error(err); - process.exit(1); - } -})();