From f93f8d2231fa810feb3ef83e9c2beb1e8043d841 Mon Sep 17 00:00:00 2001 From: Gabriele Picco Date: Thu, 22 Feb 2024 15:41:21 +0100 Subject: [PATCH] :package: Add parent package --- .github/workflows/publish-packages.yml | 4 +- .gitignore | 5 ++ cli/npm-package/.eslintignore | 2 + cli/npm-package/.eslintrc | 15 ++++ cli/npm-package/{bolt => bolt.ts} | 79 ++++++++++++--------- cli/npm-package/package.json | 24 ++++++- cli/npm-package/scripts/setupNpmRegistry.js | 31 ++++++++ cli/npm-package/tsconfig.json | 13 ++++ 8 files changed, 135 insertions(+), 38 deletions(-) create mode 100644 cli/npm-package/.eslintignore create mode 100644 cli/npm-package/.eslintrc rename cli/npm-package/{bolt => bolt.ts} (52%) mode change 100644 => 100755 create mode 100644 cli/npm-package/scripts/setupNpmRegistry.js create mode 100644 cli/npm-package/tsconfig.json diff --git a/.github/workflows/publish-packages.yml b/.github/workflows/publish-packages.yml index bf88fb2..8322bf1 100644 --- a/.github/workflows/publish-packages.yml +++ b/.github/workflows/publish-packages.yml @@ -30,7 +30,7 @@ jobs: # OS: windows-2022, # TOOLCHAIN: stable, # TARGET: x86_64-pc-windows-msvc, - } +# } - { NAME: win32-arm64-msvc, OS: windows-2022, @@ -48,7 +48,7 @@ jobs: # OS: macos-11, # TOOLCHAIN: stable, # TARGET: aarch64-apple-darwin, - } +# } steps: - name: Checkout uses: actions/checkout@v4 diff --git a/.gitignore b/.gitignore index c58e316..ca5423d 100644 --- a/.gitignore +++ b/.gitignore @@ -16,4 +16,9 @@ tests/examples/target tests/examples/node_modules tests/examples/.yarn +cli/npm-package/lib +cli/npm-package/.npmrc +cli/npm-package/.yarnrc +.npmrc +.yarnrc diff --git a/cli/npm-package/.eslintignore b/cli/npm-package/.eslintignore new file mode 100644 index 0000000..28a0782 --- /dev/null +++ b/cli/npm-package/.eslintignore @@ -0,0 +1,2 @@ +lib/** +scripts/** \ No newline at end of file diff --git a/cli/npm-package/.eslintrc b/cli/npm-package/.eslintrc new file mode 100644 index 0000000..f0f1fe9 --- /dev/null +++ b/cli/npm-package/.eslintrc @@ -0,0 +1,15 @@ +{ + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended" + ], + "parser": "@typescript-eslint/parser", + "plugins": [ + "@typescript-eslint" + ], + "ignorePatterns": [ + "lib/**", + "scripts/**" + ], + "root": true +} diff --git a/cli/npm-package/bolt b/cli/npm-package/bolt.ts old mode 100644 new mode 100755 similarity index 52% rename from cli/npm-package/bolt rename to cli/npm-package/bolt.ts index 02fb7a0..b118da1 --- a/cli/npm-package/bolt +++ b/cli/npm-package/bolt.ts @@ -1,85 +1,96 @@ #!/usr/bin/env node -const fs = require("fs"); -const { spawn, spawnSync } = require("child_process"); -const path = require("path"); -const { arch, platform } = require("os"); -const { version } = require("./package.json"); +import fs from "fs"; +import { spawn, spawnSync } from "child_process"; +import path from "path"; +import { arch, platform } from "os"; +import { version } from "./package.json"; const PACKAGE_VERSION = `bolt-cli ${version}`; -const PACKAGE_BOLT_PATH = path.join(__dirname, "bolt"); -function getBinaryVersion(location) { +function getBinaryVersion(location: string): [string | null, string | null] { const result = spawnSync(location, ["--version"]); - const error = + const error: string | null = (result.error && result.error.toString()) || (result.stderr.length > 0 && result.stderr.toString().trim()) || null; return [error, result.stdout && result.stdout.toString().trim()]; } -function runBolt(location) { +function getExePath(): string { + let os: string = platform(); + let extension = ""; + if (["win32", "cygwin"].includes(os)) { + os = "windows"; + extension = ".exe"; + } + + const binaryName = `@magicblock-labs/bolt-${os}-${arch()}/bin/app${extension}`; + try { + return require.resolve(binaryName); + } catch (e) { + throw new Error( + `Couldn't find application binary inside node_modules for ${os}-${arch()}` + ); + } +} + +function runBolt(location: string): void { const args = process.argv.slice(2); const bolt = spawn(location, args, { stdio: "inherit" }); - bolt.on("exit", (code, signal) => { + bolt.on("exit", (code: number | null, signal: NodeJS.Signals | null) => { process.on("exit", () => { if (signal) { process.kill(process.pid, signal); - } else { + } else if (code !== null) { process.exit(code); } }); }); - process.on("SIGINT", function () { + process.on("SIGINT", () => { bolt.kill("SIGINT"); bolt.kill("SIGTERM"); }); } -function tryPackageBolt() { - if (arch() !== "x64" || platform() !== "linux") { - console.error(`Only x86_64 / Linux distributed in NPM package right now.`); - return false; - } - - const [error, binaryVersion] = getBinaryVersion(PACKAGE_BOLT_PATH); - if (error !== null) { - console.error(`Failed to get version of local binary: ${error}`); - return false; - } - if (binaryVersion !== PACKAGE_VERSION) { +function tryPackageBolt(): boolean { + try { + const path = getExePath(); + runBolt(path); + return true; + } catch (e) { console.error( - `Package binary version is not correct. Expected "${PACKAGE_VERSION}", found "${binaryVersion}".` + "Failed to run bolt from package:", + e instanceof Error ? e.message : e ); return false; } - - runBolt(PACKAGE_BOLT_PATH); - return true; } -function trySystemBolt() { +function trySystemBolt(): void { console.error("Trying globally installed bolt."); - const absolutePath = process.env.PATH.split(":") + const absolutePath = process.env.PATH?.split(path.delimiter) .filter((dir) => dir !== path.dirname(process.argv[1])) .find((dir) => { try { fs.accessSync(`${dir}/bolt`, fs.constants.X_OK); + return true; } catch { return false; } - return true; }); if (!absolutePath) { - console.error(`Could not find globally installed bolt, install with cargo.`); - process.exit(); + console.error( + `Could not find globally installed bolt, install with cargo.` + ); + process.exit(1); } const absoluteBinaryPath = `${absolutePath}/bolt`; - const [error, binaryVersion] = getBinaryVersion(absoluteBinaryPath); + if (error !== null) { console.error(`Failed to get version of global binary: ${error}`); return; diff --git a/cli/npm-package/package.json b/cli/npm-package/package.json index 72ed8a3..55169b0 100644 --- a/cli/npm-package/package.json +++ b/cli/npm-package/package.json @@ -12,10 +12,30 @@ }, "license": "MIT", "bin": { - "bolt": "./bolt.js" + "bolt": "lib/bolt.js" }, "scripts": { - "prepack": "[ \"$(uname -op)\" != \"x86_64 GNU/Linux\" ] && (echo Can be packed only on x86_64 GNU/Linux && exit 1) || ([ \"$(./bolt --version)\" != \"bolt-cli $(jq -r .version package.json)\" ] && (echo Check bolt binary version && exit 2) || exit 0)" + "postinstall": "node scripts/setupNpmRegistry.js", + "typecheck": "tsc --noEmit", + "lint": "eslint .", + "lint:fix": "eslint . --fix", + "build": "tsc", + "dev": "yarn build && node lib/index.js" + }, + "devDependencies": { + "@types/node": "^20.8.8", + "@typescript-eslint/eslint-plugin": "^5.48.0", + "@typescript-eslint/parser": "^5.48.0", + "eslint": "^8.31.0", + "typescript": "^4.9.4" + }, + "optionalDependencies": { + "@magicblock-labs/bolt-linux-x64": "0.0.1", + "@magicblock-labs/bolt-linux-arm64": "0.0.1", + "@magicblock-labs/bolt-darwin-x64": "0.0.1", + "@magicblock-labs/bolt-darwin-arm64": "0.0.1", + "@magicblock-labs/bolt-windows-x64": "0.0.1", + "@magicblock-labs/bolt-windows-arm64": "0.0.1" }, "publishConfig": { "access": "public" diff --git a/cli/npm-package/scripts/setupNpmRegistry.js b/cli/npm-package/scripts/setupNpmRegistry.js new file mode 100644 index 0000000..a2723e0 --- /dev/null +++ b/cli/npm-package/scripts/setupNpmRegistry.js @@ -0,0 +1,31 @@ +const fs = require("fs"); +const path = require("path"); + +// Configuration for both npm and Yarn +const npmrcPath = path.join(process.cwd(), ".npmrc"); +const yarnrcPath = path.join(process.cwd(), ".yarnrc"); +const npmConfigLine = + "@magicblock-labs:registry=https://npm.pkg.github.com/magicblock-labs\n"; +const yarnConfigLine = + '"@magicblock-labs:registry" "https://npm.pkg.github.com/magicblock-labs"\n'; + +// Function to update or create a configuration file +function updateOrCreateConfig(filePath, configLine) { + try { + if (fs.existsSync(filePath)) { + const content = fs.readFileSync(filePath, { encoding: "utf8" }); + if (!content.includes(configLine)) { + fs.appendFileSync(filePath, configLine); + } + } else { + fs.writeFileSync(filePath, configLine); + } + console.log(`${path.basename(filePath)} configured successfully.`); + } catch (error) { + console.error(`Error configuring ${path.basename(filePath)}:`, error); + } +} + +// Update or create both .npmrc and .yarnrc +updateOrCreateConfig(npmrcPath, npmConfigLine); +updateOrCreateConfig(yarnrcPath, yarnConfigLine); diff --git a/cli/npm-package/tsconfig.json b/cli/npm-package/tsconfig.json new file mode 100644 index 0000000..a9f8699 --- /dev/null +++ b/cli/npm-package/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "target": "es2016", + "module": "commonjs", + "esModuleInterop": true, + "resolveJsonModule": true, + "baseUrl": "./", + "outDir": "lib", + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + } +} \ No newline at end of file