-
-
Notifications
You must be signed in to change notification settings - Fork 110
Expand file tree
/
Copy pathexecutor.ts
More file actions
124 lines (113 loc) · 3.52 KB
/
executor.ts
File metadata and controls
124 lines (113 loc) · 3.52 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
import {
ExecutorContext,
getPackageManagerCommand,
logger,
normalizePath,
parseTargetString,
readJsonFile,
runExecutor as nxRunExecutor,
} from '@nx/devkit';
import { execSync, spawn } from 'node:child_process';
import { existsSync, rmSync } from 'node:fs';
import runCommands from 'nx/src/executors/run-commands/run-commands.impl';
import { CommandExecutorSchema } from './schema';
export default async function* runExecutor(
options: CommandExecutorSchema,
context: ExecutorContext
) {
const projectConfig =
context.projectsConfigurations.projects[context.projectName];
const projectRoot = projectConfig.root;
const projectDistDir = projectConfig.targets['build'].options.outputPath;
const projectRootPath = normalizePath(`${context.root}/${projectRoot}`);
const projectDistPath = normalizePath(`${context.root}/${projectDistDir}`);
const { devDependencies } = readJsonFile('package.json');
const packageName = '@capacitor/cli';
const packageVersion = devDependencies?.[packageName]?.replace(/[\\~^]/g, '');
const preserveProjectNodeModules =
options?.preserveProjectNodeModules || false;
await runCommands(
{
command: getPackageManagerCommand().install,
cwd: projectRootPath,
parallel: false,
color: true,
__unparsed__: [],
},
context
);
if (!existsSync(projectDistPath)) {
logger.info(`Running build first...`);
const parsedDevServerTarget = parseTargetString(
`${context.projectName}:build`,
context.projectGraph
);
for await (const output of await nxRunExecutor<{
success: boolean;
}>(parsedDevServerTarget, {}, context)) {
yield {
success: output.success,
};
}
}
const cmd = sanitizeCapacitorCommand(options.cmd);
let success = false;
// Use spawn for long-running commands (when -l or --livereload is present)
const isLongRunning =
/(^|\s)-(l|\-livereload)(\s|$)/.test(cmd) ||
/(^|\s)--livereload(\s|$)/.test(cmd);
if (isLongRunning) {
// Split the command into args for spawn
const args = [
`--package=${packageName}@${packageVersion}`,
'cap',
...cmd.split(' '),
];
const child = spawn('npx', args, {
stdio: 'inherit',
cwd: projectRootPath,
shell: false,
});
// Wait for the process to exit
success = await new Promise((resolve) => {
child.on('exit', (code) => {
resolve(code === 0);
});
child.on('error', () => {
resolve(false);
});
});
} else {
try {
execSync(`npx --package=${packageName}@${packageVersion} cap ${cmd}`, {
stdio: 'inherit',
cwd: projectRootPath,
});
success = true;
} catch {
success = false;
}
}
const nodeModulesPath = normalizePath(`${projectRootPath}/node_modules`);
if (existsSync(nodeModulesPath) && !preserveProjectNodeModules) {
try {
logger.info(`\n\nRemoving node_modules from project root...`);
rmSync(nodeModulesPath, { recursive: true, force: true });
} catch (err) {
logger.error(`\n\nFailed to remove node_modules from project root.`);
}
}
return { success };
}
/**
* Strip quotes from the Capacitor command passed into the executor.
* @param capacitorCommand The command input from the user.
* @returns a string without quotes at the start or end.
*/
function sanitizeCapacitorCommand(capacitorCommand: string): string {
let cmd = capacitorCommand;
if (cmd[0] === '"' && cmd[cmd.length - 1] === '"') {
cmd = cmd.substring(1).slice(0, -1);
}
return cmd;
}