Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
fix(cache): adds project's dep versions to cache key
Includes the real version of each dependency of the containing project
in the cache key digest calculation.

Closes #785
  • Loading branch information
huafu committed Oct 6, 2018
1 parent 7b2dd01 commit 6cacbea
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 5 deletions.
49 changes: 46 additions & 3 deletions src/config/config-set.spec.ts
Expand Up @@ -489,23 +489,63 @@ describe('babelJestTransformer', () => {
})
}) // babelJestTransformer

describe('projectDependencies', () => {
const pkg = {
optionalDependencies: { opt: '1.2.3' },
peerDependencies: { peer: '1.2.4' },
devDependencies: { dev: '1.2.5' },
dependencies: { std: '1.2.6' },
}
const realVersions: any = {
peer: '0.1.0',
dev: '4.3.2',
std: '9.10.2',
}
it('should list all deps with their real version', () => {
jest.doMock('peer/package.json', () => ({ version: realVersions.peer }), { virtual: true })
jest.doMock('dev/package.json', () => ({ version: realVersions.dev }), { virtual: true })
jest.doMock('std/package.json', () => ({ version: realVersions.std }), { virtual: true })
const cs = createConfigSet({
tsJestConfig: { tsConfig: false } as any,
projectPackageJson: pkg,
})
expect(cs.projectDependencies).toEqual(realVersions)
jest.dontMock('peer/package.json')
jest.dontMock('dev/package.json')
jest.dontMock('std/package.json')
})
}) // projectDependencies

describe('cacheKey', () => {
it('should be a string', () => {
const cs = createConfigSet({ tsJestConfig: { tsConfig: false } as any })
const cs = createConfigSet({
tsJestConfig: { tsConfig: false } as any,
projectDependencies: {
opt: '1.2.3',
peer: '1.2.4',
dev: '1.2.5',
std: '1.2.6',
},
})
// we tested those and don't want the snapshot to change all the time we upgrade
const val = cs.jsonValue.value
delete val.versions
cs.jsonValue.value = val
// digest is mocked in src/__mocks__/index.ts
expect(cs.cacheKey).toMatchInlineSnapshot(
`"{\\"digest\\":\\"a0d51ca854194df8191d0e65c0ca4730f510f332\\",\\"jest\\":{\\"__backported\\":true,\\"globals\\":{}},\\"transformers\\":[\\"hoisting-jest-mock@1\\"],\\"tsJest\\":{\\"compiler\\":\\"typescript\\",\\"diagnostics\\":{\\"ignoreCodes\\":[6059,18002,18003],\\"pretty\\":true,\\"throws\\":true},\\"isolatedModules\\":false,\\"transformers\\":[]},\\"tsconfig\\":{\\"declaration\\":false,\\"inlineSourceMap\\":false,\\"inlineSources\\":true,\\"module\\":1,\\"noEmit\\":false,\\"outDir\\":\\"$$ts-jest$$\\",\\"removeComments\\":false,\\"sourceMap\\":true,\\"target\\":1}}"`,
'"{\\"digest\\":\\"a0d51ca854194df8191d0e65c0ca4730f510f332\\",\\"jest\\":{\\"__backported\\":true,\\"globals\\":{}},\\"projectDepVersions\\":{\\"dev\\":\\"1.2.5\\",\\"opt\\":\\"1.2.3\\",\\"peer\\":\\"1.2.4\\",\\"std\\":\\"1.2.6\\"},\\"transformers\\":[\\"hoisting-jest-mock@1\\"],\\"tsJest\\":{\\"compiler\\":\\"typescript\\",\\"diagnostics\\":{\\"ignoreCodes\\":[6059,18002,18003],\\"pretty\\":true,\\"throws\\":true},\\"isolatedModules\\":false,\\"transformers\\":[]},\\"tsconfig\\":{\\"declaration\\":false,\\"inlineSourceMap\\":false,\\"inlineSources\\":true,\\"module\\":1,\\"noEmit\\":false,\\"outDir\\":\\"$$ts-jest$$\\",\\"removeComments\\":false,\\"sourceMap\\":true,\\"target\\":1}}"',
)
})
}) // cacheKey

