bolt.ts 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. #!/usr/bin/env node
  2. import fs from "fs";
  3. import { spawn, spawnSync } from "child_process";
  4. import path from "path";
  5. import { arch, platform } from "os";
  6. import { version } from "./package.json";
  7. const PACKAGE_VERSION = `bolt-cli ${version}`;
  8. function getBinaryVersion(location: string): [string | null, string | null] {
  9. const result = spawnSync(location, ["--version"]);
  10. const error: string | null =
  11. (result.error && result.error.toString()) ||
  12. (result.stderr.length > 0 && result.stderr.toString().trim()) ||
  13. null;
  14. return [error, result.stdout && result.stdout.toString().trim()];
  15. }
  16. function getExePath(): string {
  17. let os: string = platform();
  18. let extension = "";
  19. if (["win32", "cygwin"].includes(os)) {
  20. os = "windows";
  21. extension = ".exe";
  22. }
  23. const binaryName = `@magicblock-labs/bolt-cli-${os}-${arch()}/bin/bolt${extension}`;
  24. try {
  25. return require.resolve(binaryName);
  26. } catch (e) {
  27. throw new Error(
  28. `Couldn't find application binary inside node_modules for ${os}-${arch()}`
  29. );
  30. }
  31. }
  32. function runBolt(location: string): void {
  33. const args = process.argv.slice(2);
  34. const bolt = spawn(location, args, { stdio: "inherit" });
  35. bolt.on("exit", (code: number | null, signal: NodeJS.Signals | null) => {
  36. process.on("exit", () => {
  37. if (signal) {
  38. process.kill(process.pid, signal);
  39. } else if (code !== null) {
  40. process.exit(code);
  41. }
  42. });
  43. });
  44. process.on("SIGINT", () => {
  45. bolt.kill("SIGINT");
  46. bolt.kill("SIGTERM");
  47. });
  48. }
  49. function tryPackageBolt(): boolean {
  50. try {
  51. const path = getExePath();
  52. runBolt(path);
  53. return true;
  54. } catch (e) {
  55. console.error(
  56. "Failed to run bolt from package:",
  57. e instanceof Error ? e.message : e
  58. );
  59. return false;
  60. }
  61. }
  62. function trySystemBolt(): void {
  63. const absolutePath = process.env.PATH?.split(path.delimiter)
  64. .filter((dir) => dir !== path.dirname(process.argv[1]))
  65. .find((dir) => {
  66. try {
  67. fs.accessSync(`${dir}/bolt`, fs.constants.X_OK);
  68. return true;
  69. } catch {
  70. return false;
  71. }
  72. });
  73. if (!absolutePath) {
  74. console.error(
  75. `Could not find globally installed bolt, please install with cargo.`
  76. );
  77. process.exit(1);
  78. }
  79. const absoluteBinaryPath = `${absolutePath}/bolt`;
  80. const [error, binaryVersion] = getBinaryVersion(absoluteBinaryPath);
  81. if (error !== null) {
  82. console.error(`Failed to get version of global binary: ${error}`);
  83. return;
  84. }
  85. if (binaryVersion !== PACKAGE_VERSION) {
  86. console.error(
  87. `Globally installed bolt version is not correct. Expected "${PACKAGE_VERSION}", found "${binaryVersion}".`
  88. );
  89. return;
  90. }
  91. runBolt(absoluteBinaryPath);
  92. }
  93. tryPackageBolt() || trySystemBolt();