Skip to content

Commit

Permalink
fix(core): normalize file path for node-hasher (#9585)
Browse files Browse the repository at this point in the history
Node hasher paths need to be normalized, since on windows they return with '\' instead of '/' and don't match keys in workspace configuration.

Fixes #9584
Fixes #9581
  • Loading branch information
AgentEnder committed Mar 29, 2022
1 parent ace6673 commit 9123665
Show file tree
Hide file tree
Showing 12 changed files with 33 additions and 14 deletions.
Expand Up @@ -14,10 +14,12 @@ jest.mock('fs', () => require('memfs').fs);
jest.mock('@nrwl/devkit', () => ({
...jest.requireActual<any>('@nrwl/devkit'),
appRootPath: '/root',
workspaceRoot: '/root',
}));

jest.mock('nx/src/utils/app-root', () => ({
appRootPath: '/root',
workspaceRoot: '/root',
}));

const tsconfig = {
Expand Down
1 change: 1 addition & 0 deletions packages/nx/src/command-line/report.spec.ts
Expand Up @@ -5,6 +5,7 @@ import { join } from 'path';

jest.mock('nx/src/utils/app-root', () => ({
appRootPath: '',
workspaceRoot: '',
}));

jest.mock('../utils/fileutils', () => ({
Expand Down
Expand Up @@ -11,6 +11,7 @@ import { stripIndents } from '../../utils/strip-indents';
jest.mock('fs', () => require('memfs').fs);
jest.mock('nx/src/utils/app-root', () => ({
appRootPath: '/root',
workspaceRoot: '/root',
}));

describe('project graph', () => {
Expand Down
14 changes: 8 additions & 6 deletions packages/nx/src/core/hasher/file-hasher-base.ts
@@ -1,8 +1,8 @@
import { appRootPath } from 'nx/src/utils/app-root';
import { workspaceRoot } from 'nx/src/utils/app-root';
import { performance } from 'perf_hooks';
import { defaultHashing } from './hashing-impl';
import { FileData } from 'nx/src/shared/project-graph';
import { joinPathFragments } from 'nx/src/utils/path';
import { joinPathFragments, normalizePath } from 'nx/src/utils/path';

export abstract class FileHasherBase {
protected fileHashes: Map<string, string>;
Expand Down Expand Up @@ -61,16 +61,18 @@ export abstract class FileHasherBase {
if (!this.fileHashes) {
throw new Error('FileHasher is invoked before being initialized');
}
const relativePath = path.startsWith(appRootPath)
? path.substr(appRootPath.length + 1)
: path;
const relativePath = normalizePath(
path.startsWith(workspaceRoot)
? path.substring(workspaceRoot.length + 1)
: path
);
if (this.fileHashes.has(relativePath)) {
return this.fileHashes.get(relativePath);
} else {
try {
// this has to be absolute to avoid issues with cwd
return defaultHashing.hashFile(
joinPathFragments(appRootPath, relativePath)
joinPathFragments(workspaceRoot, relativePath)
);
} catch {
return '';
Expand Down
1 change: 1 addition & 0 deletions packages/nx/src/core/hasher/hasher.spec.ts
Expand Up @@ -4,6 +4,7 @@ import { DependencyType } from 'nx/src/shared/project-graph';
jest.doMock('../../utils/app-root', () => {
return {
appRootPath: '',
workspaceRoot: '',
};
});

Expand Down
18 changes: 11 additions & 7 deletions packages/nx/src/core/hasher/node-based-file-hasher.ts
@@ -1,11 +1,12 @@
import { appRootPath } from 'nx/src/utils/app-root';
import { workspaceRoot } from 'nx/src/utils/app-root';
import { performance } from 'perf_hooks';
import { FileData } from 'nx/src/shared/project-graph';
import { join, relative } from 'path';
import { existsSync, readdirSync, readFileSync, statSync } from 'fs';
import { FileHasherBase } from './file-hasher-base';
import { stripIndents } from '../../utils/strip-indents';
import ignore from 'ignore';
import { normalizePath } from 'nx/src/utils/path';

export class NodeBasedFileHasher extends FileHasherBase {
ignoredGlobs = getIgnoredGlobs();
Expand All @@ -14,7 +15,7 @@ export class NodeBasedFileHasher extends FileHasherBase {
performance.mark('init hashing:start');
this.clear();

this.allFilesInDir(appRootPath, true);
this.allFilesInDir(workspaceRoot, true);

performance.mark('init hashing:end');
performance.measure(
Expand All @@ -36,21 +37,24 @@ export class NodeBasedFileHasher extends FileHasherBase {
absoluteDirName: string,
recurse: boolean = true
): FileData[] {
const relDirName = relative(appRootPath, absoluteDirName);
const relDirName = relative(workspaceRoot, absoluteDirName);
if (relDirName && this.ignoredGlobs.ignores(relDirName)) {
return;
}
try {
readdirSync(absoluteDirName).forEach((c) => {
const absoluteChild = join(absoluteDirName, c);
const relChild = relative(appRootPath, absoluteChild);
const relChild = relative(workspaceRoot, absoluteChild);
if (this.ignoredGlobs.ignores(relChild)) {
return;
}
try {
const s = statSync(absoluteChild);
if (!s.isDirectory()) {
this.fileHashes.set(relChild, this.hashFile(relChild));
this.fileHashes.set(
normalizePath(relChild),
this.hashFile(relChild)
);
} else if (s.isDirectory() && recurse) {
this.allFilesInDir(absoluteChild, true);
}
Expand All @@ -62,8 +66,8 @@ export class NodeBasedFileHasher extends FileHasherBase {

function getIgnoredGlobs() {
const ig = ignore();
ig.add(readFileIfExisting(`${appRootPath}/.gitignore`));
ig.add(readFileIfExisting(`${appRootPath}/.nxignore`));
ig.add(readFileIfExisting(`${workspaceRoot}/.gitignore`));
ig.add(readFileIfExisting(`${workspaceRoot}/.nxignore`));
ig.add(stripIndents`
node_modules
tmp
Expand Down
Expand Up @@ -11,6 +11,7 @@ import { ProjectGraphBuilder } from '../project-graph-builder';
jest.mock('fs', () => require('memfs').fs);
jest.mock('nx/src/utils/app-root', () => ({
appRootPath: '/root',
workspaceRoot: '/root',
}));

describe('explicit package json dependencies', () => {
Expand Down
Expand Up @@ -3,6 +3,7 @@ import { createProjectFileMap } from 'nx/src/core/file-map-utils';
jest.mock('fs', () => require('memfs').fs);
jest.mock('nx/src/utils/app-root', () => ({
appRootPath: '/root',
workspaceRoot: '/root',
}));

import { vol } from 'memfs';
Expand Down
Expand Up @@ -5,6 +5,7 @@ import { buildImplicitProjectDependencies } from './implicit-project-dependencie
jest.mock('fs', () => require('memfs').fs);
jest.mock('nx/src/utils/app-root', () => ({
appRootPath: '/root',
workspaceRoot: '/root',
}));

describe('explicit project dependencies', () => {
Expand Down
Expand Up @@ -3,6 +3,7 @@ import { vol, fs } from 'memfs';
jest.mock('fs', () => require('memfs').fs);
jest.mock('nx/src/utils/app-root', () => ({
appRootPath: '/root',
workspaceRoot: '/root',
}));
import { buildProjectGraph } from './build-project-graph';
import { defaultFileHasher } from '../hasher/file-hasher';
Expand Down
1 change: 1 addition & 0 deletions packages/nx/src/core/target-project-locator.spec.ts
Expand Up @@ -8,6 +8,7 @@ import {

jest.mock('nx/src/utils/app-root', () => ({
appRootPath: '/root',
workspaceRoot: '/root',
}));
jest.mock('fs', () => require('memfs').fs);

Expand Down
Expand Up @@ -7,7 +7,10 @@ import { TargetProjectLocator } from 'nx/src/core/target-project-locator';
import { mapProjectGraphFiles } from '@nrwl/workspace/src/utils/runtime-lint-utils';

jest.mock('fs', () => require('memfs').fs);
jest.mock('nx/src/utils/app-root', () => ({ appRootPath: '/root' }));
jest.mock('nx/src/utils/app-root', () => ({
appRootPath: '/root',
workspaceRoot: '/root',
}));

const tsconfig = {
compilerOptions: {
Expand Down

0 comments on commit 9123665

Please sign in to comment.