export function getBinPathWithPreferredGopathGorootWithExplanation()

in src/utils/pathUtils.ts [56:123]


export function getBinPathWithPreferredGopathGorootWithExplanation(
	toolName: string,
	preferredGopaths: string[],
	preferredGoroot?: string,
	alternateTool?: string,
	useCache = true
): { binPath: string; why?: string } {
	if (alternateTool && path.isAbsolute(alternateTool) && executableFileExists(alternateTool)) {
		binPathCache[toolName] = alternateTool;
		return { binPath: alternateTool, why: 'alternateTool' };
	}

	// FIXIT: this cache needs to be invalidated when go.goroot or go.alternateTool is changed.
	if (useCache && binPathCache[toolName]) {
		return { binPath: binPathCache[toolName], why: 'cached' };
	}

	const binname = alternateTool && !path.isAbsolute(alternateTool) ? alternateTool : toolName;
	const found = (why: string) => (binname === toolName ? why : 'alternateTool');
	const pathFromGoBin = getBinPathFromEnvVar(binname, process.env['GOBIN'], false);
	if (pathFromGoBin) {
		binPathCache[toolName] = pathFromGoBin;
		return { binPath: pathFromGoBin, why: binname === toolName ? 'gobin' : 'alternateTool' };
	}

	for (const preferred of preferredGopaths) {
		if (typeof preferred === 'string') {
			// Search in the preferred GOPATH workspace's bin folder
			const pathFrompreferredGoPath = getBinPathFromEnvVar(binname, preferred, true);
			if (pathFrompreferredGoPath) {
				binPathCache[toolName] = pathFrompreferredGoPath;
				return { binPath: pathFrompreferredGoPath, why: found('gopath') };
			}
		}
	}

	// Check GOROOT (go, gofmt, godoc would be found here)
	const pathFromGoRoot = getBinPathFromEnvVar(binname, preferredGoroot || getCurrentGoRoot(), true);
	if (pathFromGoRoot) {
		binPathCache[toolName] = pathFromGoRoot;
		return { binPath: pathFromGoRoot, why: found('goroot') };
	}

	// Finally search PATH parts
	const pathFromPath = getBinPathFromEnvVar(binname, envPath, false);
	if (pathFromPath) {
		binPathCache[toolName] = pathFromPath;
		return { binPath: pathFromPath, why: found('path') };
	}

	// Check common paths for go
	if (toolName === 'go') {
		const defaultPathsForGo =
			process.platform === 'win32'
				? ['C:\\Program Files\\Go\\bin\\go.exe', 'C:\\Program Files (x86)\\Go\\bin\\go.exe']
				: ['/usr/local/go/bin/go', '/usr/local/bin/go'];
		for (const p of defaultPathsForGo) {
			if (executableFileExists(p)) {
				binPathCache[toolName] = p;
				return { binPath: p, why: 'default' };
			}
		}
		return { binPath: '' };
	}

	// Else return the binary name directly (this will likely always fail downstream)
	return { binPath: toolName };
}