Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b232f8a2c8 | |||
| df8060204a | |||
| 73ba102207 | |||
| b9d4cbb474 | |||
| 9bea63171c | |||
| 25143296b4 | |||
| 15fcbbae2b | |||
| a1fe84b66c | |||
| ebf969390e | |||
| b4dbb6b1c9 |
@@ -13,7 +13,7 @@ import {
|
||||
describe('dep-graph-client', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/');
|
||||
cy.get('[data-cy=project-select]').select('Medium');
|
||||
cy.get('[data-cy=project-select]').select('Ocean');
|
||||
});
|
||||
|
||||
it('should display message to select projects', () => {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { BehaviorSubject, combineLatest, fromEvent, Subject } from 'rxjs';
|
||||
import { startWith, takeUntil } from 'rxjs/operators';
|
||||
import { startWith, takeUntil, throwIfEmpty } from 'rxjs/operators';
|
||||
import { projectGraphs } from '../graphs';
|
||||
import { DebuggerPanel } from './debugger-panel';
|
||||
import { GraphComponent } from './graph';
|
||||
@@ -28,9 +28,9 @@ export class AppComponent {
|
||||
}
|
||||
|
||||
private onProjectGraphChange(projectGraphId: string) {
|
||||
const projectGraph = projectGraphs.find(
|
||||
(graph) => graph.id === projectGraphId
|
||||
)?.graph;
|
||||
const project = projectGraphs.find((graph) => graph.id === projectGraphId);
|
||||
const projectGraph = project?.graph;
|
||||
const workspaceLayout = project?.workspaceLayout;
|
||||
|
||||
const nodes = Object.values(projectGraph.nodes).filter(
|
||||
(node) => node.type !== 'npm'
|
||||
@@ -43,6 +43,7 @@ export class AppComponent {
|
||||
window.focusedProject = null;
|
||||
window.projectGraphList = projectGraphs;
|
||||
window.selectedProjectGraph = projectGraphId;
|
||||
window.workspaceLayout = workspaceLayout;
|
||||
|
||||
this.render();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Subject } from 'rxjs';
|
||||
import { ProjectGraphList } from '../graphs';
|
||||
import { GraphPerfReport } from './graph';
|
||||
import { ProjectGraphList } from './models';
|
||||
import { removeChildrenFromContainer } from './util';
|
||||
|
||||
export class DebuggerPanel {
|
||||
|
||||
@@ -101,7 +101,12 @@ export class GraphComponent {
|
||||
> = {};
|
||||
|
||||
selectedProjects.forEach((project) => {
|
||||
const projectNode = new ProjectNode(project);
|
||||
const workspaceRoot =
|
||||
project.type === 'app' || project.type === 'e2e'
|
||||
? window.workspaceLayout.appsDir
|
||||
: window.workspaceLayout.libsDir;
|
||||
|
||||
const projectNode = new ProjectNode(project, workspaceRoot);
|
||||
projectNode.focused = project.name === window.focusedProject;
|
||||
projectNode.affected = this.affectedProjects.includes(project.name);
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import { ProjectGraphCache } from '@nrwl/workspace';
|
||||
|
||||
export interface ProjectGraphList {
|
||||
id: string;
|
||||
label: string;
|
||||
graph: ProjectGraphCache;
|
||||
workspaceLayout: WorkspaceLayout;
|
||||
}
|
||||
|
||||
export interface WorkspaceLayout {
|
||||
libsDir: string;
|
||||
appsDir: string;
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
import { ProjectGraphNode } from '@nrwl/workspace';
|
||||
import { Subject } from 'rxjs';
|
||||
import { removeChildrenFromContainer } from '../util';
|
||||
import {
|
||||
parseParentDirectoriesFromPilePath,
|
||||
removeChildrenFromContainer,
|
||||
} from '../util';
|
||||
|
||||
export class ProjectList {
|
||||
private focusProjectSubject = new Subject<string>();
|
||||
@@ -54,25 +57,35 @@ export class ProjectList {
|
||||
const libProjects = this.getProjectsByType('lib');
|
||||
const e2eProjects = this.getProjectsByType('e2e');
|
||||
|
||||
const appDirectoryGroups = this.groupProjectsByDirectory(appProjects);
|
||||
const libDirectoryGroups = this.groupProjectsByDirectory(libProjects);
|
||||
const e2eDirectoryGroups = this.groupProjectsByDirectory(e2eProjects);
|
||||
|
||||
const sortedAppDirectories = Object.keys(appDirectoryGroups).sort();
|
||||
const sortedLibDirectories = Object.keys(libDirectoryGroups).sort();
|
||||
const sortedE2EDirectories = Object.keys(e2eDirectoryGroups).sort();
|
||||
|
||||
const appsHeader = document.createElement('h4');
|
||||
appsHeader.textContent = 'app projects';
|
||||
this.container.append(appsHeader);
|
||||
this.createProjectList('apps', appProjects);
|
||||
|
||||
sortedAppDirectories.forEach((directoryName) => {
|
||||
this.createProjectList(directoryName, appDirectoryGroups[directoryName]);
|
||||
});
|
||||
|
||||
const e2eHeader = document.createElement('h4');
|
||||
e2eHeader.textContent = 'e2e projects';
|
||||
this.container.append(e2eHeader);
|
||||
this.createProjectList('e2e', e2eProjects);
|
||||
|
||||
sortedE2EDirectories.forEach((directoryName) => {
|
||||
this.createProjectList(directoryName, e2eDirectoryGroups[directoryName]);
|
||||
});
|
||||
|
||||
const libHeader = document.createElement('h4');
|
||||
libHeader.textContent = 'lib projects';
|
||||
this.container.append(libHeader);
|
||||
|
||||
const sortedDirectories = Object.keys(libDirectoryGroups).sort();
|
||||
|
||||
sortedDirectories.forEach((directoryName) => {
|
||||
sortedLibDirectories.forEach((directoryName) => {
|
||||
this.createProjectList(directoryName, libDirectoryGroups[directoryName]);
|
||||
});
|
||||
}
|
||||
@@ -83,12 +96,19 @@ export class ProjectList {
|
||||
.sort((a, b) => a.name.localeCompare(b.name));
|
||||
}
|
||||
|
||||
private groupProjectsByDirectory(projects) {
|
||||
private groupProjectsByDirectory(projects: ProjectGraphNode[]) {
|
||||
let groups = {};
|
||||
|
||||
projects.forEach((project) => {
|
||||
const split = project.data.root.split('/');
|
||||
const directory = split.slice(1, -1).join('/');
|
||||
const workspaceRoot =
|
||||
project.type === 'app' || project.type === 'e2e'
|
||||
? window.workspaceLayout.appsDir
|
||||
: window.workspaceLayout.libsDir;
|
||||
const directories = parseParentDirectoriesFromPilePath(
|
||||
project.data.root,
|
||||
workspaceRoot
|
||||
);
|
||||
const directory = directories.join('/');
|
||||
|
||||
if (!groups.hasOwnProperty(directory)) {
|
||||
groups[directory] = [];
|
||||
|
||||
@@ -3,18 +3,21 @@ import { ProjectNode } from './project-node';
|
||||
describe('ProjectNode', () => {
|
||||
describe('app nodes', () => {
|
||||
it('should not set parentId if groupByFolder is false', () => {
|
||||
const projectNode = new ProjectNode({
|
||||
name: 'sub-app',
|
||||
type: 'app',
|
||||
data: {
|
||||
projectType: 'application',
|
||||
root: 'apps/sub/app',
|
||||
sourceRoot: 'apps/sub/app/src',
|
||||
prefix: 'sub-app',
|
||||
tags: [],
|
||||
files: [],
|
||||
const projectNode = new ProjectNode(
|
||||
{
|
||||
name: 'sub-app',
|
||||
type: 'app',
|
||||
data: {
|
||||
projectType: 'application',
|
||||
root: 'apps/sub/app',
|
||||
sourceRoot: 'apps/sub/app/src',
|
||||
prefix: 'sub-app',
|
||||
tags: [],
|
||||
files: [],
|
||||
},
|
||||
},
|
||||
});
|
||||
'apps'
|
||||
);
|
||||
|
||||
const result = projectNode.getCytoscapeNodeDef(false);
|
||||
|
||||
@@ -22,18 +25,21 @@ describe('ProjectNode', () => {
|
||||
});
|
||||
|
||||
it('should not set parentId if app is not nested', () => {
|
||||
const projectNode = new ProjectNode({
|
||||
name: 'app',
|
||||
type: 'app',
|
||||
data: {
|
||||
projectType: 'application',
|
||||
root: 'apps/app',
|
||||
sourceRoot: 'apps/app/src',
|
||||
prefix: 'app',
|
||||
tags: [],
|
||||
files: [],
|
||||
const projectNode = new ProjectNode(
|
||||
{
|
||||
name: 'app',
|
||||
type: 'app',
|
||||
data: {
|
||||
projectType: 'application',
|
||||
root: 'apps/app',
|
||||
sourceRoot: 'apps/app/src',
|
||||
prefix: 'app',
|
||||
tags: [],
|
||||
files: [],
|
||||
},
|
||||
},
|
||||
});
|
||||
'apps'
|
||||
);
|
||||
|
||||
const result = projectNode.getCytoscapeNodeDef(false);
|
||||
|
||||
@@ -41,18 +47,21 @@ describe('ProjectNode', () => {
|
||||
});
|
||||
|
||||
it('should set parentId if the app is nested and groupByFolder is true', () => {
|
||||
const projectNode = new ProjectNode({
|
||||
name: 'sub-app',
|
||||
type: 'app',
|
||||
data: {
|
||||
projectType: 'application',
|
||||
root: 'apps/sub/app',
|
||||
sourceRoot: 'apps/sub/app/src',
|
||||
prefix: 'sub-app',
|
||||
tags: [],
|
||||
files: [],
|
||||
const projectNode = new ProjectNode(
|
||||
{
|
||||
name: 'sub-app',
|
||||
type: 'app',
|
||||
data: {
|
||||
projectType: 'application',
|
||||
root: 'apps/sub/app',
|
||||
sourceRoot: 'apps/sub/app/src',
|
||||
prefix: 'sub-app',
|
||||
tags: [],
|
||||
files: [],
|
||||
},
|
||||
},
|
||||
});
|
||||
'apps'
|
||||
);
|
||||
|
||||
const result = projectNode.getCytoscapeNodeDef(true);
|
||||
|
||||
@@ -62,16 +71,19 @@ describe('ProjectNode', () => {
|
||||
|
||||
describe('lib nodes', () => {
|
||||
it('should not set parentId if groupByFolder is false', () => {
|
||||
const projectNode = new ProjectNode({
|
||||
name: 'sub-lib',
|
||||
type: 'lib',
|
||||
data: {
|
||||
root: 'libs/sub/lib',
|
||||
sourceRoot: 'libs/sub/lib/src',
|
||||
projectType: 'library',
|
||||
files: [],
|
||||
const projectNode = new ProjectNode(
|
||||
{
|
||||
name: 'sub-lib',
|
||||
type: 'lib',
|
||||
data: {
|
||||
root: 'libs/sub/lib',
|
||||
sourceRoot: 'libs/sub/lib/src',
|
||||
projectType: 'library',
|
||||
files: [],
|
||||
},
|
||||
},
|
||||
});
|
||||
'libs'
|
||||
);
|
||||
|
||||
const result = projectNode.getCytoscapeNodeDef(false);
|
||||
|
||||
@@ -79,16 +91,19 @@ describe('ProjectNode', () => {
|
||||
});
|
||||
|
||||
it('should not set parentId if lib is not nested', () => {
|
||||
const projectNode = new ProjectNode({
|
||||
name: 'lib',
|
||||
type: 'lib',
|
||||
data: {
|
||||
root: 'libs/lib',
|
||||
sourceRoot: 'libs/lib/src',
|
||||
projectType: 'library',
|
||||
files: [],
|
||||
const projectNode = new ProjectNode(
|
||||
{
|
||||
name: 'lib',
|
||||
type: 'lib',
|
||||
data: {
|
||||
root: 'libs/lib',
|
||||
sourceRoot: 'libs/lib/src',
|
||||
projectType: 'library',
|
||||
files: [],
|
||||
},
|
||||
},
|
||||
});
|
||||
'libs'
|
||||
);
|
||||
|
||||
const result = projectNode.getCytoscapeNodeDef(false);
|
||||
|
||||
@@ -96,16 +111,19 @@ describe('ProjectNode', () => {
|
||||
});
|
||||
|
||||
it('should set parentId if the lib is nested and groupByFolder is true', () => {
|
||||
const projectNode = new ProjectNode({
|
||||
name: 'sub-lib',
|
||||
type: 'lib',
|
||||
data: {
|
||||
root: 'libs/sub/lib',
|
||||
sourceRoot: 'libs/sub/lib/src',
|
||||
projectType: 'library',
|
||||
files: [],
|
||||
const projectNode = new ProjectNode(
|
||||
{
|
||||
name: 'sub-lib',
|
||||
type: 'lib',
|
||||
data: {
|
||||
root: 'libs/sub/lib',
|
||||
sourceRoot: 'libs/sub/lib/src',
|
||||
projectType: 'library',
|
||||
files: [],
|
||||
},
|
||||
},
|
||||
});
|
||||
'libs'
|
||||
);
|
||||
|
||||
const result = projectNode.getCytoscapeNodeDef(true);
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { ProjectGraphNode } from '@nrwl/workspace';
|
||||
import * as cy from 'cytoscape';
|
||||
import { parseParentDirectoriesFromPilePath } from '../util';
|
||||
|
||||
interface NodeDataDefinition extends cy.NodeDataDefinition {
|
||||
id: string;
|
||||
@@ -7,11 +8,19 @@ interface NodeDataDefinition extends cy.NodeDataDefinition {
|
||||
tags: string[];
|
||||
}
|
||||
|
||||
interface Ancestor {
|
||||
id: string;
|
||||
parentId: string;
|
||||
label: string;
|
||||
}
|
||||
export class ProjectNode {
|
||||
affected = false;
|
||||
focused = false;
|
||||
|
||||
constructor(private project: ProjectGraphNode) {}
|
||||
constructor(
|
||||
private project: ProjectGraphNode,
|
||||
private workspaceRoot: string
|
||||
) {}
|
||||
|
||||
getCytoscapeNodeDef(groupByFolder: boolean): cy.NodeDefinition {
|
||||
return {
|
||||
@@ -30,8 +39,8 @@ export class ProjectNode {
|
||||
type: this.project.type,
|
||||
tags: this.project.data.tags,
|
||||
parent:
|
||||
groupByFolder && this.project.data.hasOwnProperty('sourceRoot')
|
||||
? this.getParentId(this.project.data.sourceRoot)
|
||||
groupByFolder && this.project.data.hasOwnProperty('root')
|
||||
? this.getParentId()
|
||||
: null,
|
||||
};
|
||||
}
|
||||
@@ -50,62 +59,39 @@ export class ProjectNode {
|
||||
return classes;
|
||||
}
|
||||
|
||||
private getParentId(sourceRoot: string): string | null {
|
||||
const split = sourceRoot.split('/');
|
||||
let directories = split.slice(1, -2);
|
||||
private getParentId(): string | null {
|
||||
const ancestors = this.getAncestors();
|
||||
|
||||
if (directories.length > 0) {
|
||||
let directory = directories.join('/');
|
||||
return `dir-${directory}`;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private getGrandParentId(sourceRoot: string): string | null {
|
||||
const split = sourceRoot.split('/');
|
||||
let directories = split.slice(1, -3);
|
||||
|
||||
if (directories.length > 0) {
|
||||
let directory = directories.join('/');
|
||||
return `dir-${directory}`;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public getAncestors(): { id: string; parentId: string; label: string }[] {
|
||||
if (!this.project.data.sourceRoot) {
|
||||
return [];
|
||||
}
|
||||
const split = this.project.data.sourceRoot.split('/');
|
||||
let directories = split.slice(1, -2);
|
||||
|
||||
if (directories.length > 0) {
|
||||
const ancestors: { id: string; parentId: string; label: string }[] = [
|
||||
{
|
||||
label: directories.join('/'),
|
||||
id: this.getParentId(this.project.data.sourceRoot),
|
||||
parentId: this.getGrandParentId(this.project.data.sourceRoot),
|
||||
},
|
||||
];
|
||||
|
||||
while (directories.length > 1) {
|
||||
const sourceRoot = directories.join('/');
|
||||
const parentData = {
|
||||
id: this.getParentId(sourceRoot),
|
||||
parentId: this.getGrandParentId(this.project.data.sourceRoot),
|
||||
label: sourceRoot,
|
||||
};
|
||||
ancestors.push(parentData);
|
||||
|
||||
const split = sourceRoot.split('/');
|
||||
directories = split.slice(0, -1);
|
||||
}
|
||||
|
||||
return ancestors;
|
||||
if (ancestors.length > 0) {
|
||||
return ancestors[ancestors.length - 1].id;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public getAncestors(): Ancestor[] {
|
||||
// if there's no root, we can't figure out the parent
|
||||
if (!this.project.data.root) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const directories = parseParentDirectoriesFromPilePath(
|
||||
this.project.data.root,
|
||||
this.workspaceRoot
|
||||
);
|
||||
|
||||
return directories.map((directory, index, allDirectories) => {
|
||||
const label = [...allDirectories].slice(0, index + 1).join('/');
|
||||
const id = `dir-${label}`;
|
||||
const parentId =
|
||||
index > 0
|
||||
? `dir-${[...allDirectories].slice(0, index).join('/')}`
|
||||
: null;
|
||||
return {
|
||||
label,
|
||||
id,
|
||||
parentId,
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import { parseParentDirectoriesFromPilePath } from './util';
|
||||
|
||||
describe('parseParentDirectoriesFromPilePath', () => {
|
||||
// path, workspaceRoot, output
|
||||
const cases: [string, string, string[]][] = [
|
||||
['apps/app1', 'apps', []],
|
||||
['apps/app1', '', ['apps']],
|
||||
['apps/nested/app1', 'apps', ['nested']],
|
||||
['libs/scope/some-lib', 'libs', ['scope']],
|
||||
[
|
||||
'libs/very/very/very/deeply/nested/lib',
|
||||
'libs',
|
||||
['very', 'very', 'very', 'deeply', 'nested'],
|
||||
],
|
||||
['packages/published', 'packages', []],
|
||||
['packages/published', '', ['packages']],
|
||||
['packages/published', 'libs', ['packages']],
|
||||
['libs/trailing/slash/', 'libs', ['trailing']],
|
||||
['libs/trailing/slash', 'libs/', ['trailing']],
|
||||
];
|
||||
|
||||
test.each(cases)(
|
||||
'given filepath %p and workspaceRoot %p, parent directories are %p',
|
||||
(path, workspaceRoot, expected) => {
|
||||
const result = parseParentDirectoriesFromPilePath(path, workspaceRoot);
|
||||
|
||||
expect(result).toEqual(expected);
|
||||
}
|
||||
);
|
||||
});
|
||||
@@ -3,3 +3,27 @@ export function removeChildrenFromContainer(container: HTMLElement) {
|
||||
container.removeChild(child)
|
||||
);
|
||||
}
|
||||
|
||||
export function trimBackSlash(value: string): string {
|
||||
return value.replace(/\/$/, '');
|
||||
}
|
||||
|
||||
export function parseParentDirectoriesFromPilePath(
|
||||
path: string,
|
||||
workspaceRoot: string
|
||||
) {
|
||||
const root = trimBackSlash(path);
|
||||
|
||||
// split the source root on directory separator
|
||||
const split: string[] = root.split('/');
|
||||
|
||||
// check the first part for libs or apps, depending on workspaceLayout
|
||||
if (split[0] === trimBackSlash(workspaceRoot)) {
|
||||
split.shift();
|
||||
}
|
||||
|
||||
// pop off the last element, which should be the lib name
|
||||
split.pop();
|
||||
|
||||
return split;
|
||||
}
|
||||
|
||||
Vendored
+5
@@ -1,3 +1,4 @@
|
||||
import { WorkspaceConfiguration } from '@nrwl/devkit';
|
||||
import { ProjectGraph, ProjectGraphNode } from '@nrwl/workspace';
|
||||
import { ProjectGraphList } from './graphs';
|
||||
|
||||
@@ -14,6 +15,10 @@ export declare global {
|
||||
excludeProject: Function;
|
||||
projectGraphList: ProjectGraphList[];
|
||||
selectedProjectGraph: string;
|
||||
workspaceLayout: {
|
||||
libsDir: string;
|
||||
appsDir: string;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,28 +1,39 @@
|
||||
import { ProjectGraphCache } from '@nrwl/workspace';
|
||||
import { mediumGraph } from './medium';
|
||||
import { smallGraph } from './small';
|
||||
import { subAppsGraph } from './sub-apps';
|
||||
|
||||
export interface ProjectGraphList {
|
||||
id: string;
|
||||
label: string;
|
||||
graph: ProjectGraphCache;
|
||||
}
|
||||
import { ProjectGraphList } from '../app/models';
|
||||
import { oceanGraph, oceanWorkspaceLayout } from './ocean';
|
||||
import { nxGraph, nxWorkspaceLayout } from './nx';
|
||||
import { storybookGraph, storybookWorkspaceLayout } from './storybook';
|
||||
import { subAppsGraph, subAppsWorkspaceLayout } from './sub-apps';
|
||||
import { nxExamplesGraph, nxExamplesWorkspaceLayout } from './nx-examples';
|
||||
|
||||
export const projectGraphs: ProjectGraphList[] = [
|
||||
{
|
||||
id: 'small',
|
||||
label: 'Small',
|
||||
graph: smallGraph,
|
||||
id: 'nx',
|
||||
label: 'Nx',
|
||||
graph: nxGraph,
|
||||
workspaceLayout: nxWorkspaceLayout,
|
||||
},
|
||||
{
|
||||
id: 'medium',
|
||||
label: 'Medium',
|
||||
graph: mediumGraph,
|
||||
id: 'ocean',
|
||||
label: 'Ocean',
|
||||
graph: oceanGraph,
|
||||
workspaceLayout: oceanWorkspaceLayout,
|
||||
},
|
||||
{
|
||||
id: 'nx-examples',
|
||||
label: 'Nx Examples',
|
||||
graph: nxExamplesGraph,
|
||||
workspaceLayout: nxExamplesWorkspaceLayout,
|
||||
},
|
||||
{
|
||||
id: 'sub-apps',
|
||||
label: 'Sub Apps',
|
||||
graph: subAppsGraph,
|
||||
workspaceLayout: subAppsWorkspaceLayout,
|
||||
},
|
||||
{
|
||||
id: 'storybook',
|
||||
label: 'Storybook',
|
||||
graph: storybookGraph,
|
||||
workspaceLayout: storybookWorkspaceLayout,
|
||||
},
|
||||
];
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+6156
-4925
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,10 @@
|
||||
import { ProjectGraphCache } from '@nrwl/workspace';
|
||||
import { WorkspaceLayout } from '../app/models';
|
||||
|
||||
export const subAppsWorkspaceLayout: WorkspaceLayout = {
|
||||
appsDir: 'apps',
|
||||
libsDir: 'libs',
|
||||
};
|
||||
|
||||
export const subAppsGraph: ProjectGraphCache = {
|
||||
version: '2.0',
|
||||
|
||||
@@ -60,5 +60,6 @@
|
||||
window.filteredProjects = [];
|
||||
window.groupByFolder = false;
|
||||
window.exclude = [];
|
||||
window.workspaceLayout = null;
|
||||
</script>
|
||||
</body>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { AppComponent } from './app/app';
|
||||
import { environment } from './environments/environment';
|
||||
import { projectGraphs } from './graphs';
|
||||
import { smallGraph } from './graphs/small';
|
||||
import { nxGraph } from './graphs/nx';
|
||||
|
||||
if (!environment.release) {
|
||||
const currentGraph = smallGraph;
|
||||
const currentGraph = nxGraph;
|
||||
|
||||
const nodes = Object.values(currentGraph.nodes).filter(
|
||||
(node) => node.type !== 'npm'
|
||||
@@ -16,5 +16,6 @@ if (!environment.release) {
|
||||
window.exclude = [];
|
||||
window.projectGraphList = projectGraphs;
|
||||
window.selectedProjectGraph = projectGraphs[0].id;
|
||||
window.workspaceLayout = projectGraphs[0].workspaceLayout;
|
||||
}
|
||||
setTimeout(() => new AppComponent(environment.appConfig));
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
"compilerOptions": {
|
||||
"outDir": "../../dist/out-tsc",
|
||||
"module": "commonjs",
|
||||
"types": ["jest", "node"]
|
||||
"types": ["jest", "node"],
|
||||
"lib": ["DOM"]
|
||||
},
|
||||
"files": ["src/test-setup.ts"],
|
||||
"include": ["**/*.spec.ts", "**/*.d.ts"]
|
||||
|
||||
@@ -153,6 +153,11 @@ describe('Next.js Applications', () => {
|
||||
export function testFn(): string {
|
||||
return 'Hello Nx';
|
||||
};
|
||||
|
||||
// testing whether async-await code in Node / Next.js api routes works as expected
|
||||
export async function testAsyncFn() {
|
||||
return await Promise.resolve('hell0');
|
||||
}
|
||||
`
|
||||
);
|
||||
|
||||
@@ -165,7 +170,9 @@ describe('Next.js Applications', () => {
|
||||
}
|
||||
|
||||
export const TestComponent = ({ text }: TestComponentProps) => {
|
||||
return <span>{text}</span>;
|
||||
// testing whether modern languages features like nullish coalescing work
|
||||
const t = text ?? 'abc';
|
||||
return <span>{t}</span>;
|
||||
};
|
||||
|
||||
export default TestComponent;
|
||||
@@ -175,6 +182,18 @@ describe('Next.js Applications', () => {
|
||||
const mainPath = `apps/${appName}/pages/index.tsx`;
|
||||
const content = readFile(mainPath);
|
||||
|
||||
updateFile(
|
||||
`apps/${appName}/pages/api/hello.ts`,
|
||||
`
|
||||
import { testAsyncFn } from '@${proj}/${tsLibName}';
|
||||
|
||||
export default async function handler(_, res) {
|
||||
const value = await testAsyncFn();
|
||||
res.send(value);
|
||||
}
|
||||
`
|
||||
);
|
||||
|
||||
updateFile(
|
||||
mainPath,
|
||||
`
|
||||
@@ -191,10 +210,26 @@ describe('Next.js Applications', () => {
|
||||
)}`
|
||||
);
|
||||
|
||||
const e2eTestPath = `apps/${appName}-e2e/src/integration/app.spec.ts`;
|
||||
const e2eContent = readFile(e2eTestPath);
|
||||
updateFile(
|
||||
e2eTestPath,
|
||||
`
|
||||
${
|
||||
e2eContent +
|
||||
`
|
||||
it('should successfully call async API route', () => {
|
||||
cy.request('/api/hello').its('body').should('include', 'hell0');
|
||||
});
|
||||
`
|
||||
}
|
||||
`
|
||||
);
|
||||
|
||||
await checkApp(appName, {
|
||||
checkUnitTest: true,
|
||||
checkLint: true,
|
||||
checkE2E: false,
|
||||
checkE2E: true,
|
||||
});
|
||||
}, 120000);
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@ import {
|
||||
updateFile,
|
||||
workspaceConfigName,
|
||||
} from '@nrwl/e2e/utils';
|
||||
import { TaskCacheStatus } from '@nrwl/workspace/src/utilities/output';
|
||||
|
||||
describe('run-one', () => {
|
||||
let proj: string;
|
||||
@@ -638,7 +637,7 @@ describe('cache', () => {
|
||||
});
|
||||
const outputWithBuildApp2Cached = runCLI(`affected:build ${files}`);
|
||||
expect(outputWithBuildApp2Cached).toContain('read the output from cache');
|
||||
expectMatchedOutput(outputWithBuildApp2Cached, [myapp2]);
|
||||
expectCached(outputWithBuildApp2Cached, [myapp2]);
|
||||
|
||||
// touch package.json
|
||||
// --------------------------------------------
|
||||
@@ -652,17 +651,13 @@ describe('cache', () => {
|
||||
|
||||
// build individual project with caching
|
||||
const individualBuildWithCache = runCLI(`build ${myapp1}`);
|
||||
expect(individualBuildWithCache).toContain(
|
||||
TaskCacheStatus.MatchedExistingOutput
|
||||
);
|
||||
expect(individualBuildWithCache).toContain('from cache');
|
||||
|
||||
// skip caching when building individual projects
|
||||
const individualBuildWithSkippedCache = runCLI(
|
||||
`build ${myapp1} --skip-nx-cache`
|
||||
);
|
||||
expect(individualBuildWithSkippedCache).not.toContain(
|
||||
TaskCacheStatus.MatchedExistingOutput
|
||||
);
|
||||
expect(individualBuildWithSkippedCache).not.toContain('from cache');
|
||||
|
||||
// run lint with caching
|
||||
// --------------------------------------------
|
||||
@@ -673,7 +668,7 @@ describe('cache', () => {
|
||||
expect(outputWithBothLintTasksCached).toContain(
|
||||
'read the output from cache'
|
||||
);
|
||||
expectMatchedOutput(outputWithBothLintTasksCached, [
|
||||
expectCached(outputWithBothLintTasksCached, [
|
||||
myapp1,
|
||||
myapp2,
|
||||
`${myapp1}-e2e`,
|
||||
@@ -752,38 +747,19 @@ describe('cache', () => {
|
||||
actualOutput: string,
|
||||
expectedCachedProjects: string[]
|
||||
) {
|
||||
expectProjectMatchTaskCacheStatus(actualOutput, expectedCachedProjects);
|
||||
}
|
||||
|
||||
function expectMatchedOutput(
|
||||
actualOutput: string,
|
||||
expectedMatchedOutputProjects: string[]
|
||||
) {
|
||||
expectProjectMatchTaskCacheStatus(
|
||||
actualOutput,
|
||||
expectedMatchedOutputProjects,
|
||||
TaskCacheStatus.MatchedExistingOutput
|
||||
);
|
||||
}
|
||||
|
||||
function expectProjectMatchTaskCacheStatus(
|
||||
actualOutput: string,
|
||||
expectedProjects: string[],
|
||||
cacheStatus: TaskCacheStatus = TaskCacheStatus.RetrievedFromCache
|
||||
) {
|
||||
const matchingProjects = [];
|
||||
const cachedProjects = [];
|
||||
const lines = actualOutput.split('\n');
|
||||
lines.forEach((s) => {
|
||||
lines.forEach((s, i) => {
|
||||
if (s.startsWith(`> nx run`)) {
|
||||
const projectName = s.split(`> nx run `)[1].split(':')[0].trim();
|
||||
if (s.indexOf(cacheStatus) > -1) {
|
||||
matchingProjects.push(projectName);
|
||||
if (s.indexOf('from cache') > -1) {
|
||||
cachedProjects.push(projectName);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
matchingProjects.sort((a, b) => a.localeCompare(b));
|
||||
expectedProjects.sort((a, b) => a.localeCompare(b));
|
||||
expect(matchingProjects).toEqual(expectedProjects);
|
||||
cachedProjects.sort((a, b) => a.localeCompare(b));
|
||||
expectedCachedProjects.sort((a, b) => a.localeCompare(b));
|
||||
expect(cachedProjects).toEqual(expectedCachedProjects);
|
||||
}
|
||||
});
|
||||
|
||||
+1
-4
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nrwl/nx-source",
|
||||
"version": "12.0.1",
|
||||
"version": "12.0.5",
|
||||
"description": "Powerful, Extensible Dev Tools",
|
||||
"homepage": "https://nx.dev",
|
||||
"private": true,
|
||||
@@ -59,7 +59,6 @@
|
||||
"@ngrx/schematics": "11.0.0",
|
||||
"@ngrx/store": "11.0.0",
|
||||
"@ngrx/store-devtools": "11.0.0",
|
||||
"@ngtools/webpack": "~10.1.3",
|
||||
"@nrwl/cli": "12.0.0",
|
||||
"@nrwl/cypress": "12.0.0",
|
||||
"@nrwl/eslint-plugin-nx": "12.0.0",
|
||||
@@ -117,7 +116,6 @@
|
||||
"chalk": "4.1.0",
|
||||
"circular-dependency-plugin": "5.2.0",
|
||||
"clean-css": "4.2.1",
|
||||
"codelyzer": "~5.0.1",
|
||||
"commitizen": "^4.0.3",
|
||||
"confusing-browser-globals": "^1.0.9",
|
||||
"conventional-changelog-cli": "^2.0.23",
|
||||
@@ -237,7 +235,6 @@
|
||||
"ts-node": "9.1.1",
|
||||
"tsconfig-paths": "^3.9.0",
|
||||
"tsconfig-paths-webpack-plugin": "3.2.0",
|
||||
"tsickle": "^0.38.1",
|
||||
"tslib": "^2.0.0",
|
||||
"tslint": "6.1.3",
|
||||
"tslint-to-eslint-config": "2.2.0",
|
||||
|
||||
@@ -8,11 +8,7 @@ import { Workspace } from './workspace';
|
||||
*
|
||||
* @param dir Directory to start searching with
|
||||
*/
|
||||
export function findWorkspaceRoot(dir: string): Workspace {
|
||||
if (path.dirname(dir) === dir) {
|
||||
return null;
|
||||
}
|
||||
|
||||
export function findWorkspaceRoot(dir: string): Workspace | null {
|
||||
if (existsSync(path.join(dir, 'angular.json'))) {
|
||||
return { type: 'angular', dir };
|
||||
}
|
||||
@@ -21,5 +17,9 @@ export function findWorkspaceRoot(dir: string): Workspace {
|
||||
return { type: 'nx', dir };
|
||||
}
|
||||
|
||||
if (path.dirname(dir) === dir) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return findWorkspaceRoot(path.dirname(dir));
|
||||
}
|
||||
|
||||
@@ -184,6 +184,25 @@ describe('app', () => {
|
||||
).toContain('Welcome to my-app');
|
||||
});
|
||||
|
||||
it.each`
|
||||
style
|
||||
${'styled-components'}
|
||||
${'styled-jsx'}
|
||||
${'@emotion/styled'}
|
||||
`(
|
||||
'should generate valid .babelrc JSON config for CSS-in-JS solutions',
|
||||
async ({ style }) => {
|
||||
await applicationGenerator(appTree, {
|
||||
...schema,
|
||||
style,
|
||||
});
|
||||
|
||||
expect(() => {
|
||||
JSON.parse(appTree.read(`apps/my-app/.babelrc`).toString());
|
||||
}).not.toThrow();
|
||||
}
|
||||
);
|
||||
|
||||
describe('--style scss', () => {
|
||||
it('should generate scss styles', async () => {
|
||||
await applicationGenerator(appTree, { ...schema, style: 'scss' });
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
"@nrwl/react/babel", {
|
||||
"runtime": "automatic",
|
||||
"useBuiltIns": "usage"
|
||||
<% if (style === '@emotion/styled') { %>,"importSource": "@emotion/react" }<% } %>
|
||||
<% if (style === '@emotion/styled') { %>,"importSource": "@emotion/react"<% } %>
|
||||
}
|
||||
]
|
||||
],
|
||||
"plugins": [
|
||||
<% if (style === 'styled-components') { %>["styled-components", { "pure": true, "ssr": true }]<% } %>
|
||||
<% if (style === 'styled-jsx') { %>"styled-jsx/babel"<% } %>
|
||||
<% if (style === '@emotion/styled') { %>,"@emotion/babel-plugin"<% } %>
|
||||
<% if (style === '@emotion/styled') { %>"@emotion/babel-plugin"<% } %>
|
||||
]
|
||||
}
|
||||
|
||||
@@ -614,4 +614,24 @@ describe('lib', () => {
|
||||
).not.toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
it.each`
|
||||
style
|
||||
${'styled-components'}
|
||||
${'styled-jsx'}
|
||||
${'@emotion/styled'}
|
||||
`(
|
||||
'should generate valid .babelrc JSON config for CSS-in-JS solutions',
|
||||
async ({ style }) => {
|
||||
await libraryGenerator(appTree, {
|
||||
...defaultSchema,
|
||||
style,
|
||||
name: 'myLib',
|
||||
});
|
||||
|
||||
expect(() => {
|
||||
JSON.parse(appTree.read(`libs/my-lib/.babelrc`).toString());
|
||||
}).not.toThrow();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
@@ -20,9 +20,6 @@ module.exports = function (api: any, options: NxReactBabelPresetOptions = {}) {
|
||||
|
||||
const isModern = api.caller((caller) => caller?.isModern);
|
||||
|
||||
// `isServer` is passed from `next-babel-loader`, when it compiles for the server
|
||||
const isServer = api.caller((caller) => caller?.isServer);
|
||||
|
||||
// This is set by `@nrwl/web:package` executor
|
||||
const isNxPackage = api.caller((caller) => caller?.isNxPackage);
|
||||
|
||||
@@ -38,7 +35,7 @@ module.exports = function (api: any, options: NxReactBabelPresetOptions = {}) {
|
||||
// For Jest tests, NODE_ENV is set as 'test' and we only want to set target as Node.
|
||||
// All other options will fail in Jest since Node does not support some ES features
|
||||
// such as import syntax.
|
||||
isServer || process.env.NODE_ENV === 'test'
|
||||
process.env.NODE_ENV === 'test'
|
||||
? { targets: { node: 'current' } }
|
||||
: {
|
||||
// Allow importing core-js in entrypoint and use browserlist to select polyfills.
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
} from '../core/project-graph';
|
||||
import { appRootPath } from '../utilities/app-root';
|
||||
import { output } from '../utilities/output';
|
||||
import { workspaceLayout } from '../core/file-utils';
|
||||
|
||||
// maps file extention to MIME types
|
||||
const mimeType = {
|
||||
@@ -38,7 +39,8 @@ function projectsToHtml(
|
||||
affected: string[],
|
||||
focus: string,
|
||||
groupByFolder: boolean,
|
||||
exclude: string[]
|
||||
exclude: string[],
|
||||
layout: { appsDir: string; libsDir: string }
|
||||
) {
|
||||
let f = readFileSync(
|
||||
join(__dirname, '../core/dep-graph/index.html')
|
||||
@@ -61,6 +63,10 @@ function projectsToHtml(
|
||||
.replace(
|
||||
`window.exclude = []`,
|
||||
`window.exclude = ${JSON.stringify(exclude)}`
|
||||
)
|
||||
.replace(
|
||||
`window.workspaceLayout = null`,
|
||||
`window.workspaceLayout = ${JSON.stringify(layout)}`
|
||||
);
|
||||
|
||||
if (focus) {
|
||||
@@ -149,6 +155,7 @@ export function generateGraph(
|
||||
affectedProjects: string[]
|
||||
): void {
|
||||
let graph = onlyWorkspaceProjects(createProjectGraph());
|
||||
const layout = workspaceLayout();
|
||||
|
||||
const projects = Object.values(graph.nodes) as ProjectGraphNode[];
|
||||
projects.sort((a, b) => {
|
||||
@@ -192,7 +199,8 @@ export function generateGraph(
|
||||
affectedProjects,
|
||||
args.focus || null,
|
||||
args.groupByFolder || false,
|
||||
args.exclude || []
|
||||
args.exclude || [],
|
||||
layout
|
||||
);
|
||||
} else {
|
||||
graph = filterGraph(graph, args.focus || null, args.exclude || []);
|
||||
|
||||
@@ -45,19 +45,21 @@ function getUntrackedFiles(): string[] {
|
||||
function getFilesUsingBaseAndHead(base: string, head: string): string[] {
|
||||
let mergeBase;
|
||||
try {
|
||||
mergeBase = execSync(`git merge-base ${base} ${head}`, {
|
||||
mergeBase = execSync(`git merge-base "${base}" "${head}"`, {
|
||||
maxBuffer: TEN_MEGABYTES,
|
||||
})
|
||||
.toString()
|
||||
.trim();
|
||||
} catch {
|
||||
mergeBase = execSync(`git merge-base --fork-point ${base} ${head}`, {
|
||||
mergeBase = execSync(`git merge-base --fork-point "${base}" "${head}"`, {
|
||||
maxBuffer: TEN_MEGABYTES,
|
||||
})
|
||||
.toString()
|
||||
.trim();
|
||||
}
|
||||
return parseGitOutput(`git diff --name-only --relative ${mergeBase} ${head}`);
|
||||
return parseGitOutput(
|
||||
`git diff --name-only --relative "${mergeBase}" "${head}"`
|
||||
);
|
||||
}
|
||||
|
||||
function parseGitOutput(command: string): string[] {
|
||||
|
||||
@@ -203,11 +203,10 @@ export function readNxJson(): NxJsonConfiguration {
|
||||
|
||||
export function workspaceLayout(): { appsDir: string; libsDir: string } {
|
||||
const nxJson = readNxJson();
|
||||
const appsDir =
|
||||
(nxJson.workspaceLayout && nxJson.workspaceLayout.appsDir) || 'apps';
|
||||
const libsDir =
|
||||
(nxJson.workspaceLayout && nxJson.workspaceLayout.libsDir) || 'libs';
|
||||
return { appsDir, libsDir };
|
||||
return {
|
||||
appsDir: nxJson.workspaceLayout?.appsDir ?? 'apps',
|
||||
libsDir: nxJson.workspaceLayout?.libsDir ?? 'libs',
|
||||
};
|
||||
}
|
||||
|
||||
// TODO: Make this list extensible
|
||||
|
||||
@@ -12,7 +12,6 @@ import * as fsExtra from 'fs-extra';
|
||||
import { DefaultTasksRunnerOptions } from './default-tasks-runner';
|
||||
import { spawn } from 'child_process';
|
||||
import { cacheDirectory } from '../utilities/cache-directory';
|
||||
import { readJsonFile, writeJsonFile } from '../utilities/fileutils';
|
||||
|
||||
export type CachedResult = { terminalOutput: string; outputsPath: string };
|
||||
export type TaskWithCachedResult = { task: Task; cachedResult: CachedResult };
|
||||
@@ -39,7 +38,6 @@ export class Cache {
|
||||
root = appRootPath;
|
||||
cachePath = this.createCacheDir();
|
||||
terminalOutputsDir = this.createTerminalOutputsDir();
|
||||
nxOutputsPath = this.ensureNxOutputsFile();
|
||||
cacheConfig = new CacheConfig(this.options);
|
||||
|
||||
constructor(private readonly options: DefaultTasksRunnerOptions) {}
|
||||
@@ -150,42 +148,6 @@ export class Cache {
|
||||
}
|
||||
}
|
||||
|
||||
removeOutputHashesFromNxOutputs(outputs: string[]): void {
|
||||
if (outputs.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const nxOutputs = readJsonFile(this.nxOutputsPath);
|
||||
outputs.forEach((output) => {
|
||||
delete nxOutputs[output];
|
||||
});
|
||||
writeJsonFile(this.nxOutputsPath, nxOutputs);
|
||||
}
|
||||
|
||||
writeOutputHashesToNxOutputs(outputs: string[], hash: string): void {
|
||||
if (outputs.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const nxOutputs = readJsonFile(this.nxOutputsPath);
|
||||
outputs.forEach((output) => {
|
||||
nxOutputs[output] = hash;
|
||||
});
|
||||
writeJsonFile(this.nxOutputsPath, nxOutputs);
|
||||
}
|
||||
|
||||
outputsMatchTask(task: Task, outputs: string[]): boolean {
|
||||
if (outputs.length === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const nxOutputs = readJsonFile(this.nxOutputsPath);
|
||||
return outputs.every(
|
||||
(output) =>
|
||||
existsSync(join(this.root, output)) && task.hash === nxOutputs[output]
|
||||
);
|
||||
}
|
||||
|
||||
private getFromLocalDir(task: Task) {
|
||||
const tdCommit = join(this.cachePath, `${task.hash}.commit`);
|
||||
const td = join(this.cachePath, task.hash);
|
||||
@@ -213,12 +175,4 @@ export class Cache {
|
||||
fsExtra.ensureDirSync(path);
|
||||
return path;
|
||||
}
|
||||
|
||||
private ensureNxOutputsFile() {
|
||||
const path = join(this.cachePath, 'nx-outputs.json');
|
||||
if (!existsSync(path)) {
|
||||
writeJsonFile(path, {});
|
||||
}
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import * as dotenv from 'dotenv';
|
||||
import * as fs from 'fs';
|
||||
import { ProjectGraph } from '../core/project-graph';
|
||||
import { appRootPath } from '../utilities/app-root';
|
||||
import { output, TaskCacheStatus } from '../utilities/output';
|
||||
import { output } from '../utilities/output';
|
||||
import { Cache, TaskWithCachedResult } from './cache';
|
||||
import { DefaultTasksRunnerOptions } from './default-tasks-runner';
|
||||
import { AffectedEventType, Task } from './tasks-runner';
|
||||
@@ -115,28 +115,18 @@ export class TaskOrchestrator {
|
||||
tasks.forEach((t) => {
|
||||
this.options.lifeCycle.startTask(t.task);
|
||||
|
||||
const outputs = getOutputs(this.projectGraph.nodes, t.task);
|
||||
const outputsMatchCache = this.cache.outputsMatchTask(t.task, outputs);
|
||||
if (!outputsMatchCache) {
|
||||
this.cache.removeOutputHashesFromNxOutputs(outputs);
|
||||
this.cache.copyFilesFromCache(t.cachedResult, outputs);
|
||||
this.cache.writeOutputHashesToNxOutputs(outputs, t.task.hash);
|
||||
}
|
||||
|
||||
if (
|
||||
!this.initiatingProject ||
|
||||
this.initiatingProject === t.task.target.project
|
||||
) {
|
||||
const args = this.getCommandArgs(t.task);
|
||||
output.logCommand(
|
||||
`nx ${args.join(' ')}`,
|
||||
outputsMatchCache
|
||||
? TaskCacheStatus.MatchedExistingOutput
|
||||
: TaskCacheStatus.RetrievedFromCache
|
||||
);
|
||||
output.logCommand(`nx ${args.join(' ')}`, true);
|
||||
process.stdout.write(t.cachedResult.terminalOutput);
|
||||
}
|
||||
|
||||
const outputs = getOutputs(this.projectGraph.nodes, t.task);
|
||||
this.cache.copyFilesFromCache(t.cachedResult, outputs);
|
||||
|
||||
this.options.lifeCycle.endTask(t.task, 0);
|
||||
});
|
||||
|
||||
@@ -185,7 +175,6 @@ export class TaskOrchestrator {
|
||||
if (forwardOutput) {
|
||||
output.logCommand(commandLine);
|
||||
}
|
||||
this.cache.removeOutputHashesFromNxOutputs(taskOutputs);
|
||||
const p = fork(this.getCommand(), args, {
|
||||
stdio: ['inherit', 'pipe', 'pipe', 'ipc'],
|
||||
env,
|
||||
@@ -221,10 +210,6 @@ export class TaskOrchestrator {
|
||||
this.cache
|
||||
.put(task, outputPath, taskOutputs)
|
||||
.then(() => {
|
||||
this.cache.writeOutputHashesToNxOutputs(
|
||||
taskOutputs,
|
||||
task.hash
|
||||
);
|
||||
this.options.lifeCycle.endTask(task, code);
|
||||
res(code);
|
||||
})
|
||||
@@ -232,12 +217,10 @@ export class TaskOrchestrator {
|
||||
rej(e);
|
||||
});
|
||||
} else {
|
||||
this.cache.writeOutputHashesToNxOutputs(taskOutputs, task.hash);
|
||||
this.options.lifeCycle.endTask(task, code);
|
||||
res(code);
|
||||
}
|
||||
} else {
|
||||
this.cache.writeOutputHashesToNxOutputs(taskOutputs, task.hash);
|
||||
this.options.lifeCycle.endTask(task, code);
|
||||
res(code);
|
||||
}
|
||||
@@ -268,7 +251,6 @@ export class TaskOrchestrator {
|
||||
if (forwardOutput) {
|
||||
output.logCommand(commandLine);
|
||||
}
|
||||
this.cache.removeOutputHashesFromNxOutputs(taskOutputs);
|
||||
const p = fork(this.getCommand(), args, {
|
||||
stdio: ['inherit', 'inherit', 'inherit', 'ipc'],
|
||||
env,
|
||||
@@ -293,7 +275,6 @@ export class TaskOrchestrator {
|
||||
this.cache
|
||||
.put(task, outputPath, taskOutputs)
|
||||
.then(() => {
|
||||
this.cache.writeOutputHashesToNxOutputs(taskOutputs, task.hash);
|
||||
this.options.lifeCycle.endTask(task, code);
|
||||
res(code);
|
||||
})
|
||||
@@ -301,7 +282,6 @@ export class TaskOrchestrator {
|
||||
rej(e);
|
||||
});
|
||||
} else {
|
||||
this.cache.writeOutputHashesToNxOutputs(taskOutputs, task.hash);
|
||||
this.options.lifeCycle.endTask(task, code);
|
||||
res(code);
|
||||
}
|
||||
|
||||
@@ -22,12 +22,6 @@ export interface CLISuccessMessageConfig {
|
||||
bodyLines?: string[];
|
||||
}
|
||||
|
||||
export enum TaskCacheStatus {
|
||||
NoCache = '[no cache]',
|
||||
MatchedExistingOutput = '[existing outputs match the cache, left as is]',
|
||||
RetrievedFromCache = '[retrieved from cache]',
|
||||
}
|
||||
|
||||
/**
|
||||
* Automatically disable styling applied by chalk if CI=true
|
||||
*/
|
||||
@@ -183,16 +177,13 @@ class CLIOutput {
|
||||
this.addNewline();
|
||||
}
|
||||
|
||||
logCommand(
|
||||
message: string,
|
||||
cacheStatus: TaskCacheStatus = TaskCacheStatus.NoCache
|
||||
) {
|
||||
logCommand(message: string, isCached: boolean = false) {
|
||||
this.addNewline();
|
||||
|
||||
this.writeToStdOut(chalk.bold(`> ${message} `));
|
||||
|
||||
if (cacheStatus !== TaskCacheStatus.NoCache) {
|
||||
this.writeToStdOut(chalk.bold.grey(cacheStatus));
|
||||
if (isCached) {
|
||||
this.writeToStdOut(chalk.bold.grey(`[retrieved from cache]`));
|
||||
}
|
||||
|
||||
this.addNewline();
|
||||
|
||||
@@ -108,17 +108,6 @@
|
||||
"@angular-devkit/core" "11.2.4"
|
||||
rxjs "6.6.3"
|
||||
|
||||
"@angular-devkit/core@10.1.7":
|
||||
version "10.1.7"
|
||||
resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-10.1.7.tgz#c4c4332d738075bf1346aa040c78756e3144ba4b"
|
||||
integrity sha512-RRyDkN2FByA+nlnRx/MzUMK1FXwj7+SsrzJcvZfWx4yA5rfKmJiJryXQEzL44GL1aoaXSuvOYu3H72wxZADN8Q==
|
||||
dependencies:
|
||||
ajv "6.12.4"
|
||||
fast-json-stable-stringify "2.1.0"
|
||||
magic-string "0.25.7"
|
||||
rxjs "6.6.2"
|
||||
source-map "0.7.3"
|
||||
|
||||
"@angular-devkit/core@11.2.3":
|
||||
version "11.2.3"
|
||||
resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-11.2.3.tgz#322fb08f4e2683a37bd08edecb04ddafa42865d9"
|
||||
@@ -2301,15 +2290,6 @@
|
||||
enhanced-resolve "5.7.0"
|
||||
webpack-sources "2.2.0"
|
||||
|
||||
"@ngtools/webpack@~10.1.3":
|
||||
version "10.1.7"
|
||||
resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-10.1.7.tgz#0778473a92f49ba72a56167104dcfb26ed7cebb0"
|
||||
integrity sha512-J/ePcuUfrh0tgnZ+Em4Rv0UYb8wBHARk//K0eVr/Qk5ziWEcYyOW3w3Hz6FbxwIElXvkj+/C9GOb1SapkzlEXg==
|
||||
dependencies:
|
||||
"@angular-devkit/core" "10.1.7"
|
||||
enhanced-resolve "4.3.0"
|
||||
webpack-sources "1.4.3"
|
||||
|
||||
"@nodelib/fs.scandir@2.1.4":
|
||||
version "2.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz#d4b3549a5db5de2683e0c1071ab4f140904bbf69"
|
||||
@@ -4821,16 +4801,6 @@ ajv@6.10.2:
|
||||
json-schema-traverse "^0.4.1"
|
||||
uri-js "^4.2.2"
|
||||
|
||||
ajv@6.12.4:
|
||||
version "6.12.4"
|
||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.4.tgz#0614facc4522127fa713445c6bfd3ebd376e2234"
|
||||
integrity sha512-eienB2c9qVQs2KWexhkrdMLVDoIQCz5KSeLxwg9Lzk4DOfBtIK9PQwwufcsn1jjGuf9WZmqPMbGxOzfcuphJCQ==
|
||||
dependencies:
|
||||
fast-deep-equal "^3.1.1"
|
||||
fast-json-stable-stringify "^2.0.0"
|
||||
json-schema-traverse "^0.4.1"
|
||||
uri-js "^4.2.2"
|
||||
|
||||
ajv@6.12.6, ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5:
|
||||
version "6.12.6"
|
||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
|
||||
@@ -4989,7 +4959,7 @@ app-root-dir@^1.0.2:
|
||||
resolved "https://registry.yarnpkg.com/app-root-dir/-/app-root-dir-1.0.2.tgz#38187ec2dea7577fff033ffcb12172692ff6e118"
|
||||
integrity sha1-OBh+wt6nV3//Az/8sSFyaS/24Rg=
|
||||
|
||||
app-root-path@^2.0.1, app-root-path@^2.1.0:
|
||||
app-root-path@^2.0.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-2.2.1.tgz#d0df4a682ee408273583d43f6f79e9892624bc9a"
|
||||
integrity sha512-91IFKeKk7FjfmezPKkwtaRvSpnUc4gDwPAjA1YZ9Gn0q0PPeW+vbeUsZuyDwjI7+QTHhcLen2v25fi/AmhvbJA==
|
||||
@@ -5044,14 +5014,6 @@ argparse@~0.1.15:
|
||||
underscore "~1.7.0"
|
||||
underscore.string "~2.4.0"
|
||||
|
||||
aria-query@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-3.0.0.tgz#65b3fcc1ca1155a8c9ae64d6eee297f15d5133cc"
|
||||
integrity sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w=
|
||||
dependencies:
|
||||
ast-types-flow "0.0.7"
|
||||
commander "^2.11.0"
|
||||
|
||||
aria-query@^4.2.2:
|
||||
version "4.2.2"
|
||||
resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-4.2.2.tgz#0d2ca6c9aceb56b8977e9fed6aed7e15bbd2f83b"
|
||||
@@ -5238,7 +5200,7 @@ assign-symbols@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367"
|
||||
integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=
|
||||
|
||||
ast-types-flow@0.0.7, ast-types-flow@^0.0.7:
|
||||
ast-types-flow@^0.0.7:
|
||||
version "0.0.7"
|
||||
resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad"
|
||||
integrity sha1-9wtzXGvKGlycItmCw+Oef+ujva0=
|
||||
@@ -5380,7 +5342,7 @@ axios@0.21.1, axios@^0.21.1:
|
||||
dependencies:
|
||||
follow-redirects "^1.10.0"
|
||||
|
||||
axobject-query@^2.0.2, axobject-query@^2.2.0:
|
||||
axobject-query@^2.2.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be"
|
||||
integrity sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==
|
||||
@@ -7475,21 +7437,6 @@ code-point-at@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
|
||||
integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
|
||||
|
||||
codelyzer@~5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/codelyzer/-/codelyzer-5.0.1.tgz#c52a593368269b791594603968eb82cbecae3cda"
|
||||
integrity sha512-UVV76+/y1RwaxzCeGPFE3G4GFtfV42r3x8EmRd7XMNFLlLC0ewdtCqWTbvhwPQMxFZZ+OTLEOJNWfyPPn3QFWg==
|
||||
dependencies:
|
||||
app-root-path "^2.1.0"
|
||||
aria-query "^3.0.0"
|
||||
axobject-query "^2.0.2"
|
||||
css-selector-tokenizer "^0.7.1"
|
||||
cssauron "^1.4.0"
|
||||
damerau-levenshtein "^1.0.4"
|
||||
semver-dsl "^1.0.1"
|
||||
source-map "^0.5.7"
|
||||
sprintf-js "^1.1.2"
|
||||
|
||||
coffeescript@1.12.7:
|
||||
version "1.12.7"
|
||||
resolved "https://registry.yarnpkg.com/coffeescript/-/coffeescript-1.12.7.tgz#e57ee4c4867cf7f606bfc4a0f2d550c0981ddd27"
|
||||
@@ -7590,7 +7537,7 @@ commander@7.1.0, commander@^7.0.0:
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-7.1.0.tgz#f2eaecf131f10e36e07d894698226e36ae0eb5ff"
|
||||
integrity sha512-pRxBna3MJe6HKnBGsDyMv8ETbptw3axEdYHoqNh7gu5oDcew8fs0xnivZGm06Ogk8zGAJ9VX+OPEr2GXEQK4dg==
|
||||
|
||||
commander@^2.11.0, commander@^2.12.1, commander@^2.19.0, commander@^2.20.0:
|
||||
commander@^2.12.1, commander@^2.19.0, commander@^2.20.0:
|
||||
version "2.20.3"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
|
||||
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
|
||||
@@ -8505,14 +8452,6 @@ css-select@^2.0.0, css-select@^2.0.2:
|
||||
domutils "^1.7.0"
|
||||
nth-check "^1.0.2"
|
||||
|
||||
css-selector-tokenizer@^0.7.1:
|
||||
version "0.7.3"
|
||||
resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.7.3.tgz#735f26186e67c749aaf275783405cf0661fae8f1"
|
||||
integrity sha512-jWQv3oCEL5kMErj4wRnK/OPoBi0D+P1FR2cDCKYPaMeD2eW3/mttav8HT4hT1CKopiJI/psEULjkClhvJo4Lvg==
|
||||
dependencies:
|
||||
cssesc "^3.0.0"
|
||||
fastparse "^1.1.2"
|
||||
|
||||
css-to-react-native@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/css-to-react-native/-/css-to-react-native-3.0.0.tgz#62dbe678072a824a689bcfee011fc96e02a7d756"
|
||||
@@ -8572,13 +8511,6 @@ css@^3.0.0:
|
||||
source-map "^0.6.1"
|
||||
source-map-resolve "^0.6.0"
|
||||
|
||||
cssauron@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/cssauron/-/cssauron-1.4.0.tgz#a6602dff7e04a8306dc0db9a551e92e8b5662ad8"
|
||||
integrity sha1-pmAt/34EqDBtwNuaVR6S6LVmKtg=
|
||||
dependencies:
|
||||
through X.X.X
|
||||
|
||||
cssesc@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
|
||||
@@ -8853,7 +8785,7 @@ dagre@^0.8.5:
|
||||
graphlib "^2.1.8"
|
||||
lodash "^4.17.15"
|
||||
|
||||
damerau-levenshtein@^1.0.4, damerau-levenshtein@^1.0.6:
|
||||
damerau-levenshtein@^1.0.6:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz#143c1641cb3d85c60c32329e26899adea8701791"
|
||||
integrity sha512-JVrozIeElnj3QzfUIt8tB8YMluBJom4Vw9qTPpjGYQ9fYlB3D/rb6OordUxf3xeFB35LKWs0xqcO5U6ySvBtug==
|
||||
@@ -9772,15 +9704,6 @@ engine.io@~3.2.0:
|
||||
engine.io-parser "~2.1.0"
|
||||
ws "~3.3.1"
|
||||
|
||||
enhanced-resolve@4.3.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.3.0.tgz#3b806f3bfafc1ec7de69551ef93cca46c1704126"
|
||||
integrity sha512-3e87LvavsdxyoCfGusJnrZ5G8SLPOFeHSNpZI/ATL9a5leXo2k0w6MKnbqhdBad9qTobSfB20Ld7UmgoNbAZkQ==
|
||||
dependencies:
|
||||
graceful-fs "^4.1.2"
|
||||
memory-fs "^0.5.0"
|
||||
tapable "^1.0.0"
|
||||
|
||||
enhanced-resolve@5.7.0:
|
||||
version "5.7.0"
|
||||
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.7.0.tgz#525c5d856680fbd5052de453ac83e32049958b5c"
|
||||
@@ -10547,11 +10470,6 @@ fast-safe-stringify@2.0.7:
|
||||
resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz#124aa885899261f68aedb42a7c080de9da608743"
|
||||
integrity sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==
|
||||
|
||||
fastparse@^1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.2.tgz#91728c5a5942eced8531283c79441ee4122c35a9"
|
||||
integrity sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==
|
||||
|
||||
fastq@^1.6.0:
|
||||
version "1.11.0"
|
||||
resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.11.0.tgz#bb9fb955a07130a918eb63c1f5161cc32a5d0858"
|
||||
@@ -19166,13 +19084,6 @@ rxjs@6.5.5:
|
||||
dependencies:
|
||||
tslib "^1.9.0"
|
||||
|
||||
rxjs@6.6.2:
|
||||
version "6.6.2"
|
||||
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.2.tgz#8096a7ac03f2cc4fe5860ef6e572810d9e01c0d2"
|
||||
integrity sha512-BHdBMVoWC2sL26w//BCu3YzKT4s2jip/WhwsGEDmeKYBhKDZeYezVUnHatYB7L85v5xs0BAQmg6BEYJEKxBabg==
|
||||
dependencies:
|
||||
tslib "^1.9.0"
|
||||
|
||||
rxjs@6.6.3, rxjs@^6.5.0:
|
||||
version "6.6.3"
|
||||
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.3.tgz#8ca84635c4daa900c0d3967a6ee7ac60271ee552"
|
||||
@@ -19416,13 +19327,6 @@ semver-diff@^2.0.0:
|
||||
dependencies:
|
||||
semver "^5.0.3"
|
||||
|
||||
semver-dsl@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/semver-dsl/-/semver-dsl-1.0.1.tgz#d3678de5555e8a61f629eed025366ae5f27340a0"
|
||||
integrity sha1-02eN5VVeimH2Ke7QJTZq5fJzQKA=
|
||||
dependencies:
|
||||
semver "^5.3.0"
|
||||
|
||||
semver-intersect@1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/semver-intersect/-/semver-intersect-1.4.0.tgz#bdd9c06bedcdd2fedb8cd352c3c43ee8c61321f3"
|
||||
@@ -20059,11 +19963,6 @@ split@^1.0.0:
|
||||
dependencies:
|
||||
through "2"
|
||||
|
||||
sprintf-js@^1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673"
|
||||
integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==
|
||||
|
||||
sprintf-js@~1.0.2:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
|
||||
@@ -20954,7 +20853,7 @@ through2@^4.0.0:
|
||||
dependencies:
|
||||
readable-stream "3"
|
||||
|
||||
through@2, "through@>=2.2.7 <3", through@X.X.X, through@^2.3.6:
|
||||
through@2, "through@>=2.2.7 <3", through@^2.3.6:
|
||||
version "2.3.8"
|
||||
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
|
||||
integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=
|
||||
@@ -21305,11 +21204,6 @@ tsconfig-paths@^3.4.0, tsconfig-paths@^3.9.0:
|
||||
minimist "^1.2.0"
|
||||
strip-bom "^3.0.0"
|
||||
|
||||
tsickle@^0.38.1:
|
||||
version "0.38.1"
|
||||
resolved "https://registry.yarnpkg.com/tsickle/-/tsickle-0.38.1.tgz#30762db759d40c435943093b6972c7f2efb384ef"
|
||||
integrity sha512-4xZfvC6+etRu6ivKCNqMOd1FqcY/m6JY3Y+yr5+Xw+i751ciwrWINi6x/3l1ekcODH9GZhlf0ny2LpzWxnjWYA==
|
||||
|
||||
tslib@2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.1.tgz#410eb0d113e5b6356490eec749603725b021b43e"
|
||||
|
||||
Reference in New Issue
Block a user