diff --git a/e2e/js/src/js.test.ts b/e2e/js/src/js.test.ts index ff3671ea74..e56222b195 100644 --- a/e2e/js/src/js.test.ts +++ b/e2e/js/src/js.test.ts @@ -38,7 +38,6 @@ describe('js e2e', () => { }, 120000); it('should create libs with js executors (--compiler=tsc)', async () => { - // const lib = uniq('lib'); runCLI(`generate @nrwl/js:lib ${lib} --buildable --compiler=tsc`); const libPackageJson = readJson(`libs/${lib}/package.json`); diff --git a/packages/nx/bin/compute-project-graph.ts b/packages/nx/bin/compute-project-graph.ts index bb1b3bdb40..ddafabf2e1 100644 --- a/packages/nx/bin/compute-project-graph.ts +++ b/packages/nx/bin/compute-project-graph.ts @@ -10,7 +10,16 @@ import { isServerAvailable, stop } from '../src/daemon/client/client'; if (await isServerAvailable()) { await stop(); } + const b = new Date(); await buildProjectGraphWithoutDaemon(); + const a = new Date(); + if (process.env.NX_VERBOSE_LOGGING === 'true') { + console.log( + `Nx project graph has been precomputed in ${ + a.getTime() - b.getTime() + }ms` + ); + } } } catch (e) { // Do not error since this runs in a postinstall diff --git a/packages/nx/src/daemon/client/client.ts b/packages/nx/src/daemon/client/client.ts index 6b16699311..17f1648aaa 100644 --- a/packages/nx/src/daemon/client/client.ts +++ b/packages/nx/src/daemon/client/client.ts @@ -15,10 +15,11 @@ import { DAEMON_DIR_FOR_CURRENT_WORKSPACE, DAEMON_OUTPUT_LOG_FILE, isDaemonDisabled, + removeSocketDir, } from '../tmp-dir'; import { ProjectGraph } from '../../config/project-graph'; import { isCI } from '../../utils/is-ci'; -import { NxJsonConfiguration } from 'nx/src/config/nx-json'; +import { NxJsonConfiguration } from '../../config/nx-json'; const DAEMON_ENV_SETTINGS = { ...process.env, @@ -205,6 +206,8 @@ export function stop(): void { stdio: 'inherit', }); + removeSocketDir(); + output.log({ title: 'Daemon Server - Stopped' }); } diff --git a/packages/nx/src/daemon/socket-utils.ts b/packages/nx/src/daemon/socket-utils.ts index a914e10a58..70cbbc2be7 100644 --- a/packages/nx/src/daemon/socket-utils.ts +++ b/packages/nx/src/daemon/socket-utils.ts @@ -2,7 +2,6 @@ import { unlinkSync } from 'fs'; import { platform } from 'os'; import { resolve } from 'path'; import { DAEMON_SOCKET_PATH } from './tmp-dir'; -import { ProjectGraph } from '../config/project-graph'; export const isWindows = platform() === 'win32'; @@ -22,11 +21,6 @@ export function killSocketOrPath(): void { } catch {} } -export interface ProjectGraphServerResult { - error: Error | null; - projectGraph: ProjectGraph | null; -} - // Include the original stack trace within the serialized error so that the client can show it to the user. function serializeError(error: Error | null): string | null { if (!error) { diff --git a/packages/nx/src/daemon/tmp-dir.ts b/packages/nx/src/daemon/tmp-dir.ts index d6406bbe6b..d6b036baa5 100644 --- a/packages/nx/src/daemon/tmp-dir.ts +++ b/packages/nx/src/daemon/tmp-dir.ts @@ -4,8 +4,14 @@ * and where we create the actual unix socket/named pipe for the daemon. */ import { statSync, writeFileSync } from 'fs'; +import { ensureDirSync, rmdirSync } from 'fs-extra'; import { join } from 'path'; import { projectGraphCacheDirectory } from '../utils/cache-directory'; +import { createHash } from 'crypto'; +import { tmpdir } from 'tmp'; +import { workspaceRoot } from '../utils/workspace-root'; + +const socketDir = createSocketDir(); export const DAEMON_DIR_FOR_CURRENT_WORKSPACE = join( projectGraphCacheDirectory, @@ -18,7 +24,7 @@ export const DAEMON_OUTPUT_LOG_FILE = join( ); export const DAEMON_SOCKET_PATH = join( - DAEMON_DIR_FOR_CURRENT_WORKSPACE, + socketDir, // As per notes above on socket/named pipe length limitations, we keep this intentionally short 'd.sock' ); @@ -41,3 +47,30 @@ export function isDaemonDisabled() { return false; } } + +function socketDirName() { + const hasher = createHash('sha256'); + hasher.update(workspaceRoot); + const unique = hasher.digest('hex').substring(0, 20); + return join(tmpdir, unique); +} + +/** + * We try to create a socket file in a tmp dir, but if it doesn't work because + * for instance we don't have permissions, we create it in DAEMON_DIR_FOR_CURRENT_WORKSPACE + */ +function createSocketDir() { + try { + const dir = socketDirName(); + ensureDirSync(dir); + return dir; + } catch (e) { + return DAEMON_DIR_FOR_CURRENT_WORKSPACE; + } +} + +export function removeSocketDir() { + try { + rmdirSync(socketDir); + } catch (e) {} +}