Skip to content

Commit 9f9c5e8

Browse files
alsurencpojer
authored andcommitted
jest --changedSince=origin/master (#5312)
* --changedFilesToContributeTo=$BRANCH make changedFilesToContributeTo require an arg, and imply onlyChanged * rename; reorder; fix CLI.md * doc changes from review comments
1 parent 630b5c0 commit 9f9c5e8

14 files changed

Lines changed: 120 additions & 8 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
## master
22

3+
### Features
4+
* `[jest-cli]` `--changedSince`: allow selectively running tests for code
5+
changed since arbitrary revisions.
6+
([#5312](https://github.com/facebook/jest/pull/5312))
7+
38
## jest 22.1.3
49

510
### Fixes

docs/CLI.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,14 @@ If you want to inspect the cache, use `--showConfig` and look at the
108108
Runs tests related to the current changes and the changes made in the last
109109
commit. Behaves similarly to `--onlyChanged`.
110110

111+
### `--changedSince`
112+
113+
##### available in Jest **22.2.0+**
114+
115+
Runs tests related the changes since the provided branch. If the current branch
116+
has diverged from the given branch, then only changes made locally will be
117+
tested. Behaves similarly to `--onlyChanged`.
118+
111119
### `--ci`
112120

113121
When this option is provided, Jest will assume it is running in a CI

integration-tests/__tests__/jest_changed_files.test.js

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,37 @@ test('gets changed files for git', async () => {
191191
.map(filePath => path.basename(filePath))
192192
.sort(),
193193
).toEqual(['file1.txt', 'file4.txt']);
194+
195+
run(`${GIT} add file4.txt`, DIR);
196+
run(`${GIT} commit -m "test3"`, DIR);
197+
198+
({changedFiles: files} = await getChangedFilesForRoots(roots, {
199+
changedSince: 'HEAD^^',
200+
}));
201+
// Returns files from the last 2 commits
202+
expect(
203+
Array.from(files)
204+
.map(filePath => path.basename(filePath))
205+
.sort(),
206+
).toEqual(['file1.txt', 'file4.txt']);
207+
208+
run(`${GIT} checkout HEAD^^ -b feature-branch`, DIR);
209+
210+
writeFiles(DIR, {
211+
'file5.txt': 'file5',
212+
});
213+
run(`${GIT} add file5.txt`, DIR);
214+
run(`${GIT} commit -m "test5"`, DIR);
215+
216+
({changedFiles: files} = await getChangedFilesForRoots(roots, {
217+
changedSince: 'master',
218+
}));
219+
// Returns files from this branch but not ones that only exist on master
220+
expect(
221+
Array.from(files)
222+
.map(filePath => path.basename(filePath))
223+
.sort(),
224+
).toEqual(['file5.txt']);
194225
});
195226

196227
test('gets changed files for hg', async () => {
@@ -261,4 +292,37 @@ test('gets changed files for hg', async () => {
261292
.map(filePath => path.basename(filePath))
262293
.sort(),
263294
).toEqual(['file1.txt', 'file4.txt']);
295+
296+
run(`${HG} add file4.txt`, DIR);
297+
run(`${HG} commit -m "test3"`, DIR);
298+
299+
({changedFiles: files} = await getChangedFilesForRoots(roots, {
300+
changedSince: '-3',
301+
}));
302+
// Returns files from the last 2 commits
303+
expect(
304+
Array.from(files)
305+
.map(filePath => path.basename(filePath))
306+
.sort(),
307+
).toEqual(['file1.txt', 'file4.txt']);
308+
309+
run(`${HG} bookmark master`, DIR);
310+
// Back up and develop on a different branch
311+
run(`${HG} checkout --rev=-2`, DIR);
312+
313+
writeFiles(DIR, {
314+
'file5.txt': 'file5',
315+
});
316+
run(`${HG} add file5.txt`, DIR);
317+
run(`${HG} commit -m "test4"`, DIR);
318+
319+
({changedFiles: files} = await getChangedFilesForRoots(roots, {
320+
changedSince: 'master',
321+
}));
322+
// Returns files from this branch but not ones that only exist on master
323+
expect(
324+
Array.from(files)
325+
.map(filePath => path.basename(filePath))
326+
.sort(),
327+
).toEqual(['file5.txt']);
264328
});

packages/jest-changed-files/src/git.js

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ import type {Options, SCMAdapter} from 'types/ChangedFiles';
1313
import path from 'path';
1414
import childProcess from 'child_process';
1515

16-
const findChangedFilesUsingCommand = async (args, cwd) => {
16+
const findChangedFilesUsingCommand = async (
17+
args: Array<string>,
18+
cwd: Path,
19+
): Promise<Array<Path>> => {
1720
return new Promise((resolve, reject) => {
1821
const child = childProcess.spawn('git', args, {cwd});
1922
let stdout = '';
@@ -30,6 +33,7 @@ const findChangedFilesUsingCommand = async (args, cwd) => {
3033
resolve(
3134
stdout
3235
.split('\n')
36+
.filter(s => s !== '')
3337
.map(changedPath => path.resolve(cwd, changedPath)),
3438
);
3539
}
@@ -45,21 +49,28 @@ const adapter: SCMAdapter = {
4549
cwd: string,
4650
options?: Options,
4751
): Promise<Array<Path>> => {
52+
const changedSince: ?string =
53+
options && (options.withAncestor ? 'HEAD^' : options.changedSince);
54+
4855
if (options && options.lastCommit) {
4956
return await findChangedFilesUsingCommand(
5057
['show', '--name-only', '--pretty=%b', 'HEAD'],
5158
cwd,
5259
);
53-
} else if (options && options.withAncestor) {
54-
const changed = await findChangedFilesUsingCommand(
55-
['diff', '--name-only', 'HEAD^'],
60+
} else if (changedSince) {
61+
const committed = await findChangedFilesUsingCommand(
62+
['log', '--name-only', '--pretty=%b', 'HEAD', `^${changedSince}`],
63+
cwd,
64+
);
65+
const staged = await findChangedFilesUsingCommand(
66+
['diff', '--cached', '--name-only'],
5667
cwd,
5768
);
58-
const untracked = await findChangedFilesUsingCommand(
59-
['ls-files', '--other', '--exclude-standard'],
69+
const unstaged = await findChangedFilesUsingCommand(
70+
['ls-files', '--other', '--modified', '--exclude-standard'],
6071
cwd,
6172
);
62-
return changed.concat(untracked);
73+
return [...committed, ...staged, ...unstaged];
6374
} else {
6475
return await findChangedFilesUsingCommand(
6576
['ls-files', '--other', '--modified', '--exclude-standard'],

packages/jest-changed-files/src/hg.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ const adapter: SCMAdapter = {
2626
let args = ['status', '-amnu'];
2727
if (options && options.withAncestor) {
2828
args.push('--rev', 'ancestor(.^)');
29+
} else if (options && options.changedSince) {
30+
args.push('--rev', `ancestor(., ${options.changedSince})`);
2931
} else if (options && options.lastCommit === true) {
3032
args = ['tip', '--template', '{files%"{file}\n"}'];
3133
}

packages/jest-cli/src/cli/args.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,12 @@ export const check = (argv: Argv) => {
2020
);
2121
}
2222

23-
for (const key of ['onlyChanged', 'lastCommit', 'changedFilesWithAncestor']) {
23+
for (const key of [
24+
'onlyChanged',
25+
'lastCommit',
26+
'changedFilesWithAncestor',
27+
'changedSince',
28+
]) {
2429
if (argv[key]) {
2530
argv.onlyChanged = true;
2631
}
@@ -113,6 +118,14 @@ export const options = {
113118
'last commit. Behaves similarly to `--onlyChanged`.',
114119
type: 'boolean',
115120
},
121+
changedSince: {
122+
description:
123+
'Runs tests related the changes since the provided branch. If the ' +
124+
'current branch has diverged from the given branch, then only changes ' +
125+
'made locally will be tested. Behaves similarly to `--onlyChanged`.',
126+
nargs: 1,
127+
type: 'string',
128+
},
116129
ci: {
117130
default: isCI,
118131
description:

packages/jest-cli/src/get_changed_files_promise.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export default (
2121
[],
2222
);
2323
return getChangedFilesForRoots(allRootsForAllProjects, {
24+
changedSince: globalConfig.changedSince,
2425
lastCommit: globalConfig.lastCommit,
2526
withAncestor: globalConfig.changedFilesWithAncestor,
2627
});

packages/jest-config/src/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ const getConfigs = (
9494
globalConfig: Object.freeze({
9595
bail: options.bail,
9696
changedFilesWithAncestor: options.changedFilesWithAncestor,
97+
changedSince: options.changedSince,
9798
collectCoverage: options.collectCoverage,
9899
collectCoverageFrom: options.collectCoverageFrom,
99100
collectCoverageOnlyFrom: options.collectCoverageOnlyFrom,

packages/jest-config/src/normalize.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,7 @@ export default function normalize(options: InitialOptions, argv: Argv) {
461461
case 'bail':
462462
case 'browser':
463463
case 'cache':
464+
case 'changedSince':
464465
case 'changedFilesWithAncestor':
465466
case 'clearMocks':
466467
case 'collectCoverage':

packages/jest-config/src/valid_config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export default ({
2121
cache: true,
2222
cacheDirectory: '/tmp/user/jest',
2323
changedFilesWithAncestor: false,
24+
changedSince: '',
2425
clearMocks: false,
2526
collectCoverage: true,
2627
collectCoverageFrom: ['src', '!public'],

0 commit comments

Comments
 (0)