Skip to content

Commit

Permalink
fix(cache): resolved tsconfig in cache key + pkg digest
Browse files Browse the repository at this point in the history
- Includes the resolved tsconfig object and not the input one in the
jest cache key.
- Includes a digest of ts-jest's package in the jest cache key.
- Cascade typescript compiler cache dir

Closes #749
  • Loading branch information
huafu committed Sep 22, 2018
1 parent a1b77a1 commit e891608
Show file tree
Hide file tree
Showing 12 changed files with 77 additions and 21 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -50,6 +50,7 @@ tests/simple-long-path/long-src-path
# is linked to the temp dir of the os
e2e/__workdir_synlink__
**/.ts-jest-e2e.json
.ts-jest-digest
# while refactoring...
old/

Expand Down
3 changes: 3 additions & 0 deletions .npmignore
Expand Up @@ -74,3 +74,6 @@ tslint.json
docs

commitlint.config.js

# ensure we do not omit the digest
!.ts-jest-digest
3 changes: 2 additions & 1 deletion package.json
Expand Up @@ -8,9 +8,10 @@
"scripts": {
"prebuild": "node scripts/clean-dist.js",
"build": "tsc -p tsconfig.build.json",
"postbuild": "node scripts/post-build.js",
"build:watch": "tsc -p tsconfig.build.json -w",
"clean": "node scripts/clean.js",
"pretest": "run-s typecheck lint",
"pretest": "npm run lint",
"test": "run-s -s test:e2e \"test:unit -- {@}\" --",
"test:prepare": "npm run test:e2e -- --prepareOnly",
"test:e2e": "node scripts/e2e.js",
Expand Down
5 changes: 2 additions & 3 deletions scripts/e2e.js
Expand Up @@ -8,7 +8,7 @@ const path = require('path')
const Paths = require('./lib/paths')
const { createHash } = require('crypto')
const logger = require('./lib/logger')
const { createBundle, packageDigest } = require('./lib/bundle')
const { createBundle, readPackageDigest } = require('./lib/bundle')
const npm = require('./lib/npm')

const configFile = path.join(Paths.e2eRootDir, 'jest.config.js')
Expand Down Expand Up @@ -49,8 +49,7 @@ function setupE2e() {
)

// get the hash of the bundle (to know if we should install it again or not)
// we need to compute it ourselfs as the npm pack creates different tgz even tho content has not changed
const bundleHash = packageDigest(bundle)
const bundleHash = readPackageDigest()
log('ts-jest digest:', bundleHash)

// ensure directory exists before copying over
Expand Down
21 changes: 15 additions & 6 deletions scripts/lib/bundle.js
@@ -1,8 +1,8 @@
const npm = require('./npm')
const logger = require('./logger')
const { rootDir } = require('./paths')
const { rootDir, pkgDigestFile } = require('./paths')
const { join, resolve } = require('path')
const { readFileSync, statSync } = require('fs')
const { readFileSync, statSync, writeFileSync, existsSync } = require('fs-extra')
const { createHash } = require('crypto')
const { sync: globIgnore } = require('glob-gitignore')

Expand All @@ -19,7 +19,11 @@ function createBundle(log = logger.log.bind(logger)) {
return join(rootDir, res.stdout.toString().trim())
}

function packageDigest() {
function readPackageDigest() {
return existsSync(pkgDigestFile) ? readFileSync(pkgDigestFile, 'utf8') : undefined
}

function computePackageDigest(noWriteFile = false) {
const files = globIgnore(join(rootDir, '**'), {
ignore: readFileSync(join(rootDir, '.npmignore'))
.toString('utf8')
Expand All @@ -28,14 +32,19 @@ function packageDigest() {
})
const hash = createHash('sha1')
files.sort().forEach(file => {
if (statSync(file).isDirectory()) return
if (file === pkgDigestFile || statSync(file).isDirectory()) return
hash.update(readFileSync(resolve(file)))
hash.update('\x00')
})
return hash.digest('hex')
const digest = hash.digest('hex')
if (!noWriteFile) {
writeFileSync(pkgDigestFile, digest, 'utf8')
}
return digest
}

module.exports = {
createBundle,
packageDigest,
computePackageDigest,
readPackageDigest,
}
2 changes: 2 additions & 0 deletions scripts/lib/paths.d.ts
@@ -1,4 +1,5 @@
declare const rootDir: string
declare const pkgDigestFile: string
declare const e2eSourceDir: string
declare const e2eRootDir: string
declare const e2eWorkDir: string
Expand All @@ -11,6 +12,7 @@ declare const e2eTestsDir: string

export {
rootDir,
pkgDigestFile,
e2eSourceDir,
e2eRootDir,
e2eWorkDir,
Expand Down
2 changes: 2 additions & 0 deletions scripts/lib/paths.js
Expand Up @@ -2,6 +2,7 @@ const path = require('path')
const os = require('os')

const rootDir = path.resolve(__dirname, '..', '..')
const pkgDigestFile = path.join(rootDir, '.ts-jest-digest')
const distDir = path.join(rootDir, 'dist')
const testsRootDir = path.join(rootDir, 'tests')
const e2eRootDir = path.join(rootDir, 'e2e')
Expand All @@ -15,6 +16,7 @@ const e2eWorkTemplatesDir = path.join(e2eWorkDir, '__templates__')
const e2eWotkDirLink = path.join(e2eRootDir, '__workdir_synlink__')

module.exports = {
pkgDigestFile,
rootDir,
e2eSourceDir,
e2eRootDir,
Expand Down
3 changes: 3 additions & 0 deletions scripts/post-build.js
@@ -0,0 +1,3 @@
const { computePackageDigest } = require('./lib/bundle')

computePackageDigest()
6 changes: 6 additions & 0 deletions src/__mocks__/index.ts
@@ -0,0 +1,6 @@
export const version = '1.2.3-test.0'
export const digest = 'a0d51ca854194df8191d0e65c0ca4730f510f332'
export const createTransformer = jest.fn()
export const jestPreset = { jestPreset: true }
export const createJestPreset = jest.fn()
export const pathsToModuleNameMapper = jest.fn()
32 changes: 26 additions & 6 deletions src/config/config-set.spec.ts
Expand Up @@ -2,7 +2,7 @@ import { testing } from 'bs-logger'
import { resolve } from 'path'
import ts, { Diagnostic, ModuleKind, ScriptTarget } from 'typescript'

import { version as currentVersion } from '../../package.json'
import * as _myModule from '..'
import * as fakers from '../__helpers__/fakers'
import { logTargetMock, mocked } from '../__helpers__/mocks'
import { TsJestGlobalOptions } from '../types'
Expand All @@ -12,8 +12,10 @@ import { normalizeSlashes } from '../util/normalize-slashes'
import { ConfigSet, IGNORE_DIAGNOSTIC_CODES, MATCH_NOTHING } from './config-set'

jest.mock('../util/backports')
jest.mock('../index')

const backports = mocked(_backports)
const myModule = mocked(_myModule)

backports.backportJestConfig.mockImplementation((_, config) => ({
...config,
Expand Down Expand Up @@ -385,7 +387,7 @@ describe('versions', () => {
it('should return correct version map', () => {
expect(createConfigSet().versions).toEqual({
jest: pkgVersion('jest'),
'ts-jest': currentVersion,
'ts-jest': myModule.version,
typescript: pkgVersion('typescript'),
})
})
Expand All @@ -397,13 +399,19 @@ describe('versions', () => {
'babel-core': pkgVersion('babel-core'),
'babel-jest': pkgVersion('babel-jest'),
jest: pkgVersion('jest'),
'ts-jest': currentVersion,
'ts-jest': myModule.version,
typescript: pkgVersion('typescript'),
})
})
})
}) // versions

describe('tsJestDigest', () => {
it('should be the package digest', () => {
expect(createConfigSet().tsJestDigest).toBe(myModule.digest)
})
}) // tsJestDigest

describe('tsconfig', () => {
it('should return input tsconfig', () => {
const cs = createConfigSet({ tsJestConfig: { tsConfig: { target: 'ES6' } } as any })
Expand Down Expand Up @@ -468,8 +476,9 @@ describe('cacheKey', () => {
const val = cs.jsonValue.value
delete val.versions
cs.jsonValue.value = val
// digest is mocked in src/__mocks__/index.ts
expect(cs.cacheKey).toMatchInlineSnapshot(
`"{\\"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\\":{\\"compilerOptions\\":{}}}"`,
`"{\\"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}}"`,
)
})
}) // cacheKey
Expand All @@ -479,13 +488,15 @@ describe('jsonValue', () => {
const cs = createConfigSet({ tsJestConfig: { tsConfig: false } as any })
const val = cs.jsonValue.valueOf()
expect(cs.toJSON()).toEqual(val)
// it will change each time we upgrade and we tested those in the `version` block
// it will change each time we upgrade we tested those in the `version` block
expect(val.versions).toEqual(cs.versions)
delete val.versions

// digest is mocked in src/__mocks__/index.ts
expect(val).toMatchInlineSnapshot(`
Object {
"babel": undefined,
"digest": "a0d51ca854194df8191d0e65c0ca4730f510f332",
"jest": Object {
"__backported": true,
"globals": Object {},
Expand All @@ -511,7 +522,16 @@ Object {
"tsConfig": undefined,
},
"tsconfig": Object {
"compilerOptions": Object {},
"configFilePath": undefined,
"declaration": false,
"inlineSourceMap": false,
"inlineSources": true,
"module": 1,
"noEmit": false,
"outDir": "$$ts-jest$$",
"removeComments": false,
"sourceMap": true,
"target": 1,
},
}
`)
Expand Down
16 changes: 11 additions & 5 deletions src/config/config-set.ts
Expand Up @@ -23,7 +23,7 @@ import {
SourceFile,
} from 'typescript'

import { version as myVersion } from '..'
import { digest as MY_DIGEST, version as MY_VERSION } from '..'
import { createCompiler } from '../compiler'
import { internals as internalAstTransformers } from '../transformers'
import {
Expand Down Expand Up @@ -229,7 +229,7 @@ export class ConfigSet {
map[name] = getPackageVersion(name) || '-'
return map
},
{ 'ts-jest': myVersion } as Record<string, string>,
{ 'ts-jest': MY_VERSION } as Record<string, string>,
)
}

Expand Down Expand Up @@ -438,10 +438,10 @@ export class ConfigSet {
compiler: this.tsJest.compiler,
compilerOptions: this.typescript.options,
isolatedModules: this.tsJest.isolatedModules,
ignoreDiagnostics: this.tsJest.diagnostics.ignoreCodes,
diagnostics: this.tsJest.diagnostics,
}),
)
const res = join(this.jest.cacheDirectory, `ts-jest-${cacheSuffix}`)
const res = join(this.jest.cacheDirectory, 'ts-jest', cacheSuffix.substr(0, 2), cacheSuffix.substr(2))
logger.debug({ cacheDirectory: res }, `will use file caching`)
return res
}
Expand Down Expand Up @@ -489,6 +489,11 @@ export class ConfigSet {
return !!process.env.TS_JEST_DOCTOR
}

@Memoize()
get tsJestDigest(): string {
return MY_DIGEST
}

/**
* @internal
*/
Expand All @@ -505,11 +510,12 @@ export class ConfigSet {

return new JsonableValue({
versions: this.versions,
digest: this.tsJestDigest,
transformers: this.astTransformers.map(t => `${t.name}@${t.version}`),
jest,
tsJest: this.tsJest,
babel: this.babel,
tsconfig: this.tsconfig,
tsconfig: this.typescript.options,
})
}

Expand Down
4 changes: 4 additions & 0 deletions src/index.ts
@@ -1,3 +1,6 @@
import { readFileSync } from 'fs'
import { resolve } from 'path'

import { createJestPreset } from './config/create-jest-preset'
import { pathsToModuleNameMapper } from './config/paths-to-module-name-mapper'
import { TsJestTransformer } from './ts-jest-transformer'
Expand All @@ -6,6 +9,7 @@ import { VersionCheckers } from './util/version-checkers'

// tslint:disable-next-line:no-var-requires
export const version: string = require('../package.json').version
export const digest: string = readFileSync(resolve(__dirname, '..', '.ts-jest-digest'), 'utf8')

let transformer!: TsJestTransformer
function defaultTransformer(): TsJestTransformer {
Expand Down

0 comments on commit e891608

Please sign in to comment.