mirror of
https://github.com/enso-org/enso.git
synced 2024-12-22 06:01:35 +03:00
ce33af82f7
* Consistent order for statements in `dashboard.tsx`; change functions back to lambdas * Create convenience aliases for each asset type * Remove obsolete FIXME * Refactor out column renderers into components * Enable `prefer-const` lint * Remove hardcoded product name * Add fixme * Enable `react-hooks` lints (not working for some reason) * Consistent messages for naming-convention lint overrides * Enable `react` lints * Extract out tables for each asset type * Refactor out column display mode switcher to a file * Switch VM check state to use an enum * Fix lint errors * Minor section change * Fix position of create forms * Fix bugs; improve debugging QoL * Add documentation for new components * Refactor out drive bar * Refactor out event handlers to variables * Minor clarifications * Refactor out directory view; some fixes; improve React DX There are still many issues when switching backends * Add `assert` * Use `backend.platform` instead of checking for properties * Fix errors when switching backend * Minor style changes; fix lint errors * Fix assert behavior * Change `Rows` to `Table` * Fixes * Fix lint errors * Fix "show dashboard" button * Implement click to rename * Fix lint errors * Fix lint errors (along with a bug in `devServiceWorker`) * Enable dev-mode on `ide watch` * Fix bug in `useAsyncEffect` introduced during merge * More fixes; new debug hooks; fix infinite loop in `auth.tsx` * Inline Cognito methods * Remove redundant `Promise.resolve`s * Fix column display * Fixes * Simplify modal type * Fix bug when opening IDE * Shift+click to select a range of table items * Implement delete multiple * Fixes * Tick and cross for rename input; fixes * Implement rename and delete directory and multi-delete directory; fixes * Optimize modal re-rendering * Make some internal `Props` private * Remove old asset selection code * Eliminate re-renders when clicking document body * Fix name flickering when renaming * Use static placeholders * Avoid refreshing entire directory on rename * Use asset name instead of ID in error messages * QoL improvements * Enable react lints and `strict-boolean-expressions` * Extract dashboard feature flags to its own module * Feature flag to show more toasts; minimize calls to `listDirectory` * Deselect selection on delete; hide unused features; add exception to PascalCase lint * Fix projects disappearing after being created * Fix name of `projectEvent` module imports * Re-disable delete when project is being closed * Fix assets refreshing when adding new projects * Refactor row state into `Table`; fix delete not being disabled again * Address review * Implement shortcut registry * Fix stop icon spinning when switching backends (ported from #6919) * Give columns names * Immediately show project as opening * Replace `asNewtype` with constructor functions * Address review * Minor bugfixes * Prepare for optimistically updated tables * wip 2 * Fix type errors * Remove indirect usages of `doRefresh` Updating the lists of items will need to be re-added later * Remove `toastPromise` * Fix `New_Directory_-Infinity` bug * wip * WIP: Begin restoring functionality to rows * Fix most issues with DirectoriesTable * Port optimistic UI from `DirectoriesTable` to all other asset tables * Fix bugs in item list events for asset tables * Merge `projectActionButton` into `projectsTable` * Remove `RenameModal`; minor context menu bugfixes * Fix bugs * Remove small default user icon * Fix more bugs * Fix bugs * Fix type error * Address review and QA * Fix optimistic UI for "manage permissions" modal * Fix "share with" modal * Fix template spinner disappearing * Allow multiple projects to be opened on local backend; fix version lifecycle returned by local backend * Fix minor bug when closing local project --------- Co-authored-by: Paweł Buchowski <pawel.buchowski@enso.org>
158 lines
5.9 KiB
TypeScript
158 lines
5.9 KiB
TypeScript
/** @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 * as url from 'node:url'
|
|
import process from 'node:process'
|
|
|
|
import * as esbuild from 'esbuild'
|
|
|
|
import * as clientBundler from './esbuild-config'
|
|
import * as contentBundler from '../content/esbuild-config'
|
|
import * as dashboardBundler from '../dashboard/esbuild-config'
|
|
import * as paths from './paths'
|
|
|
|
// =============
|
|
// === Types ===
|
|
// =============
|
|
|
|
/** Set of esbuild watches for the client and content. */
|
|
interface Watches {
|
|
client: esbuild.BuildResult
|
|
dashboard: esbuild.BuildResult
|
|
content: esbuild.BuildResult
|
|
}
|
|
|
|
// =================
|
|
// === Constants ===
|
|
// =================
|
|
|
|
/** The path of this file. */
|
|
const THIS_PATH = path.resolve(path.dirname(url.fileURLToPath(import.meta.url)))
|
|
const IDE_DIR_PATH = paths.getIdeDirectory()
|
|
const PROJECT_MANAGER_BUNDLE_PATH = paths.getProjectManagerBundlePath()
|
|
|
|
// =============
|
|
// === Watch ===
|
|
// =============
|
|
|
|
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 ALL_BUNDLES_READY = new Promise<Watches>((resolve, reject) => {
|
|
void (async () => {
|
|
console.log('Bundling client.')
|
|
const clientBundlerOpts = clientBundler.bundlerOptionsFromEnv()
|
|
clientBundlerOpts.outdir = path.resolve(IDE_DIR_PATH)
|
|
// Eslint is wrong here; `clientBundlerOpts.plugins` is actually `undefined`.
|
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
;(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.')
|
|
}
|
|
})
|
|
},
|
|
})
|
|
const clientBuilder = await esbuild.context(clientBundlerOpts)
|
|
const client = await clientBuilder.rebuild()
|
|
console.log('Result of client bundling: ', client)
|
|
void clientBuilder.watch()
|
|
|
|
console.log('Bundling dashboard.')
|
|
const dashboardOpts = dashboardBundler.bundleOptions()
|
|
dashboardOpts.plugins.push({
|
|
name: 'enso-on-rebuild',
|
|
setup: build => {
|
|
build.onEnd(() => {
|
|
console.log('Dashboard bundle updated.')
|
|
})
|
|
},
|
|
})
|
|
dashboardOpts.outdir = path.resolve(IDE_DIR_PATH, 'assets')
|
|
const dashboardBuilder = await esbuild.context(dashboardOpts)
|
|
const dashboard = await dashboardBuilder.rebuild()
|
|
console.log('Result of dashboard bundling: ', dashboard)
|
|
// We do not need to serve the dashboard as it outputs to the same directory.
|
|
// It will not rebuild on request, but it is not intended to rebuild on request anyway.
|
|
// This MUST be called before `builder.watch()` as `tailwind.css` must be generated
|
|
// before the copy plugin runs.
|
|
void dashboardBuilder.watch()
|
|
|
|
console.log('Bundling content.')
|
|
const contentOpts = contentBundler.bundlerOptionsFromEnv({
|
|
devMode: true,
|
|
supportsLocalBackend: true,
|
|
supportsDeepLinks: false,
|
|
})
|
|
contentOpts.plugins.push({
|
|
name: 'enso-on-rebuild',
|
|
setup: build => {
|
|
build.onEnd(() => {
|
|
console.log('Content bundle updated.')
|
|
})
|
|
},
|
|
})
|
|
contentOpts.pure.splice(contentOpts.pure.indexOf('assert'), 1)
|
|
;(contentOpts.inject = contentOpts.inject ?? []).push(
|
|
path.resolve(THIS_PATH, '..', '..', 'debugGlobals.ts')
|
|
)
|
|
contentOpts.outdir = path.resolve(IDE_DIR_PATH, 'assets')
|
|
contentOpts.define.REDIRECT_OVERRIDE = JSON.stringify('http://localhost:8080')
|
|
const contentBuilder = await esbuild.context(contentOpts)
|
|
const content = await contentBuilder.rebuild()
|
|
console.log('Result of content bundling: ', content)
|
|
void contentBuilder.watch()
|
|
|
|
resolve({ client, dashboard, content })
|
|
})()
|
|
})
|
|
|
|
await ALL_BUNDLES_READY
|
|
console.log('Exposing Project Manager bundle.')
|
|
await fs.symlink(
|
|
PROJECT_MANAGER_BUNDLE_PATH,
|
|
path.join(IDE_DIR_PATH, paths.PROJECT_MANAGER_BUNDLE),
|
|
'dir'
|
|
)
|
|
|
|
const ELECTRON_ARGS = [path.join(IDE_DIR_PATH, 'index.cjs'), '--', ...process.argv.slice(2)]
|
|
|
|
process.on('SIGINT', () => {
|
|
console.log('SIGINT received. Exiting.')
|
|
// 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)
|
|
})
|
|
|
|
while (true) {
|
|
console.log('Spawning Electron process.')
|
|
const electronProcess = childProcess.spawn('electron', ELECTRON_ARGS, {
|
|
stdio: 'inherit',
|
|
shell: true,
|
|
})
|
|
console.log('Waiting for Electron process to finish.')
|
|
const result = await new Promise((resolve, reject) => {
|
|
electronProcess.on('close', resolve)
|
|
electronProcess.on('error', reject)
|
|
})
|
|
console.log('Electron process finished. Exit code: ', result)
|
|
}
|