enso/app/ide-desktop/client/watch.ts

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

137 lines
4.1 KiB
TypeScript
Raw Normal View History

/**
* @file This script is for watching the whole IDE and spawning the electron process.
*
* It sets up watchers for the client and content, and spawns the electron process with the IDE.
* The spawned electron process can then use its refresh capability to pull the latest changes
* from the watchers.
*
* If the electron app is closed, the script will restart it, allowing to test the IDE setup.
* To stop, use Ctrl+C.
*/
import * as childProcess from 'node:child_process'
import * as fs from 'node:fs/promises'
import * as path from 'node:path'
import process from 'node:process'
import * as esbuild from 'esbuild'
import * as clientBundler from './esbuildConfig'
import * as paths from './paths'
// =============
// === Types ===
// =============
/** Set of esbuild watches for the client and content. */
interface Watches {
readonly client: esbuild.BuildResult
}
// =================
// === Constants ===
// =================
const IDE_DIR_PATH = paths.getIdeDirectory()
const PROJECT_MANAGER_BUNDLE_PATH = paths.getProjectManagerBundlePath()
// =============
// === Watch ===
// =============
// @ts-expect-error This is the only place where an environment variable should be written to.
process.env.ELECTRON_DEV_MODE = 'true'
console.log('Cleaning IDE dist directory.')
await fs.rm(IDE_DIR_PATH, { recursive: true, force: true })
await fs.mkdir(IDE_DIR_PATH, { recursive: true })
const NODE_MODULES_PATH = path.resolve('./node_modules')
const ALL_BUNDLES_READY = new Promise<Watches>((resolve, reject) => {
void (async () => {
console.log('Bundling client.')
const devMode = true
const clientBundlerOpts = clientBundler.bundlerOptionsFromEnv(devMode)
clientBundlerOpts.outdir = path.resolve(IDE_DIR_PATH)
;(clientBundlerOpts.plugins ??= []).push({
name: 'enso-on-rebuild',
setup: build => {
build.onEnd(result => {
if (result.errors.length) {
// We cannot carry on if the client failed to build, because electron
// would immediately exit with an error.
console.error('Client watch bundle failed:', result.errors[0])
reject(result.errors[0])
} else {
console.log('Client bundle updated.')
}
})
2024-07-26 09:34:51 +03:00
},
})
const clientBuilder = await esbuild.context(clientBundlerOpts)
const client = await clientBuilder.rebuild()
console.log('Result of client bundling: ', client)
void clientBuilder.watch()
resolve({ client })
})()
})
await ALL_BUNDLES_READY
console.log('Exposing Project Manager bundle.')
console.log(
`Linking '${PROJECT_MANAGER_BUNDLE_PATH}' to '${path.join(
IDE_DIR_PATH,
paths.PROJECT_MANAGER_BUNDLE,
)}'.`,
)
await fs.symlink(
PROJECT_MANAGER_BUNDLE_PATH,
path.join(IDE_DIR_PATH, paths.PROJECT_MANAGER_BUNDLE),
'dir',
)
const ELECTRON_FLAGS =
process.env.ELECTRON_FLAGS == null ? [] : String(process.env.ELECTRON_FLAGS).split(' ')
const ELECTRON_ARGS = [
path.join(IDE_DIR_PATH, 'index.mjs'),
...ELECTRON_FLAGS,
'--',
Local Dashboard fixes (#10958) - Fix most of https://github.com/enso-org/cloud-v2/issues/1459 - Prevent click + click from triggering rename on Windows and Linux. Behavior is preserved on macOS. - Fix text in Drive when root folder is empty - Properly remove the "Drop here to upload box" after a file is dropped - "Copy as path" now unconditionally uses `/` for path delimiters, even on Windows - Duplicating a project in the root folder on Windows no longer errors - Extra folders in the sidebar now (correctly) show folder name, rather than path, on Windows - Mouse pointer when dragging to a folder is now move, not copy Not addressed: - [no-repro] Tooltips should have some latency before showing up - This should already be the case, although it may work weirdly (once the tooltip opens, there is no delay on subsequent tooltips opening until the last tooltip closes.) - [no-repro] Ctrl-click should add to selection - Column width should be resizable - This requires a refactor and therefore is considered out of scope for this PR - [no-repro] Choosing root folder needs a file browser - [no-repro] Choosing root folder doesn't do anything get the same list as we had before - [no-repro] Open in explorer didn't work in a file but did on project - possibly fixed by path changes. - [no-repro] Opening an enso-project by double clicking resulted on it being renamed with a (2) Related changes: - Make "root directory" picker's file browser default to the current root directory # Important Notes None
2024-09-08 09:54:41 +03:00
...process.argv.slice(2).map(arg => `'${arg}'`),
]
process.on('SIGINT', () => {
console.log('SIGINT received. Exiting.')
void fs.rm(IDE_DIR_PATH, { recursive: true, force: true }).then(() => {
// The `esbuild` process seems to remain alive at this point and will keep our process
// from ending. Thus, we exit manually. It seems to terminate the child `esbuild` process
// as well.
process.exit(0)
})
})
/** Starts the electron process with the IDE. */
function startElectronProcess() {
console.log('Spawning Electron process.')
2024-07-26 09:34:51 +03:00
const electronProcess = childProcess.spawn('electron', ELECTRON_ARGS, {
stdio: 'inherit',
shell: true,
env: Object.assign({ NODE_MODULES_PATH }, process.env),
})
2024-07-26 09:34:51 +03:00
electronProcess.on('close', code => {
if (code === 0) {
electronProcess.removeAllListeners()
process.exit(0)
}
})
electronProcess.on('error', error => {
console.error('Electron process failed:', error)
console.error('Killing electron process.')
electronProcess.removeAllListeners()
electronProcess.kill()
process.exit(1)
})
}
startElectronProcess()