-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(schematics): add lint checks ensuring the integrity of the works…
…pace
- Loading branch information
Showing
15 changed files
with
293 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { updateJsonFile } from '@nrwl/schematics/src/utils/fileutils'; | ||
|
||
export default { | ||
description: 'Run lint checks ensuring the integrity of the workspace', | ||
run: () => { | ||
updateJsonFile('package.json', json => { | ||
json.scripts = { | ||
...json.scripts, | ||
lint: './node_modules/.bin/nx lint && ng lint' | ||
}; | ||
}); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { getProjectNodes, readCliConfig, allFilesInDir } from './shared'; | ||
import { WorkspaceIntegrityCheck } from './workspace-integrity-checks'; | ||
import * as appRoot from 'app-root-path'; | ||
import * as path from 'path'; | ||
import * as fs from 'fs'; | ||
|
||
export function lint() { | ||
const nodes = getProjectNodes(readCliConfig()); | ||
const packageJson = JSON.parse( | ||
fs.readFileSync(`${appRoot.path}/package.json`, 'utf-8') | ||
); | ||
|
||
const errorGroups = new WorkspaceIntegrityCheck( | ||
nodes, | ||
readAllFilesFromAppsAndLibs(), | ||
packageJson | ||
).run(); | ||
if (errorGroups.length > 0) { | ||
errorGroups.forEach(g => { | ||
console.error(`${g.header}:`); | ||
g.errors.forEach(e => console.error(e)); | ||
console.log(''); | ||
}); | ||
process.exit(1); | ||
} | ||
} | ||
|
||
function readAllFilesFromAppsAndLibs() { | ||
return [ | ||
...allFilesInDir(`${appRoot.path}/apps`), | ||
...allFilesInDir(`${appRoot.path}/libs`) | ||
].filter(f => !path.basename(f).startsWith('.')); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
106 changes: 106 additions & 0 deletions
106
packages/schematics/src/command-line/workspace-integrity-checks.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
import { WorkspaceIntegrityCheck } from './workspace-integrity-checks'; | ||
import { ProjectType } from './affected-apps'; | ||
|
||
describe('WorkspaceIntegrityCheck', () => { | ||
const packageJson = { | ||
dependencies: { | ||
'@nrwl/nx': '1.2.3' | ||
}, | ||
devDependencies: { | ||
'@nrwl/schematics': '1.2.3' | ||
} | ||
}; | ||
|
||
describe('.angular-cli.json is in sync with the filesystem', () => { | ||
it('should not error when they are in sync', () => { | ||
const c = new WorkspaceIntegrityCheck( | ||
[ | ||
{ | ||
name: 'project1', | ||
type: ProjectType.lib, | ||
root: 'libs/project1/src', | ||
tags: [], | ||
files: ['libs/project1/index.ts'] | ||
} | ||
], | ||
['libs/project1/index.ts'], | ||
packageJson | ||
); | ||
expect(c.run().length).toEqual(0); | ||
}); | ||
|
||
it('should error when there are projects without files', () => { | ||
const c = new WorkspaceIntegrityCheck( | ||
[ | ||
{ | ||
name: 'project1', | ||
type: ProjectType.lib, | ||
root: 'libs/project1/src', | ||
tags: [], | ||
files: [] | ||
}, | ||
{ | ||
name: 'project2', | ||
type: ProjectType.lib, | ||
root: 'libs/project2/src', | ||
tags: [], | ||
files: ['libs/project2/index.ts'] | ||
} | ||
], | ||
['libs/project2/index.ts'], | ||
packageJson | ||
); | ||
|
||
const errors = c.run(); | ||
expect(errors.length).toEqual(1); | ||
expect(errors[0].errors[0]).toEqual( | ||
`Cannot find project 'project1' in 'libs/project1'` | ||
); | ||
}); | ||
|
||
it('should error when there are files in apps or libs without projects', () => { | ||
const c = new WorkspaceIntegrityCheck( | ||
[ | ||
{ | ||
name: 'project1', | ||
type: ProjectType.lib, | ||
root: 'libs/project1/src', | ||
tags: [], | ||
files: ['libs/project1/index.ts'] | ||
} | ||
], | ||
['libs/project1/index.ts', 'libs/project2/index.ts'], | ||
packageJson | ||
); | ||
|
||
const errors = c.run(); | ||
expect(errors.length).toEqual(1); | ||
expect(errors[0].errors[0]).toEqual( | ||
`The 'libs/project2/index.ts' file doesn't belong to any project.` | ||
); | ||
}); | ||
}); | ||
|
||
describe('package.json is consistent', () => { | ||
it('should not error when @nrwl/nx and @nrwl/schematics are in sync', () => { | ||
const c = new WorkspaceIntegrityCheck([], [], packageJson); | ||
expect(c.run().length).toEqual(0); | ||
}); | ||
|
||
it('should error when @nrwl/nx and @nrwl/schematics are not in sync', () => { | ||
const c = new WorkspaceIntegrityCheck([], [], { | ||
dependencies: { | ||
'@nrwl/nx': '1.2.3' | ||
}, | ||
devDependencies: { | ||
'@nrwl/schematics': '4.5.6' | ||
} | ||
}); | ||
const errors = c.run(); | ||
expect(errors.length).toEqual(1); | ||
expect(errors[0].errors[0]).toEqual( | ||
`The versions of the @nrwl/nx and @nrwl/schematics packages must be the same.` | ||
); | ||
}); | ||
}); | ||
}); |
80 changes: 80 additions & 0 deletions
80
packages/schematics/src/command-line/workspace-integrity-checks.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import { ProjectNode } from './affected-apps'; | ||
import * as path from 'path'; | ||
|
||
export interface ErrorGroup { | ||
header: string; | ||
errors: string[]; | ||
} | ||
|
||
export class WorkspaceIntegrityCheck { | ||
constructor( | ||
private projectNodes: ProjectNode[], | ||
private files: string[], | ||
private packageJson: any | ||
) {} | ||
|
||
run(): ErrorGroup[] { | ||
return [ | ||
...this.packageJsonConsistencyCheck(), | ||
...this.projectWithoutFilesCheck(), | ||
...this.filesWithoutProjects() | ||
]; | ||
} | ||
|
||
private packageJsonConsistencyCheck(): ErrorGroup[] { | ||
const nx = this.packageJson.dependencies['@nrwl/nx']; | ||
const schematics = this.packageJson.devDependencies['@nrwl/schematics']; | ||
if (nx !== schematics) { | ||
return [ | ||
{ | ||
header: 'The package.json is inconsistent', | ||
errors: [ | ||
'The versions of the @nrwl/nx and @nrwl/schematics packages must be the same.' | ||
] | ||
} | ||
]; | ||
} else { | ||
return []; | ||
} | ||
} | ||
|
||
private projectWithoutFilesCheck(): ErrorGroup[] { | ||
const errors = this.projectNodes | ||
.filter(n => n.files.length === 0) | ||
.map(p => `Cannot find project '${p.name}' in '${path.dirname(p.root)}'`); | ||
|
||
return errors.length === 0 | ||
? [] | ||
: [{ header: 'The .angular-cli.json file is out of sync', errors }]; | ||
} | ||
|
||
private filesWithoutProjects(): ErrorGroup[] { | ||
const allFilesFromProjects = this.allProjectFiles(); | ||
const allFilesWithoutProjects = minus(this.files, allFilesFromProjects); | ||
const first5FilesWithoutProjects = | ||
allFilesWithoutProjects.length > 5 | ||
? allFilesWithoutProjects.slice(0, 5) | ||
: allFilesWithoutProjects; | ||
|
||
const errors = first5FilesWithoutProjects.map( | ||
p => `The '${p}' file doesn't belong to any project.` | ||
); | ||
|
||
return errors.length === 0 | ||
? [] | ||
: [ | ||
{ | ||
header: `All files in 'apps' and 'libs' must be part of a project.`, | ||
errors | ||
} | ||
]; | ||
} | ||
|
||
private allProjectFiles() { | ||
return this.projectNodes.reduce((m, c) => [...m, ...c.files], []); | ||
} | ||
} | ||
|
||
function minus(a: string[], b: string[]): string[] { | ||
return a.filter(aa => b.indexOf(aa) === -1); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.