@runium/cli 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/{lib/commands → commands}/index.js +0 -0
  2. package/{lib/commands → commands}/project/project-start.js +1 -1
  3. package/{lib/constants → constants}/index.js +0 -0
  4. package/{lib/macros → macros}/index.js +0 -0
  5. package/package.json +7 -30
  6. package/{lib/services → services}/index.js +0 -0
  7. package/services/plugin-context.js +1 -0
  8. package/services/shutdown.js +1 -0
  9. package/{lib/utils → utils}/index.js +0 -0
  10. package/.eslintrc.json +0 -31
  11. package/.prettierrc.json +0 -10
  12. package/README.md +0 -3
  13. package/build.js +0 -104
  14. package/lib/package.json +0 -21
  15. package/lib/services/plugin-context.js +0 -1
  16. package/lib/services/shutdown.js +0 -1
  17. package/src/app.ts +0 -175
  18. package/src/commands/index.ts +0 -2
  19. package/src/commands/plugin/plugin-add.ts +0 -48
  20. package/src/commands/plugin/plugin-command.ts +0 -36
  21. package/src/commands/plugin/plugin-disable.ts +0 -46
  22. package/src/commands/plugin/plugin-enable.ts +0 -50
  23. package/src/commands/plugin/plugin-list.ts +0 -61
  24. package/src/commands/plugin/plugin-remove.ts +0 -42
  25. package/src/commands/plugin/plugin.ts +0 -41
  26. package/src/commands/project/project-add.ts +0 -46
  27. package/src/commands/project/project-command.ts +0 -36
  28. package/src/commands/project/project-list.ts +0 -32
  29. package/src/commands/project/project-remove.ts +0 -41
  30. package/src/commands/project/project-start.ts +0 -152
  31. package/src/commands/project/project-state-command.ts +0 -68
  32. package/src/commands/project/project-status.ts +0 -103
  33. package/src/commands/project/project-stop.ts +0 -55
  34. package/src/commands/project/project-validate.ts +0 -43
  35. package/src/commands/project/project.ts +0 -45
  36. package/src/commands/runium-command.ts +0 -50
  37. package/src/constants/error-code.ts +0 -15
  38. package/src/constants/index.ts +0 -1
  39. package/src/index.ts +0 -21
  40. package/src/macros/conditional.ts +0 -31
  41. package/src/macros/empty.ts +0 -6
  42. package/src/macros/env.ts +0 -8
  43. package/src/macros/index.ts +0 -12
  44. package/src/macros/path.ts +0 -9
  45. package/src/services/config.ts +0 -76
  46. package/src/services/index.ts +0 -7
  47. package/src/services/output.ts +0 -201
  48. package/src/services/plugin-context.ts +0 -81
  49. package/src/services/plugin.ts +0 -144
  50. package/src/services/profile.ts +0 -211
  51. package/src/services/project.ts +0 -114
  52. package/src/services/shutdown.ts +0 -130
  53. package/src/utils/convert-path-to-valid-file-name.ts +0 -39
  54. package/src/utils/debounce.ts +0 -23
  55. package/src/utils/format-timestamp.ts +0 -17
  56. package/src/utils/index.ts +0 -3
  57. package/tsconfig.json +0 -40
  58. /package/{lib/app.js → app.js} +0 -0
  59. /package/{lib/commands → commands}/plugin/plugin-add.js +0 -0
  60. /package/{lib/commands → commands}/plugin/plugin-command.js +0 -0
  61. /package/{lib/commands → commands}/plugin/plugin-disable.js +0 -0
  62. /package/{lib/commands → commands}/plugin/plugin-enable.js +0 -0
  63. /package/{lib/commands → commands}/plugin/plugin-list.js +0 -0
  64. /package/{lib/commands → commands}/plugin/plugin-remove.js +0 -0
  65. /package/{lib/commands → commands}/plugin/plugin.js +0 -0
  66. /package/{lib/commands → commands}/project/project-add.js +0 -0
  67. /package/{lib/commands → commands}/project/project-command.js +0 -0
  68. /package/{lib/commands → commands}/project/project-list.js +0 -0
  69. /package/{lib/commands → commands}/project/project-remove.js +0 -0
  70. /package/{lib/commands → commands}/project/project-state-command.js +0 -0
  71. /package/{lib/commands → commands}/project/project-status.js +0 -0
  72. /package/{lib/commands → commands}/project/project-stop.js +0 -0
  73. /package/{lib/commands → commands}/project/project-validate.js +0 -0
  74. /package/{lib/commands → commands}/project/project.js +0 -0
  75. /package/{lib/commands → commands}/runium-command.js +0 -0
  76. /package/{lib/constants → constants}/error-code.js +0 -0
  77. /package/{lib/index.js → index.js} +0 -0
  78. /package/{lib/macros → macros}/conditional.js +0 -0
  79. /package/{lib/macros → macros}/empty.js +0 -0
  80. /package/{lib/macros → macros}/env.js +0 -0
  81. /package/{lib/macros → macros}/path.js +0 -0
  82. /package/{lib/services → services}/config.js +0 -0
  83. /package/{lib/services → services}/output.js +0 -0
  84. /package/{lib/services → services}/plugin.js +0 -0
  85. /package/{lib/services → services}/profile.js +0 -0
  86. /package/{lib/services → services}/project.js +0 -0
  87. /package/{lib/utils → utils}/convert-path-to-valid-file-name.js +0 -0
  88. /package/{lib/utils → utils}/debounce.js +0 -0
  89. /package/{lib/utils → utils}/format-timestamp.js +0 -0
