aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/packages/turbo-utils/src/managers.ts
blob: ab9c53d5bc044b623339c666e93001dd19a170c1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import execa from "execa";
import os from "os";

export type PackageManager = "npm" | "yarn" | "pnpm";
export type PackageManagerAvailable = { available: boolean; version?: string };

async function getVersion(
  packageManager: string
): Promise<PackageManagerAvailable> {
  // run the check from tmpdir to avoid corepack conflicting -
  // this is no longer needed as of https://github.com/nodejs/corepack/pull/167
  // but we'll keep the behavior for those on older versions)
  const execOptions = {
    cwd: os.tmpdir(),
    env: { COREPACK_ENABLE_STRICT: "0" },
  };

  let available = false;
  try {
    const userAgent = process.env.npm_config_user_agent;
    if (userAgent && userAgent.startsWith(packageManager)) {
      available = true;
    }

    const result = await execa(packageManager, ["--version"], execOptions);
    return {
      available: true,
      version: result.stdout.trim(),
    };
  } catch (e) {
    return {
      available,
    };
  }
}

async function getAvailablePackageManagers(): Promise<
  Record<PackageManager, PackageManagerAvailable>
> {
  const [yarn, npm, pnpm] = await Promise.all([
    getVersion("yarnpkg"),
    getVersion("npm"),
    getVersion("pnpm"),
  ]);

  return {
    yarn,
    pnpm,
    npm,
  };
}

export { getAvailablePackageManagers };