UNPKG

pi-lens

Version:

Real-time code feedback for pi — LSP, linters, formatters, type-checking, structural analysis & booboo

85 lines (84 loc) • 2.44 kB
/** * Go Client for pi-lens * * Provides Go type checking and linting via gopls and go vet. * * Requires: gopls (go install golang.org/x/tools/gopls@latest) * Docs: https://pkg.go.dev/golang.org/x/tools/gopls */ import * as fs from "node:fs"; import * as path from "node:path"; import { safeSpawnAsync } from "./safe-spawn.js"; // --- Common install paths --- const GO_WINDOWS_PATHS = [ "C:\\Program Files\\Go\\bin\\go.exe", "C:\\Go\\bin\\go.exe", "go.exe", // PATH ]; const GO_UNIX_PATHS = [ "/usr/local/go/bin/go", "/usr/bin/go", "go", // PATH ]; // --- Client --- export class GoClient { goAvailable = null; goPath = null; log; constructor(verbose = false) { this.log = verbose ? (msg) => console.error(`[go] ${msg}`) : () => { }; } /** * Find go executable path (async — probes PATH candidates off the event loop). */ async findGoPathAsync() { if (this.goPath) return this.goPath; const paths = process.platform === "win32" ? GO_WINDOWS_PATHS : GO_UNIX_PATHS; for (const p of paths) { try { if (p.includes("\\") || p.includes("/")) { // Absolute path - check if exists if (fs.existsSync(p)) { this.goPath = p; return p; } } else { // Relative (PATH) - try running it const result = await safeSpawnAsync(p, ["version"], { timeout: 3000, }); if (!result.error && result.status === 0) { this.goPath = p; return p; } } } catch (err) { void err; } } return null; } /** * Check if Go is installed (cached) */ async isGoAvailableAsync() { if (this.goAvailable !== null) return this.goAvailable; this.goAvailable = (await this.findGoPathAsync()) !== null; if (this.goAvailable) { this.log(`Go found: ${this.goPath}`); } return this.goAvailable; } /** * Check if a file is a Go file */ isGoFile(filePath) { return path.extname(filePath).toLowerCase() === ".go"; } }