-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathutils.ts
More file actions
161 lines (142 loc) · 4.82 KB
/
utils.ts
File metadata and controls
161 lines (142 loc) · 4.82 KB
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
import { info, warning, debug } from "@actions/core";
import { getExecOutput } from "@actions/exec";
import { existsSync, readdirSync, statSync } from "node:fs";
import { homedir } from "node:os";
import { isAbsolute, join, basename } from "node:path";
import type { Inputs } from "./types.js";
import { LockFileType } from "./types.js";
import type { LockFileInfo } from "./types.js";
export function getVitePlusHome(): string {
const home = process.platform === "win32" ? process.env.USERPROFILE : process.env.HOME;
return join(home || homedir(), ".vite-plus");
}
export function getWorkspaceDir(): string {
return process.env.GITHUB_WORKSPACE || process.cwd();
}
export function resolvePath(filePath: string, baseDir: string): string {
return isAbsolute(filePath) ? filePath : join(baseDir, filePath);
}
export function getConfiguredProjectDir(inputs: Inputs): string {
if (!inputs.workingDirectory) {
return getWorkspaceDir();
}
const projectDir = resolvePath(inputs.workingDirectory, getWorkspaceDir());
if (!existsSync(projectDir)) {
throw new Error(
`working-directory not found: ${inputs.workingDirectory} (resolved to ${projectDir})`,
);
}
if (!statSync(projectDir).isDirectory()) {
throw new Error(
`working-directory is not a directory: ${inputs.workingDirectory} (resolved to ${projectDir})`,
);
}
return projectDir;
}
export function getInstallCwd(projectDir: string, cwd?: string): string {
return cwd ? resolvePath(cwd, projectDir) : projectDir;
}
// Lock file patterns in priority order
const LOCK_FILES: Array<{ filename: string; type: LockFileType }> = [
{ filename: "pnpm-lock.yaml", type: LockFileType.Pnpm },
{ filename: "bun.lockb", type: LockFileType.Bun },
{ filename: "bun.lock", type: LockFileType.Bun },
{ filename: "package-lock.json", type: LockFileType.Npm },
{ filename: "npm-shrinkwrap.json", type: LockFileType.Npm },
{ filename: "yarn.lock", type: LockFileType.Yarn },
];
/**
* Detect a lock file in the provided workspace directory.
* Defaults to the GitHub workspace root.
*/
export function detectLockFile(
explicitPath?: string,
workspace = getWorkspaceDir(),
): LockFileInfo | undefined {
// If explicit path provided, use it
if (explicitPath) {
const fullPath = resolvePath(explicitPath, workspace);
if (existsSync(fullPath)) {
const filename = basename(fullPath);
const lockInfo = LOCK_FILES.find((l) => l.filename === filename);
if (lockInfo) {
return {
type: lockInfo.type,
path: fullPath,
filename,
};
}
// Unknown lock file type - try to infer from name
return inferLockFileType(fullPath, filename);
}
return undefined;
}
// Auto-detect: search for lock files in the provided workspace directory
const workspaceContents = readdirSync(workspace);
for (const lockInfo of LOCK_FILES) {
if (workspaceContents.includes(lockInfo.filename)) {
const fullPath = join(workspace, lockInfo.filename);
info(`Auto-detected lock file: ${lockInfo.filename}`);
return {
type: lockInfo.type,
path: fullPath,
filename: lockInfo.filename,
};
}
}
return undefined;
}
function inferLockFileType(fullPath: string, filename: string): LockFileInfo {
// Infer type from filename patterns
if (filename.includes("pnpm")) {
return { type: LockFileType.Pnpm, path: fullPath, filename };
}
if (filename.includes("yarn")) {
return { type: LockFileType.Yarn, path: fullPath, filename };
}
if (filename.startsWith("bun.")) {
return { type: LockFileType.Bun, path: fullPath, filename };
}
// Default to npm
return { type: LockFileType.Npm, path: fullPath, filename };
}
/**
* Get cache directories based on package manager type
*/
export async function getCacheDirectories(lockType: LockFileType, cwd: string): Promise<string[]> {
switch (lockType) {
case LockFileType.Npm:
case LockFileType.Pnpm:
case LockFileType.Yarn:
case LockFileType.Bun:
return getViteCacheDir(cwd);
default:
return [];
}
}
async function getCommandOutput(
command: string,
args: string[],
options?: { cwd?: string },
): Promise<string | undefined> {
const cmdStr = `${command} ${args.join(" ")}`;
try {
const result = await getExecOutput(command, args, {
cwd: options?.cwd,
silent: true,
ignoreReturnCode: true,
});
if (result.exitCode === 0) {
return result.stdout.trim();
}
debug(`Command "${cmdStr}" exited with code ${result.exitCode}`);
return undefined;
} catch (error) {
warning(`Failed to run "${cmdStr}": ${String(error)}`);
return undefined;
}
}
async function getViteCacheDir(cwd: string): Promise<string[]> {
const cacheDir = await getCommandOutput("vp", ["pm", "cache", "dir"], { cwd });
return cacheDir ? [cacheDir] : [];
}