describe('jsonValue', () => {
it('should create jsonValue based on each config and version', () => {
const cs = createConfigSet({ tsJestConfig: { tsConfig: false } as any })
const cs = createConfigSet({
tsJestConfig: { tsConfig: false } as any,
projectDependencies: {
'some-module': '1.2.3',
},
})
const val = cs.jsonValue.valueOf()
expect(cs.toJSON()).toEqual(val)
// it will change each time we upgrade – we tested those in the `version` block
Expand All @@ -521,6 +561,9 @@ Object {
"__backported": true,
"globals": Object {},
},
"projectDepVersions": Object {
"some-module": "1.2.3",
},
"transformers": Array [
"hoisting-jest-mock@1",
],
Expand Down
42 changes: 40 additions & 2 deletions src/config/config-set.ts
Expand Up @@ -9,7 +9,7 @@
* with the complete, object version of it.
*/
import { LogContexts, Logger } from 'bs-logger'
import { existsSync, readFileSync } from 'fs'
import { existsSync, readFileSync, realpathSync } from 'fs'
import json5 from 'json5'
import { dirname, isAbsolute, join, normalize, resolve } from 'path'
import semver from 'semver'
Expand Down Expand Up @@ -112,6 +112,41 @@ const toDiagnosticCodeList = (items: any, into: number[] = []): number[] => {
}

export class ConfigSet {
@Memoize()
get projectPackageJson(): Record<string, any> {
const tsJestRoot = resolve(__dirname, '..', '..')
let pkgPath = resolve(tsJestRoot, '..', '..', 'package.json')
let exists = existsSync(pkgPath)
if (!exists) {
if (realpathSync(this.rootDir) === realpathSync(tsJestRoot)) {
pkgPath = resolve(tsJestRoot, 'package.json')
exists = true
} else {
this.logger.warn(Errors.UnableToFindProjectRoot)
}
}
return exists ? require(pkgPath) : {}
}

@Memoize()
get projectDependencies(): Record<string, string> {
const { projectPackageJson: pkg } = this
const names = Object.keys({
...pkg.optionalDependencies,
...pkg.peerDependencies,
...pkg.devDependencies,
...pkg.dependencies,
})
return names.reduce(
(map, name) => {
const version = getPackageVersion(name)
if (version) map[name] = version
return map
},
{} as Record<string, string>,
)
}

@Memoize()
get jest(): jest.ProjectConfig {
const config = backportJestConfig(this.logger, this._jestConfig)
Expand Down Expand Up @@ -440,14 +475,16 @@ export class ConfigSet {
const cacheSuffix = sha1(
stringify({
version: this.compilerModule.version,
digest: this.tsJestDigest,
dependencies: this.projectDependencies,
compiler: this.tsJest.compiler,
compilerOptions: this.typescript.options,
isolatedModules: this.tsJest.isolatedModules,
diagnostics: this.tsJest.diagnostics,
}),
)
const res = join(this.jest.cacheDirectory, 'ts-jest', cacheSuffix.substr(0, 2), cacheSuffix.substr(2))
logger.debug({ cacheDirectory: res }, `will use file caching`)
logger.debug({ cacheDirectory: res }, 'will use file caching')
return res
}

Expand Down Expand Up @@ -519,6 +556,7 @@ export class ConfigSet {

return new JsonableValue({
versions: this.versions,
projectDepVersions: this.projectDependencies,
digest: this.tsJestDigest,
transformers: this.astTransformers.map(t => `${t.name}@${t.version}`),
jest,
Expand Down
1 change: 1 addition & 0 deletions src/util/messages.ts
Expand Up @@ -21,6 +21,7 @@ export enum Errors {
GotUnknownFileTypeWithoutBabel = 'Got a unknown file type to compile (file: {{path}}). To fix this, in your Jest config change the `transform` key which value is `ts-jest` so that it does not match this kind of files anymore.',
GotUnknownFileTypeWithBabel = 'Got a unknown file type to compile (file: {{path}}). To fix this, in your Jest config change the `transform` key which value is `ts-jest` so that it does not match this kind of files anymore. If you still want Babel to process it, add another entry to the `transform` option with value `babel-jest` which key matches this type of files.',
ConfigNoModuleInterop = 'If you have issues related to imports, you should consider setting `esModuleInterop` to `true` in your TypeScript configuration file (usually `tsconfig.json`). See https://blogs.msdn.microsoft.com/typescript/2018/01/31/announcing-typescript-2-7/#easier-ecmascript-module-interoperability for more information.',
UnableToFindProjectRoot = 'Unable to find the root of the project where ts-jest has been installed.',
}

/**
Expand Down

0 comments on commit 6cacbea

Please sign in to comment.