@@ -1,61 +0,0 @@
1
- import { Option } from 'commander';
2
- import { PluginCommand } from './plugin-command.js';
3
-
4
- /**
5
- * Plugin list command
6
- */
7
- export class PluginListCommand extends PluginCommand {
8
- /**
9
- * Config command
10
- */
11
- protected config(): void {
12
- this.command
13
- .name('list')
14
- .addOption(
15
- new Option('-d, --disabled', 'show only disabled plugins').conflicts(
16
- 'enabled'
17
- )
18
- )
19
- .addOption(
20
- new Option('-e, --enabled', 'show only enabled plugins').conflicts(
21
- 'disabled'
22
- )
23
- )
24
- .option('-s, --sort', 'sort by name')
25
- .description('list plugins');
26
- }
27
-
28
- /**
29
- * Handle command
30
- */
31
- protected async handle({
32
- disabled,
33
- enabled,
34
- sort,
35
- }: {
36
- disabled: boolean;
37
- enabled: boolean;
38
- sort: boolean;
39
- }): Promise<void> {
40
- let plugins = this.profileService.getPlugins();
41
- if (disabled) {
42
- plugins = plugins.filter(p => p.disabled === true);
43
- }
44
- if (enabled) {
45
- plugins = plugins.filter(p => p.disabled === false);
46
- }
47
- if (sort) {
48
- plugins.sort((a, b) => a.name.localeCompare(b.name));
49
- }
50
-
51
- if (plugins.length !== 0) {
52
- this.outputService.table(plugins, [
53
- 'name',
54
- 'path',
55
- ...(disabled || enabled ? [] : ['disabled']),
56
- ]);
57
- } else {
58
- this.outputService.warn('No plugins found');
59
- }
60
- }
61
- }
@@ -1,42 +0,0 @@
1
- import { PluginCommand } from './plugin-command.js';
2
-
3
- /**
4
- * Plugin remove command
5
- */
6
- export class PluginRemoveCommand extends PluginCommand {
7
- /**
8
- * Config command
9
- */
10
- protected config(): void {
11
- this.command
12
- .name('remove')
13
- .description('remove plugin')
14
- .option('-a, --all', 'remove all plugins')
15
- .argument('[plugin...]', 'plugin names');
16
- }
17
-
18
- /**
19
- * Handle command
20
- * @param names
21
- * @param all
22
- */
23
- protected async handle(
24
- names: string[],
25
- { all }: { all: boolean }
26
- ): Promise<void> {
27
- if (names.length === 0 && !all) {
28
- this.outputService.warn('No plugins specified to remove');
29
- return;
30
- }
31
- if (all) {
32
- names = this.profileService.getPlugins().map(p => p.name);
33
- }
34
-
35
- for (const name of names) {
36
- this.ensureProfilePlugin(name);
37
- await this.profileService.removePlugin(name);
38
- await this.pluginService.unloadPlugin(name);
39
- this.outputService.success(`Plugin "%s" successfully removed`, name);
40
- }
41
- }
42
- }
@@ -1,41 +0,0 @@
1
- import { RuniumCommand } from '@commands/runium-command.js';
2
- import { PluginAddCommand } from './plugin-add.js';
3
- import { PluginDisableCommand } from './plugin-disable.js';
4
- import { PluginEnableCommand } from './plugin-enable.js';
5
- import { PluginListCommand } from './plugin-list.js';
6
- import { PluginRemoveCommand } from './plugin-remove.js';
7
-
8
- /**
9
- * Plugin group command
10
- */
11
- export class PluginCommand extends RuniumCommand {
12
- /**
13
- * Config command
14
- */
15
- protected config(): void {
16
- this.command.name('plugin').description('manage plugins');
17
- }
18
-
19
- /**
20
- * Handle command
21
- */
22
- protected async handle(): Promise<void> {
23
- this.command.help();
24
- }
25
-
26
- /**
27
- * Add subcommands
28
- */
29
- protected addSubcommands(): void {
30
- const constructors = [
31
- PluginListCommand,
32
- PluginAddCommand,
33
- PluginRemoveCommand,
34
- PluginDisableCommand,
35
- PluginEnableCommand,
36
- ];
37
- for (const CommandConstructor of constructors) {
38
- this.subcommands.push(new CommandConstructor(this.command));
39
- }
40
- }
41
- }
@@ -1,46 +0,0 @@
1
- import { RuniumError } from '@runium/core';
2
- import { ErrorCode } from '@constants';
3
- import { ProjectCommand } from './project-command.js';
4
- /**
5
- * Project add command
6
- */
7
- export class ProjectAddCommand extends ProjectCommand {
8
- /**
9
- * Config command
10
- */
11
- protected config(): void {
12
- this.command
13
- .name('add')
14
- .description('add project')
15
- .argument('<path>', 'project file path')
16
- .argument('[name]', 'project name (default: project config id)');
17
- }
18
-
19
- /**
20
- * Handle command
21
- * @param path
22
- * @param name
23
- */
24
- protected async handle(path: string, name?: string): Promise<void> {
25
- const projectPath = this.projectService.resolvePath(path);
26
- const project = await this.projectService.initProject(projectPath);
27
- if (project) {
28
- await this.profileService.addProject({
29
- // TODO validate name
30
- // optionally save project file to profile
31
- name: name ?? project.getConfig().id,
32
- path: projectPath,
33
- });
34
- this.outputService.success(
35
- `Project "%s" successfully added`,
36
- name ?? project.getConfig().id
37
- );
38
- } else {
39
- throw new RuniumError(
40
- `Failed to add project "${projectPath}"`,
41
- ErrorCode.PROJECT_NOT_FOUND,
42
- { path: projectPath }
43
- );
44
- }
45
- }
46
- }
@@ -1,36 +0,0 @@
1
- import { Command } from 'commander';
2
- import { Container } from 'typedi';
3
- import { RuniumError } from '@runium/core';
4
- import { RuniumCommand } from '@commands/runium-command.js';
5
- import { ErrorCode } from '@constants';
6
- import { ProfileService, ProjectService, ProfileProject } from '@services';
7
-
8
- /**
9
- * Base project command
10
- */
11
- export abstract class ProjectCommand extends RuniumCommand {
12
- protected projectService: ProjectService;
13
- protected profileService: ProfileService;
14
-
15
- constructor(parent: Command) {
16
- super(parent);
17
- this.projectService = Container.get(ProjectService);
18
- this.profileService = Container.get(ProfileService);
19
- }
20
-
21
- /**
22
- * Ensure project exists
23
- * @param name
24
- */
25
- protected ensureProfileProject(name: string): ProfileProject {
26
- const project = this.profileService.getProjectByName(name);
27
- if (!project) {
28
- throw new RuniumError(
29
- `Project "${name}" not found`,
30
- ErrorCode.PROJECT_NOT_FOUND,
31
- { name }
32
- );
33
- }
34
- return project;
35
- }
36
- }
@@ -1,32 +0,0 @@
1
- import { ProjectCommand } from './project-command.js';
2
-
3
- /**
4
- * Project list command
5
- */
6
- export class ProjectListCommand extends ProjectCommand {
7
- /**
8
- * Config command
9
- */
10
- protected config(): void {
11
- this.command
12
- .name('list')
13
- .description('list projects')
14
- .option('-s, --sort', 'sort by name');
15
- }
16
-
17
- /**
18
- * Handle command
19
- */
20
- protected async handle({ sort }: { sort: boolean }): Promise<void> {
21
- const projects = this.profileService.getProjects();
22
- if (sort) {
23
- projects.sort((a, b) => a.name.localeCompare(b.name));
24
- }
25
- // handle empty list
26
- if (projects.length !== 0) {
27
- this.outputService.table(projects, ['name', 'path']);
28
- } else {
29
- this.outputService.warn('No projects found');
30
- }
31
- }
32
- }
@@ -1,41 +0,0 @@
1
- import { ProjectCommand } from './project-command.js';
2
-
3
- /**
4
- * Project remove command
5
- */
6
- export class ProjectRemoveCommand extends ProjectCommand {
7
- /**
8
- * Config command
9
- */
10
- protected config(): void {
11
- this.command
12
- .name('remove')
13
- .description('remove project')
14
- .option('-a, --all', 'remove all projects')
15
- .argument('[name...]', 'project names');
16
- }
17
-
18
- /**
19
- * Handle command
20
- * @param names
21
- * @param all
22
- */
23
- protected async handle(
24
- names: string[],
25
- { all }: { all: boolean }
26
- ): Promise<void> {
27
- if (names.length === 0 && !all) {
28
- this.outputService.warn('No projects specified to remove');
29
- return;
30
- }
31
- if (all) {
32
- names = this.profileService.getProjects().map(p => p.name);
33
- }
34
-
35
- for (const name of names) {
36
- this.ensureProfileProject(name);
37
- await this.profileService.removeProject(name);
38
- this.outputService.success(`Project "%s" successfully removed`, name);
39
- }
40
- }
41
- }
@@ -1,152 +0,0 @@
1
- import { dirname } from 'node:path';
2
- import { Command, Option } from 'commander';
3
- import { Container } from 'typedi';
4
- import {
5
- Project,
6
- ProjectEvent,
7
- ProjectState,
8
- RuniumError,
9
- TaskState,
10
- } from '@runium/core';
11
- import { ErrorCode } from '@constants';
12
- import { ShutdownService } from '@services';
13
- import { debounce } from '@utils';
14
- import { ProjectData, ProjectStateCommand } from './project-state-command.js';
15
-
16
- const WRITE_PROJECT_DATA_DEBOUNCE_WAIT = 100;
17
-
18
- /**
19
- * Project start command
20
- */
21
- export class ProjectStartCommand extends ProjectStateCommand {
22
- protected shutdownService: ShutdownService;
23
-
24
- constructor(parent: Command) {
25
- super(parent);
26
- this.shutdownService = Container.get(ShutdownService);
27
- }
28
-
29
- /**
30
- * Config command
31
- */
32
- protected config(): void {
33
- this.command
34
- .name('start')
35
- .description('start project')
36
- .option('-f, --file', 'use file path instead of project name')
37
- .option('-o, --output', 'output project state changes')
38
- .addOption(
39
- new Option('-w, --working-dir <choice>', 'set working directory')
40
- .choices(['cwd', 'project'])
41
- .default('cwd')
42
- )
43
- .argument('<name>', 'project name');
44
- }
45
-
46
- /**
47
- * Handle command
48
- * @param name
49
- * @param file
50
- * @param workingDir
51
- * @param output
52
- */
53
- protected async handle(
54
- name: string,
55
- {
56
- file,
57
- workingDir,
58
- output,
59
- }: { file: boolean; workingDir?: string; output?: boolean }
60
- ): Promise<void> {
61
- const path = file
62
- ? this.projectService.resolvePath(name)
63
- : this.ensureProfileProject(name).path;
64
-
65
- const projectDataFileName = this.getProjectDataFileName(file ? path : name);
66
-
67
- // check if project is started
68
- const projectData = await this.readProjectData(projectDataFileName);
69
- if (projectData && this.isProjectProcessStarted(projectData.pid)) {
70
- throw new RuniumError(
71
- `Project "${name}" is already started`,
72
- ErrorCode.PROJECT_ALREADY_STARTED,
73
- { name }
74
- );
75
- }
76
-
77
- if (workingDir === 'project') {
78
- const projectDir = dirname(path);
79
- if (projectDir !== process.cwd()) {
80
- process.chdir(projectDir);
81
- }
82
- }
83
-
84
- const project = await this.projectService.initProject(path);
85
- this.shutdownService.addBlocker(() => project.stop());
86
-
87
- this.addProjectListeners(project, {
88
- dataFileName: projectDataFileName,
89
- projectPath: path,
90
- output,
91
- });
92
-
93
- await project.start();
94
- }
95
-
96
- /**
97
- * Add project listeners
98
- * @param project
99
- * @param options
100
- */
101
- protected addProjectListeners(
102
- project: Project,
103
- options: { dataFileName: string; projectPath: string; output?: boolean }
104
- ): void {
105
- const { dataFileName, projectPath, output } = options;
106
-
107
- const projectData: ProjectData = {
108
- id: project.getConfig().id,
109
- pid: process.pid,
110
- cwd: process.cwd(),
111
- path: projectPath,
112
- state: {
113
- project: [],
114
- tasks: {},
115
- },
116
- };
117
-
118
- const writeProjectData = debounce(() => {
119
- this.writeProjectData(projectData, dataFileName);
120
- }, WRITE_PROJECT_DATA_DEBOUNCE_WAIT);
121
-
122
- // write initial data
123
- writeProjectData();
124
-
125
- project.on(ProjectEvent.STATE_CHANGE, async (state: ProjectState) => {
126
- projectData.state.project.push(state);
127
- writeProjectData();
128
- if (output) {
129
- this.outputService.info('Project %s', state.status);
130
- }
131
- });
132
-
133
- project.on(
134
- ProjectEvent.TASK_STATE_CHANGE,
135
- (taskId: string, state: TaskState) => {
136
- if (!projectData.state.tasks[taskId]) {
137
- projectData.state.tasks[taskId] = [];
138
- }
139
- projectData.state.tasks[taskId].push(state);
140
- writeProjectData();
141
- if (output) {
142
- this.outputService.info(
143
- 'Task %s %s %s',
144
- taskId,
145
- state.status,
146
- state.exitCode || state.error || ''
147
- );
148
- }
149
- }
150
- );
151
- }
152
- }
@@ -1,68 +0,0 @@
1
- import { convertPathToValidFileName } from '@utils';
2
- import { ProjectCommand } from './project-command.js';
3
- import { ProjectState, TaskState } from '@runium/core';
4
-
5
- export interface ProjectData {
6
- id: string;
7
- pid: number;
8
- cwd: string;
9
- path: string;
10
- state: {
11
- project: ProjectState[];
12
- tasks: Record<string, TaskState[]>;
13
- };
14
- }
15
-
16
- /**
17
- * Base project state command
18
- */
19
- export abstract class ProjectStateCommand extends ProjectCommand {
20
- /**
21
- * Get project data file name
22
- * @param name
23
- */
24
- protected getProjectDataFileName(name: string): string {
25
- let fileName = convertPathToValidFileName(name);
26
- if (!fileName.endsWith('.json')) {
27
- fileName = fileName + '.json';
28
- }
29
- return fileName;
30
- }
31
-
32
- /**
33
- * Read project data
34
- * @param fileName
35
- */
36
- protected async readProjectData(
37
- fileName: string
38
- ): Promise<ProjectData | null> {
39
- return this.profileService
40
- .readJsonFile('projects', fileName)
41
- .catch(() => null) as Promise<ProjectData | null>;
42
- }
43
-
44
- /**
45
- * Write project data
46
- * @param data
47
- * @param fileName
48
- */
49
- protected async writeProjectData(
50
- data: ProjectData,
51
- fileName: string
52
- ): Promise<void> {
53
- return this.profileService.writeJsonFile(data, 'projects', fileName);
54
- }
55
-
56
- /**
57
- * Checks if a project process is started
58
- * @param pid
59
- */
60
- protected isProjectProcessStarted(pid: number): boolean {
61
- // and process started
62
- try {
63
- return process.kill(Number(pid), 0);
64
- } catch (ex) {
65
- return (ex as { code?: string }).code === 'EPERM';
66
- }
67
- }
68
- }
@@ -1,103 +0,0 @@
1
- import { formatTimestamp } from '@utils';
2
- import { ProjectStateCommand } from './project-state-command.js';
3
-
4
- interface StateRecord {
5
- name: string;
6
- status: string;
7
- time: string;
8
- timestamp: number;
9
- }
10
-
11
- /**
12
- * Project status command
13
- */
14
- export class ProjectStatusCommand extends ProjectStateCommand {
15
- /**
16
- * Config command
17
- */
18
- protected config(): void {
19
- this.command
20
- .name('status')
21
- .description('get project status')
22
- .option('-f, --file', 'use file path instead of project name')
23
- .option('-t, --tasks', 'show task status')
24
- .option('-a, --all', 'show status change history')
25
- .argument('<name>', 'project name');
26
- }
27
-
28
- /**
29
- * Handle command
30
- * @param name
31
- * @param file
32
- * @param tasks
33
- * @param all
34
- */
35
- protected async handle(
36
- name: string,
37
- { file, tasks, all }: { file: boolean; tasks: boolean; all: boolean }
38
- ): Promise<void> {
39
- const path = file
40
- ? this.projectService.resolvePath(name)
41
- : this.ensureProfileProject(name).path;
42
-
43
- const projectDataFileName = this.getProjectDataFileName(file ? path : name);
44
-
45
- const projectData = await this.readProjectData(projectDataFileName);
46
- if (projectData) {
47
- let { project: projectState = [] } = projectData.state;
48
- if (!all) {
49
- projectState =
50
- projectState.length > 0
51
- ? [projectState[projectState.length - 1]]
52
- : [];
53
- }
54
-
55
- if (tasks) {
56
- const projectMappedState = projectState.map(state => {
57
- return {
58
- name: 'Project',
59
- status: state.status,
60
- time: formatTimestamp(state.timestamp),
61
- timestamp: state.timestamp,
62
- };
63
- });
64
-
65
- const { tasks: tasksState = [] } = projectData.state;
66
-
67
- const tasksMappedState: StateRecord[] = [];
68
- Object.entries(tasksState).forEach(([key, value]) => {
69
- if (!all) {
70
- value = value.length > 0 ? [value[value.length - 1]] : [];
71
- }
72
- value.forEach(task => {
73
- tasksMappedState.push({
74
- name: key,
75
- status: task.status,
76
- time: formatTimestamp(task.timestamp),
77
- timestamp: task.timestamp,
78
- });
79
- });
80
- });
81
-
82
- const mappedState: StateRecord[] = [
83
- ...projectMappedState,
84
- ...tasksMappedState,
85
- ];
86
- mappedState.sort((a, b) => a.timestamp - b.timestamp);
87
-
88
- this.outputService.table(mappedState, ['time', 'name', 'status']);
89
- } else {
90
- const mappedState = projectState.map(state => {
91
- return {
92
- status: state.status,
93
- time: formatTimestamp(state.timestamp),
94
- };
95
- });
96
-
97
- this.outputService.table(mappedState, ['time', 'status']);
98
- }
99
- } else {
100
- this.outputService.info(`No project status for "${name}"`);
101
- }
102
- }
103
- }
@@ -1,55 +0,0 @@
1
- import { RuniumError } from '@runium/core';
2
- import { ErrorCode } from '@constants';
3
- import { ProjectStateCommand } from './project-state-command.js';
4
-
5
- /**
6
- * Project stop command
7
- */
8
- export class ProjectStopCommand extends ProjectStateCommand {
9
- /**
10
- * Config command
11
- */
12
- protected config(): void {
13
- this.command
14
- .name('stop')
15
- .description('stop project')
16
- .option('-f, --file', 'use file path instead of project name')
17
- .argument('<name>', 'project name');
18
- }
19
-
20
- /**
21
- * Handle command
22
- * @param name
23
- * @param file
24
- */
25
- protected async handle(
26
- name: string,
27
- { file }: { file: boolean }
28
- ): Promise<void> {
29
- const path = file
30
- ? this.projectService.resolvePath(name)
31
- : this.ensureProfileProject(name).path;
32
-
33
- const projectDataFileName = this.getProjectDataFileName(file ? path : name);
34
-
35
- // check if project is started
36
- const projectData = await this.readProjectData(projectDataFileName);
37
- if (!projectData || !this.isProjectProcessStarted(projectData.pid)) {
38
- throw new RuniumError(
39
- `Project "${name}" is not started`,
40
- ErrorCode.PROJECT_NOT_STARTED,
41
- { name }
42
- );
43
- }
44
-
45
- try {
46
- process.kill(projectData.pid, 'SIGTERM');
47
- } catch (ex) {
48
- throw new RuniumError(
49
- `Failed to stop project "${name}"`,
50
- ErrorCode.PROJECT_STOP_ERROR,
51
- { name, original: ex }
52
- );
53
- }
54
- }
55
- }