From 82c74151d15ab1d18119287956f6d8b97f8f375a Mon Sep 17 00:00:00 2001 From: Christoph Nakazawa Date: Mon, 5 Oct 2020 17:15:12 +0900 Subject: [PATCH] [feature] Add package to create cache key functions (#10587) --- .watchmanconfig | 1 + CHANGELOG.md | 1 + .../jest-create-cache-key-function/.npmignore | 5 ++ .../package.json | 22 +++++++ .../src/__tests__/index.test.ts | 42 +++++++++++++ .../src/index.ts | 59 +++++++++++++++++++ .../tsconfig.json | 10 ++++ yarn.lock | 8 +++ 8 files changed, 148 insertions(+) create mode 100644 packages/jest-create-cache-key-function/.npmignore create mode 100644 packages/jest-create-cache-key-function/package.json create mode 100644 packages/jest-create-cache-key-function/src/__tests__/index.test.ts create mode 100644 packages/jest-create-cache-key-function/src/index.ts create mode 100644 packages/jest-create-cache-key-function/tsconfig.json diff --git a/.watchmanconfig b/.watchmanconfig index e69de29bb2d1..fe51488c7066 100644 --- a/.watchmanconfig +++ b/.watchmanconfig @@ -0,0 +1 @@ +[] diff --git a/CHANGELOG.md b/CHANGELOG.md index 95b3d0ec82d2..81696b1d76f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - `[jest-circus, jest-config, jest-runtime]` Add new `injectGlobals` config and CLI option to disable injecting global variables into the runtime ([#10484](https://github.com/facebook/jest/pull/10484)) - `[jest-each]` Fixes `.each` type to always be callable ([#10447](https://github.com/facebook/jest/pull/10447)) - `[jest-runner]` Add support for `moduleLoader`s with `default` exports ([#10541](https://github.com/facebook/jest/pull/10541)) +- `[@jest/create-cache-key-function]` Added a new package for creating cache keys ([#10587](https://github.com/facebook/jest/pull/10587)) ### Fixes diff --git a/packages/jest-create-cache-key-function/.npmignore b/packages/jest-create-cache-key-function/.npmignore new file mode 100644 index 000000000000..3ee5d55b0b89 --- /dev/null +++ b/packages/jest-create-cache-key-function/.npmignore @@ -0,0 +1,5 @@ +**/__mocks__/** +**/__tests__/** +src +tsconfig.json +tsconfig.tsbuildinfo diff --git a/packages/jest-create-cache-key-function/package.json b/packages/jest-create-cache-key-function/package.json new file mode 100644 index 000000000000..766e3b7b2d67 --- /dev/null +++ b/packages/jest-create-cache-key-function/package.json @@ -0,0 +1,22 @@ +{ + "name": "@jest/create-cache-key-function", + "version": "26.4.2", + "repository": { + "type": "git", + "url": "https://github.com/facebook/jest.git", + "directory": "packages/jest-create-cache-key-function" + }, + "devDependencies": { + "@types/node": "*" + }, + "engines": { + "node": ">= 10.14.2" + }, + "license": "MIT", + "main": "build/index.js", + "types": "build/index.d.ts", + "publishConfig": { + "access": "public" + }, + "gitHead": "170eee11d03b0ed5c60077982fdbc3bafd403638" +} diff --git a/packages/jest-create-cache-key-function/src/__tests__/index.test.ts b/packages/jest-create-cache-key-function/src/__tests__/index.test.ts new file mode 100644 index 000000000000..ca498a0210fa --- /dev/null +++ b/packages/jest-create-cache-key-function/src/__tests__/index.test.ts @@ -0,0 +1,42 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +let NODE_ENV: string; +let BABEL_ENV: string; + +beforeEach(() => { + NODE_ENV = process.env.NODE_ENV; + process.env.NODE_ENV = 'test'; + BABEL_ENV = process.env.BABEL_ENV; + process.env.BABEL_ENV = 'test'; +}); + +afterEach(() => { + process.env.NODE_ENV = NODE_ENV; + process.env.BABEL_ENV = BABEL_ENV; +}); + +test('creation of a cache key', () => { + const createCacheKeyFunction = require('../index').default; + const createCacheKey = createCacheKeyFunction([], ['value']); + const hashA = createCacheKey('test', 'test.js', null, { + config: {}, + instrument: false, + }); + const hashB = createCacheKey('test code;', 'test.js', null, { + config: {}, + instrument: false, + }); + const hashC = createCacheKey('test', 'test.js', null, { + config: {}, + instrument: true, + }); + + expect(hashA.length).toEqual(32); + expect(hashA).not.toEqual(hashB); + expect(hashA).not.toEqual(hashC); +}); diff --git a/packages/jest-create-cache-key-function/src/index.ts b/packages/jest-create-cache-key-function/src/index.ts new file mode 100644 index 000000000000..8b87deb69ef8 --- /dev/null +++ b/packages/jest-create-cache-key-function/src/index.ts @@ -0,0 +1,59 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +import {createHash} from 'crypto'; +import {relative} from 'path'; +/* eslint-disable-next-line no-restricted-imports */ +import {readFileSync} from 'fs'; +import type {Config} from '@jest/types'; + +type CacheKeyOptions = { + config: Config.ProjectConfig; + instrument: boolean; +}; + +type GetCacheKeyFunction = ( + fileData: string, + filePath: Config.Path, + configStr: string, + options: CacheKeyOptions, +) => string; + +function getGlobalCacheKey(files: Array, values: Array) { + return [ + process.env.NODE_ENV, + process.env.BABEL_ENV, + ...values, + ...files.map((file: string) => readFileSync(file)), + ] + .reduce( + (hash, chunk) => hash.update('\0', 'utf8').update(chunk || ''), + createHash('md5'), + ) + .digest('hex'); +} + +function getCacheKeyFunction(globalCacheKey: string): GetCacheKeyFunction { + return (src, file, _configString, options) => { + const {config, instrument} = options; + return createHash('md5') + .update(globalCacheKey) + .update('\0', 'utf8') + .update(src) + .update('\0', 'utf8') + .update(config.rootDir ? relative(config.rootDir, file) : '') + .update('\0', 'utf8') + .update(instrument ? 'instrument' : '') + .digest('hex'); + }; +} + +export default ( + files: Array = [], + values: Array = [], +): GetCacheKeyFunction => getCacheKeyFunction(getGlobalCacheKey(files, values)); diff --git a/packages/jest-create-cache-key-function/tsconfig.json b/packages/jest-create-cache-key-function/tsconfig.json new file mode 100644 index 000000000000..25e34a0f4511 --- /dev/null +++ b/packages/jest-create-cache-key-function/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "build" + }, + "references": [ + {"path": "../jest-types"} + ] +} diff --git a/yarn.lock b/yarn.lock index 2abda00e24c1..306fb76be4c8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1808,6 +1808,14 @@ __metadata: languageName: unknown linkType: soft +"@jest/create-cache-key-function@workspace:packages/jest-create-cache-key-function": + version: 0.0.0-use.local + resolution: "@jest/create-cache-key-function@workspace:packages/jest-create-cache-key-function" + dependencies: + "@types/node": "*" + languageName: unknown + linkType: soft + "@jest/environment@^26.3.0, @jest/environment@workspace:packages/jest-environment": version: 0.0.0-use.local resolution: "@jest/environment@workspace:packages/jest-environment"