Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion app/electron-client/src/guiConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ const GUI_ENV_DIR = fileURLToPath(new URL('../../gui', import.meta.url))
function envToConfig(env: Record<string, string | undefined>): $Config {
// Conversion is technically unsafe, but practically is only used in Electron watch mode.
return Object.fromEntries(
Object.entries(env).filter(([key]) => key.startsWith(GUI_ENV_PREFIX)),
Object.entries(env).flatMap(([key, value]) =>
key.startsWith(GUI_ENV_PREFIX) ? [[key.slice(GUI_ENV_PREFIX.length), value]] : [],
),
) as $Config
}

Expand Down
10 changes: 6 additions & 4 deletions app/electron-client/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -520,19 +520,21 @@ class App {
const projectToOpen = args.startup.project
if (projectToOpen.startsWith(`${DEEP_LINK_SCHEME}:`)) {
try {
await runHybridProjectByUrl(
const exitCode = await runHybridProjectByUrl(
EnsoPath(projectToOpen.toString()),
await createRemoteBackend(),
)
this.exit(0)
// Forward exact failure exit code if available (or 0 if no error).
this.exit(exitCode)
} catch (error) {
console.error(`Error starting hybrid project '${projectToOpen}':`, error)
return this.exit(1)
}
} else if (projectToOpen) {
try {
await runLocalProjectByPath(Path(projectToOpen))
this.exit(0)
const exitCode = await runLocalProjectByPath(Path(projectToOpen))
// Forward exact failure exit code if available (or 0 if no error).
this.exit(exitCode)
} catch (error) {
console.error(`Error starting local project '${projectToOpen}':`, error)
return this.exit(1)
Expand Down
1 change: 1 addition & 0 deletions app/electron-client/watch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ console.log(
),
)
await symlink(BACKEND_BUNDLE_PATH, path.join(IDE_DIR_PATH, 'enso'), 'dir')
await symlink(path.resolve('../gui'), path.resolve(IDE_DIR_PATH, '../../gui'), 'dir')

const ELECTRON_FLAGS =
process.env.ELECTRON_FLAGS == null ? [] : String(process.env.ELECTRON_FLAGS).split(' ')
Expand Down
14 changes: 4 additions & 10 deletions app/project-manager-shim/src/projectService/ensoRunner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { extract } from 'tar'
import { Path } from './types.js'

export interface Runner {
runProject(projectPath: Path, extraEnv?: readonly (readonly [string, string])[]): Promise<void>
runProject(projectPath: Path, extraEnv?: readonly (readonly [string, string])[]): Promise<number>
createProject(path: Path, name: string, projectTemplate?: string): Promise<void>
openProject(
projectPath: Path,
Expand Down Expand Up @@ -129,11 +129,11 @@ export class EnsoRunner implements Runner {
})
}

/** Run an existing Enso project at the specified path. */
/** Run an existing Enso project at the specified path. Returns the exit code of the process. */
async runProject(
projectPath: Path,
extraEnv?: readonly (readonly [string, string])[],
): Promise<void> {
): Promise<number> {
const args = ['--run', projectPath]
const env = { ...process.env, ...(extraEnv ? Object.fromEntries(extraEnv) : {}) }
const cwd = path.dirname(projectPath)
Expand All @@ -144,13 +144,7 @@ export class EnsoRunner implements Runner {
spawnedProcess.on('error', (error) => {
reject(new Error(`Failed to spawn enso process: ${error.message}`))
})
spawnedProcess.on('exit', (code) => {
if (code === 0) {
resolve()
} else {
reject(new Error(`Enso process exited with code ${code}.`))
}
})
spawnedProcess.on('exit', resolve)
})
}

Expand Down
5 changes: 3 additions & 2 deletions app/project-manager-shim/src/projectService/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,11 +175,12 @@ export class ProjectService {
}

/** Run an existing Enso project at the specified path. */
async runProject(projectId: UUID, projectsDirectory: Path, cloud?: CloudParams): Promise<void> {
async runProject(projectId: UUID, projectsDirectory: Path, cloud?: CloudParams): Promise<number> {
const project = await this.getProject(projectId, projectsDirectory, true)
this.logger.debug(`Running project '${project.path}'`)
await this.runner.runProject(project.path, this.projectEnvVars(cloud))
const exitCode = await this.runner.runProject(project.path, this.projectEnvVars(cloud))
this.logger.debug(`Project '${project.path}' finished running`)
return exitCode
}

/** Open a project and starts its language server. */
Expand Down
16 changes: 10 additions & 6 deletions app/project-manager-shim/src/runProjects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ function createProjectService(): ProjectService {
export async function runHybridProjectByUrl(
path: EnsoPath,
remoteBackend: RemoteBackend,
): Promise<void> {
): Promise<number> {
let project: ProjectEntry | undefined
let asset: ProjectAsset | undefined
try {
Expand All @@ -56,13 +56,15 @@ export async function runHybridProjectByUrl(
}
const cloudProjectDirectoryPath = Path(asset.ensoPath.slice(0, asset.ensoPath.lastIndexOf('/')))
await remoteBackend.setHybridOpened(asset.id, asset.title)
await runLocalProjectByUuid(project.metadata.id, parentPath, {
const exitCode = await runLocalProjectByUuid(project.metadata.id, parentPath, {
cloudProjectDirectoryPath,
cloudProjectId: asset.id,
cloudProjectSessionId,
})
return exitCode
} catch (error) {
console.error(`Error starting hybrid project '${asset?.title ?? '(unknown)'}':`, error)
return 1
} finally {
if (asset) {
await remoteBackend.closeProject(asset.id, asset.title)
Expand All @@ -75,10 +77,11 @@ export async function runLocalProjectByUuid(
projectId: UUID,
projectsDirectory: Path,
cloudParams?: CloudParams,
): Promise<void> {
): Promise<number> {
const projectService = createProjectService()
try {
await projectService.runProject(projectId, projectsDirectory, cloudParams)
const exitCode = await projectService.runProject(projectId, projectsDirectory, cloudParams)
return exitCode
} catch (error) {
console.error(`Error starting local project '${projectId}':`, error)
await projectService.closeProject(projectId)
Expand All @@ -87,11 +90,12 @@ export async function runLocalProjectByUuid(
}

/** Run a local project by path. */
export async function runLocalProjectByPath(projectPath: Path): Promise<void> {
export async function runLocalProjectByPath(projectPath: Path): Promise<number> {
const directoryId = Path(dirname(projectPath))
const project = await getFileSystemEntry(projectPath)
if (project.type !== 'ProjectEntry') {
throw new Error(`The path '${projectPath}' does not point to a project.`)
}
await runLocalProjectByUuid(project.metadata.id as UUID, directoryId)
const exitCode = await runLocalProjectByUuid(project.metadata.id as UUID, directoryId)
return exitCode
}
Loading