diff --git a/.gitignore b/.gitignore index 6bf7fdc08f..0f63580947 100644 --- a/.gitignore +++ b/.gitignore @@ -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/ diff --git a/.npmignore b/.npmignore index 9168b0e8cf..2c9e8e1826 100644 --- a/.npmignore +++ b/.npmignore @@ -74,3 +74,6 @@ tslint.json docs commitlint.config.js + +# ensure we do not omit the digest +!.ts-jest-digest diff --git a/package.json b/package.json index cd6e364c61..e9eab1b89d 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/scripts/e2e.js b/scripts/e2e.js index 3d988bf653..605b7b4523 100755 --- a/scripts/e2e.js +++ b/scripts/e2e.js @@ -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') @@ -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 diff --git a/scripts/lib/bundle.js b/scripts/lib/bundle.js index a70b2e08b7..2c32874c38 100644 --- a/scripts/lib/bundle.js +++ b/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') @@ -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') @@ -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, } diff --git a/scripts/lib/paths.d.ts b/scripts/lib/paths.d.ts index 6a346dcd24..4c6b0e3768 100644 --- a/scripts/lib/paths.d.ts +++ b/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 @@ -11,6 +12,7 @@ declare const e2eTestsDir: string export { rootDir, + pkgDigestFile, e2eSourceDir, e2eRootDir, e2eWorkDir, diff --git a/scripts/lib/paths.js b/scripts/lib/paths.js index 8abc889a5a..26907635b1 100644 --- a/scripts/lib/paths.js +++ b/scripts/lib/paths.js @@ -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') @@ -15,6 +16,7 @@ const e2eWorkTemplatesDir = path.join(e2eWorkDir, '__templates__') const e2eWotkDirLink = path.join(e2eRootDir, '__workdir_synlink__') module.exports = { + pkgDigestFile, rootDir, e2eSourceDir, e2eRootDir, diff --git a/scripts/post-build.js b/scripts/post-build.js new file mode 100644 index 0000000000..c88e7b5796 --- /dev/null +++ b/scripts/post-build.js @@ -0,0 +1,3 @@ +const { computePackageDigest } = require('./lib/bundle') + +computePackageDigest() diff --git a/src/__mocks__/index.ts b/src/__mocks__/index.ts new file mode 100644 index 0000000000..54c4bda3d1 --- /dev/null +++ b/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() diff --git a/src/config/config-set.spec.ts b/src/config/config-set.spec.ts index e5a7bc3988..a357fc9bbe 100644 --- a/src/config/config-set.spec.ts +++ b/src/config/config-set.spec.ts @@ -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' @@ -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, @@ -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'), }) }) @@ -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 }) @@ -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 @@ -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 {}, @@ -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, }, } `) diff --git a/src/config/config-set.ts b/src/config/config-set.ts index 00acbfafc9..4d1c1debfd 100644 --- a/src/config/config-set.ts +++ b/src/config/config-set.ts @@ -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 { @@ -229,7 +229,7 @@ export class ConfigSet { map[name] = getPackageVersion(name) || '-' return map }, - { 'ts-jest': myVersion } as Record, + { 'ts-jest': MY_VERSION } as Record, ) } @@ -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 } @@ -489,6 +489,11 @@ export class ConfigSet { return !!process.env.TS_JEST_DOCTOR } + @Memoize() + get tsJestDigest(): string { + return MY_DIGEST + } + /** * @internal */ @@ -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, }) } diff --git a/src/index.ts b/src/index.ts index 76e8775a37..15806be569 100644 --- a/src/index.ts +++ b/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' @@ -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 {