-
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(core): analyze changes to nx.json and workspace.json (#2338)
- Loading branch information
1 parent
616fbd6
commit b30930f
Showing
7 changed files
with
566 additions
and
1 deletion.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import { | ||
ensureProject, | ||
readJson, | ||
runCommand, | ||
uniq, | ||
updateFile, | ||
runCLI, | ||
forEachCli, | ||
workspaceConfigName | ||
} from './utils'; | ||
import { NxJson } from '@nrwl/workspace/src/core/shared-interfaces'; | ||
|
||
forEachCli(() => { | ||
describe('Affected (with Git)', () => { | ||
let myapp = uniq('myapp'); | ||
let myapp2 = uniq('myapp'); | ||
let mylib = uniq('mylib'); | ||
it('should not affect other projects by generating a new project', () => { | ||
ensureProject(); | ||
|
||
const nxJson: NxJson = readJson('nx.json'); | ||
|
||
delete nxJson.implicitDependencies; | ||
|
||
updateFile('nx.json', JSON.stringify(nxJson)); | ||
runCommand(`git init`); | ||
runCommand(`git config user.email "test@test.com"`); | ||
runCommand(`git config user.name "Test"`); | ||
runCommand( | ||
`git add . && git commit -am "initial commit" && git checkout -b master` | ||
); | ||
runCLI(`generate @nrwl/angular:app ${myapp}`); | ||
expect(runCommand('yarn affected:apps')).toContain(myapp); | ||
runCommand(`git add . && git commit -am "add ${myapp}"`); | ||
|
||
runCLI(`generate @nrwl/angular:app ${myapp2}`); | ||
expect(runCommand('yarn affected:apps')).not.toContain(myapp); | ||
expect(runCommand('yarn affected:apps')).toContain(myapp2); | ||
runCommand(`git add . && git commit -am "add ${myapp2}"`); | ||
|
||
runCLI(`generate @nrwl/angular:lib ${mylib}`); | ||
expect(runCommand('yarn affected:apps')).not.toContain(myapp); | ||
expect(runCommand('yarn affected:apps')).not.toContain(myapp2); | ||
expect(runCommand('yarn affected:libs')).toContain(mylib); | ||
runCommand(`git add . && git commit -am "add ${mylib}"`); | ||
}, 1000000); | ||
|
||
it('should detect changes to projects based on the nx.json', () => { | ||
const nxJson: NxJson = readJson('nx.json'); | ||
|
||
nxJson.projects[myapp].tags = ['tag']; | ||
updateFile('nx.json', JSON.stringify(nxJson)); | ||
expect(runCommand('yarn affected:apps')).toContain(myapp); | ||
expect(runCommand('yarn affected:apps')).not.toContain(myapp2); | ||
expect(runCommand('yarn affected:libs')).not.toContain(mylib); | ||
runCommand(`git add . && git commit -am "add tag to ${myapp}"`); | ||
}); | ||
|
||
it('should detect changes to projects based on the workspace.json', () => { | ||
const workspaceJson = readJson(workspaceConfigName()); | ||
|
||
workspaceJson.projects[myapp].prefix = 'my-app'; | ||
updateFile(workspaceConfigName(), JSON.stringify(workspaceJson)); | ||
expect(runCommand('yarn affected:apps')).toContain(myapp); | ||
expect(runCommand('yarn affected:apps')).not.toContain(myapp2); | ||
expect(runCommand('yarn affected:libs')).not.toContain(mylib); | ||
runCommand(`git add . && git commit -am "change prefix for ${myapp}"`); | ||
}); | ||
|
||
it('should affect all projects by removing projects', () => { | ||
const workspaceJson = readJson(workspaceConfigName()); | ||
delete workspaceJson.projects[mylib]; | ||
updateFile(workspaceConfigName(), JSON.stringify(workspaceJson)); | ||
|
||
const nxJson = readJson('nx.json'); | ||
delete nxJson.projects[mylib]; | ||
updateFile('nx.json', JSON.stringify(nxJson)); | ||
|
||
expect(runCommand('yarn affected:apps')).toContain(myapp); | ||
expect(runCommand('yarn affected:apps')).toContain(myapp2); | ||
expect(runCommand('yarn affected:libs')).not.toContain(mylib); | ||
runCommand(`git add . && git commit -am "remove ${mylib}"`); | ||
}); | ||
}); | ||
}); |
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
194 changes: 194 additions & 0 deletions
194
packages/workspace/src/core/affected-project-graph/locators/nx-json-changes.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,194 @@ | ||
import { getTouchedProjectsInNxJson } from './nx-json-changes'; | ||
import { WholeFileChange } from '../../file-utils'; | ||
import { DiffType } from '../../../utils/json-diff'; | ||
|
||
describe('getTouchedProjectsInNxJson', () => { | ||
it('should not return changes when nx.json is not touched', () => { | ||
const result = getTouchedProjectsInNxJson( | ||
[ | ||
{ | ||
file: 'source.ts', | ||
ext: '.ts', | ||
mtime: 0, | ||
getChanges: () => [new WholeFileChange()] | ||
} | ||
], | ||
{}, | ||
{ | ||
npmScope: 'proj', | ||
projects: { | ||
proj1: { | ||
tags: [] | ||
} | ||
} | ||
} | ||
); | ||
expect(result).toEqual([]); | ||
}); | ||
|
||
it('should return all projects for a whole file change', () => { | ||
const result = getTouchedProjectsInNxJson( | ||
[ | ||
{ | ||
file: 'nx.json', | ||
ext: '.json', | ||
mtime: 0, | ||
getChanges: () => [new WholeFileChange()] | ||
} | ||
], | ||
{}, | ||
{ | ||
npmScope: 'proj', | ||
projects: { | ||
proj1: { | ||
tags: [] | ||
}, | ||
proj2: { | ||
tags: [] | ||
} | ||
} | ||
} | ||
); | ||
expect(result).toEqual(['proj1', 'proj2']); | ||
}); | ||
|
||
it('should return all projects for changes to npmScope', () => { | ||
const result = getTouchedProjectsInNxJson( | ||
[ | ||
{ | ||
file: 'nx.json', | ||
ext: '.json', | ||
mtime: 0, | ||
getChanges: () => [ | ||
{ | ||
type: DiffType.Modified, | ||
path: ['npmScope'], | ||
value: { | ||
lhs: 'proj', | ||
rhs: 'awesome-proj' | ||
} | ||
} | ||
] | ||
} | ||
], | ||
{}, | ||
{ | ||
npmScope: 'proj', | ||
projects: { | ||
proj1: { | ||
tags: [] | ||
}, | ||
proj2: { | ||
tags: [] | ||
} | ||
} | ||
} | ||
); | ||
expect(result).toEqual(['proj1', 'proj2']); | ||
}); | ||
|
||
it('should return projects added in nx.json', () => { | ||
const result = getTouchedProjectsInNxJson( | ||
[ | ||
{ | ||
file: 'nx.json', | ||
ext: '.json', | ||
mtime: 0, | ||
getChanges: () => [ | ||
{ | ||
type: DiffType.Added, | ||
path: ['projects', 'proj1', 'tags'], | ||
value: { | ||
lhs: undefined, | ||
rhs: [] | ||
} | ||
} | ||
] | ||
} | ||
], | ||
{}, | ||
{ | ||
npmScope: 'proj', | ||
projects: { | ||
proj1: { | ||
tags: [] | ||
}, | ||
proj2: { | ||
tags: [] | ||
} | ||
} | ||
} | ||
); | ||
expect(result).toEqual(['proj1']); | ||
}); | ||
|
||
it('should not return projects removed in nx.json', () => { | ||
const result = getTouchedProjectsInNxJson( | ||
[ | ||
{ | ||
file: 'nx.json', | ||
ext: '.json', | ||
mtime: 0, | ||
getChanges: () => [ | ||
{ | ||
type: DiffType.Deleted, | ||
path: ['projects', 'proj3', 'tags'], | ||
value: { | ||
lhs: [], | ||
rhs: undefined | ||
} | ||
} | ||
] | ||
} | ||
], | ||
{}, | ||
{ | ||
npmScope: 'proj', | ||
projects: { | ||
proj1: { | ||
tags: [] | ||
}, | ||
proj2: { | ||
tags: [] | ||
} | ||
} | ||
} | ||
); | ||
expect(result).toEqual(['proj1', 'proj2']); | ||
}); | ||
|
||
it('should return projects modified in nx.json', () => { | ||
const result = getTouchedProjectsInNxJson( | ||
[ | ||
{ | ||
file: 'nx.json', | ||
ext: '.json', | ||
mtime: 0, | ||
getChanges: () => [ | ||
{ | ||
type: DiffType.Modified, | ||
path: ['projects', 'proj1', 'tags', '0'], | ||
value: { | ||
lhs: 'scope:feat', | ||
rhs: 'scope:shared' | ||
} | ||
} | ||
] | ||
} | ||
], | ||
{}, | ||
{ | ||
npmScope: 'proj', | ||
projects: { | ||
proj1: { | ||
tags: [] | ||
}, | ||
proj2: { | ||
tags: [] | ||
} | ||
} | ||
} | ||
); | ||
expect(result).toEqual(['proj1']); | ||
}); | ||
}); |
46 changes: 46 additions & 0 deletions
46
packages/workspace/src/core/affected-project-graph/locators/nx-json-changes.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,46 @@ | ||
import { isWholeFileChange, WholeFileChange } from '../../file-utils'; | ||
import { DiffType, isJsonChange, JsonChange } from '../../../utils/json-diff'; | ||
import { TouchedProjectLocator } from '../affected-project-graph-models'; | ||
|
||
export const getTouchedProjectsInNxJson: TouchedProjectLocator< | ||
WholeFileChange | JsonChange | ||
> = (touchedFiles, workspaceJson, nxJson): string[] => { | ||
const nxJsonChange = touchedFiles.find(change => change.file === 'nx.json'); | ||
if (!nxJsonChange) { | ||
return []; | ||
} | ||
|
||
const changes = nxJsonChange.getChanges(); | ||
|
||
if ( | ||
changes.some(change => { | ||
if (isJsonChange(change)) { | ||
return change.path[0] !== 'projects'; | ||
} | ||
if (isWholeFileChange(change)) { | ||
return true; | ||
} | ||
return false; | ||
}) | ||
) { | ||
return Object.keys(nxJson.projects); | ||
} | ||
|
||
const touched = []; | ||
for (let i = 0; i < changes.length; i++) { | ||
const change = changes[i]; | ||
if (!isJsonChange(change) || change.path[0] !== 'projects') { | ||
return; | ||
} | ||
|
||
if (nxJson.projects[change.path[1]]) { | ||
touched.push(change.path[1]); | ||
} else { | ||
// The project was deleted so affect all projects | ||
touched.push(...Object.keys(nxJson.projects)); | ||
// Break out of the loop after all projects have been added. | ||
break; | ||
} | ||
} | ||
return touched; | ||
}; |
Oops, something went wrong.