mirror of https://github.com/status-im/metro.git
metro-bundler: @format lib/
Reviewed By: cpojer Differential Revision: D5493458 fbshipit-source-id: 05ac2895125b1419996a66f3ef155bc2cec11c02
This commit is contained in:
parent
521e25bded
commit
14b88b6ad4
|
@ -7,13 +7,16 @@
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
*
|
*
|
||||||
* @flow
|
* @flow
|
||||||
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const invariant = require('fbjs/lib/invariant');
|
const invariant = require('fbjs/lib/invariant');
|
||||||
|
|
||||||
type ProcessBatch<TItem, TResult> = (batch: Array<TItem>) => Promise<Array<TResult>>;
|
type ProcessBatch<TItem, TResult> = (
|
||||||
|
batch: Array<TItem>,
|
||||||
|
) => Promise<Array<TResult>>;
|
||||||
|
|
||||||
type BatchProcessorOptions = {
|
type BatchProcessorOptions = {
|
||||||
maximumDelayMs: number,
|
maximumDelayMs: number,
|
||||||
|
@ -35,14 +38,16 @@ type QueueItem<TItem, TResult> = {
|
||||||
* processing right away.
|
* processing right away.
|
||||||
*/
|
*/
|
||||||
class BatchProcessor<TItem, TResult> {
|
class BatchProcessor<TItem, TResult> {
|
||||||
|
|
||||||
_currentProcessCount: number;
|
_currentProcessCount: number;
|
||||||
_options: BatchProcessorOptions;
|
_options: BatchProcessorOptions;
|
||||||
_processBatch: ProcessBatch<TItem, TResult>;
|
_processBatch: ProcessBatch<TItem, TResult>;
|
||||||
_queue: Array<QueueItem<TItem, TResult>>;
|
_queue: Array<QueueItem<TItem, TResult>>;
|
||||||
_timeoutHandle: ?number;
|
_timeoutHandle: ?number;
|
||||||
|
|
||||||
constructor(options: BatchProcessorOptions, processBatch: ProcessBatch<TItem, TResult>) {
|
constructor(
|
||||||
|
options: BatchProcessorOptions,
|
||||||
|
processBatch: ProcessBatch<TItem, TResult>,
|
||||||
|
) {
|
||||||
this._options = options;
|
this._options = options;
|
||||||
this._processBatch = processBatch;
|
this._processBatch = processBatch;
|
||||||
this._queue = [];
|
this._queue = [];
|
||||||
|
@ -56,7 +61,10 @@ class BatchProcessor<TItem, TResult> {
|
||||||
this._processQueueOnceReady();
|
this._processQueueOnceReady();
|
||||||
}
|
}
|
||||||
|
|
||||||
_onBatchResults(jobs: Array<QueueItem<TItem, TResult>>, results: Array<TResult>) {
|
_onBatchResults(
|
||||||
|
jobs: Array<QueueItem<TItem, TResult>>,
|
||||||
|
results: Array<TResult>,
|
||||||
|
) {
|
||||||
invariant(results.length === jobs.length, 'Not enough results returned.');
|
invariant(results.length === jobs.length, 'Not enough results returned.');
|
||||||
for (let i = 0; i < jobs.length; ++i) {
|
for (let i = 0; i < jobs.length; ++i) {
|
||||||
jobs[i].resolve(results[i]);
|
jobs[i].resolve(results[i]);
|
||||||
|
@ -104,7 +112,6 @@ class BatchProcessor<TItem, TResult> {
|
||||||
this._processQueueOnceReady();
|
this._processQueueOnceReady();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = BatchProcessor;
|
module.exports = BatchProcessor;
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
*
|
*
|
||||||
* @flow
|
* @flow
|
||||||
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
@ -76,7 +77,6 @@ type URI = string;
|
||||||
* ensures we do a single request at a time to avoid pressuring the I/O.
|
* ensures we do a single request at a time to avoid pressuring the I/O.
|
||||||
*/
|
*/
|
||||||
class KeyURIFetcher {
|
class KeyURIFetcher {
|
||||||
|
|
||||||
_batchProcessor: BatchProcessor<string, ?URI>;
|
_batchProcessor: BatchProcessor<string, ?URI>;
|
||||||
_fetchResultURIs: FetchResultURIs;
|
_fetchResultURIs: FetchResultURIs;
|
||||||
|
|
||||||
|
@ -96,24 +96,27 @@ class KeyURIFetcher {
|
||||||
|
|
||||||
constructor(fetchResultURIs: FetchResultURIs) {
|
constructor(fetchResultURIs: FetchResultURIs) {
|
||||||
this._fetchResultURIs = fetchResultURIs;
|
this._fetchResultURIs = fetchResultURIs;
|
||||||
this._batchProcessor = new BatchProcessor({
|
this._batchProcessor = new BatchProcessor(
|
||||||
|
{
|
||||||
maximumDelayMs: 10,
|
maximumDelayMs: 10,
|
||||||
maximumItems: 500,
|
maximumItems: 500,
|
||||||
concurrency: 2,
|
concurrency: 2,
|
||||||
}, this._processKeys.bind(this));
|
},
|
||||||
|
this._processKeys.bind(this),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type KeyedResult = {key: string, result: CachedResult};
|
type KeyedResult = {key: string, result: CachedResult};
|
||||||
|
|
||||||
class KeyResultStore {
|
class KeyResultStore {
|
||||||
|
|
||||||
_storeResults: StoreResults;
|
_storeResults: StoreResults;
|
||||||
_batchProcessor: BatchProcessor<KeyedResult, void>;
|
_batchProcessor: BatchProcessor<KeyedResult, void>;
|
||||||
|
|
||||||
async _processResults(keyResults: Array<KeyedResult>): Promise<Array<void>> {
|
async _processResults(keyResults: Array<KeyedResult>): Promise<Array<void>> {
|
||||||
const resultsByKey = new Map(keyResults.map(pair => [pair.key, pair.result]));
|
const resultsByKey = new Map(
|
||||||
|
keyResults.map(pair => [pair.key, pair.result]),
|
||||||
|
);
|
||||||
await this._storeResults(resultsByKey);
|
await this._storeResults(resultsByKey);
|
||||||
return new Array(keyResults.length);
|
return new Array(keyResults.length);
|
||||||
}
|
}
|
||||||
|
@ -124,16 +127,22 @@ class KeyResultStore {
|
||||||
|
|
||||||
constructor(storeResults: StoreResults) {
|
constructor(storeResults: StoreResults) {
|
||||||
this._storeResults = storeResults;
|
this._storeResults = storeResults;
|
||||||
this._batchProcessor = new BatchProcessor({
|
this._batchProcessor = new BatchProcessor(
|
||||||
|
{
|
||||||
maximumDelayMs: 1000,
|
maximumDelayMs: 1000,
|
||||||
maximumItems: 100,
|
maximumItems: 100,
|
||||||
concurrency: 10,
|
concurrency: 10,
|
||||||
}, this._processResults.bind(this));
|
},
|
||||||
|
this._processResults.bind(this),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TransformProfile = {+dev: boolean, +minify: boolean, +platform: ?string};
|
export type TransformProfile = {
|
||||||
|
+dev: boolean,
|
||||||
|
+minify: boolean,
|
||||||
|
+platform: ?string,
|
||||||
|
};
|
||||||
|
|
||||||
function profileKey({dev, minify, platform}: TransformProfile): string {
|
function profileKey({dev, minify, platform}: TransformProfile): string {
|
||||||
return jsonStableStringify({dev, minify, platform});
|
return jsonStableStringify({dev, minify, platform});
|
||||||
|
@ -157,14 +166,14 @@ class TransformProfileSet {
|
||||||
}
|
}
|
||||||
|
|
||||||
type FetchFailedDetails =
|
type FetchFailedDetails =
|
||||||
{
|
| {
|
||||||
+statusCode: number,
|
+statusCode: number,
|
||||||
+statusText: string,
|
+statusText: string,
|
||||||
+type: 'unhandled_http_status',
|
+type: 'unhandled_http_status',
|
||||||
+uri: string,
|
+uri: string,
|
||||||
} |
|
}
|
||||||
{+type: 'invalid_data'} |
|
| {+type: 'invalid_data'}
|
||||||
{+type: 'invalid_key_data', key: string};
|
| {+type: 'invalid_key_data', key: string};
|
||||||
|
|
||||||
class FetchFailedError extends Error {
|
class FetchFailedError extends Error {
|
||||||
/** Separate object for details allows us to have a type union. */
|
/** Separate object for details allows us to have a type union. */
|
||||||
|
@ -210,7 +219,6 @@ function validateCachedResult(cachedResult: mixed): ?CachedResult {
|
||||||
}
|
}
|
||||||
|
|
||||||
class URIBasedGlobalTransformCache {
|
class URIBasedGlobalTransformCache {
|
||||||
|
|
||||||
_fetcher: KeyURIFetcher;
|
_fetcher: KeyURIFetcher;
|
||||||
_fetchResultFromURI: FetchResultFromURI;
|
_fetchResultFromURI: FetchResultFromURI;
|
||||||
_profileSet: TransformProfileSet;
|
_profileSet: TransformProfileSet;
|
||||||
|
@ -249,7 +257,9 @@ class URIBasedGlobalTransformCache {
|
||||||
keyOf(props: FetchProps) {
|
keyOf(props: FetchProps) {
|
||||||
const hash = crypto.createHash('sha1');
|
const hash = crypto.createHash('sha1');
|
||||||
const {sourceCode, localPath, transformOptions} = props;
|
const {sourceCode, localPath, transformOptions} = props;
|
||||||
hash.update(this._optionsHasher.getTransformWorkerOptionsDigest(transformOptions));
|
hash.update(
|
||||||
|
this._optionsHasher.getTransformWorkerOptionsDigest(transformOptions),
|
||||||
|
);
|
||||||
const cacheKey = props.getTransformCacheKey(transformOptions);
|
const cacheKey = props.getTransformCacheKey(transformOptions);
|
||||||
hash.update(JSON.stringify(cacheKey));
|
hash.update(JSON.stringify(cacheKey));
|
||||||
hash.update(JSON.stringify(localPath));
|
hash.update(JSON.stringify(localPath));
|
||||||
|
@ -287,7 +297,9 @@ class URIBasedGlobalTransformCache {
|
||||||
* waiting a little time before retring if experience shows it's useful.
|
* waiting a little time before retring if experience shows it's useful.
|
||||||
*/
|
*/
|
||||||
static _fetchResultFromURIWithRetry(uri: string): Promise<CachedResult> {
|
static _fetchResultFromURIWithRetry(uri: string): Promise<CachedResult> {
|
||||||
return URIBasedGlobalTransformCache._fetchResultFromURI(uri).catch(error => {
|
return URIBasedGlobalTransformCache._fetchResultFromURI(
|
||||||
|
uri,
|
||||||
|
).catch(error => {
|
||||||
if (!URIBasedGlobalTransformCache.shouldRetryAfterThatError(error)) {
|
if (!URIBasedGlobalTransformCache.shouldRetryAfterThatError(error)) {
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
@ -311,11 +323,10 @@ class URIBasedGlobalTransformCache {
|
||||||
*/
|
*/
|
||||||
static shouldRetryAfterThatError(error: mixed): boolean {
|
static shouldRetryAfterThatError(error: mixed): boolean {
|
||||||
return (
|
return (
|
||||||
error instanceof FetchError && error.type === 'request-timeout' || (
|
(error instanceof FetchError && error.type === 'request-timeout') ||
|
||||||
error instanceof FetchFailedError &&
|
(error instanceof FetchFailedError &&
|
||||||
error.details.type === 'unhandled_http_status' &&
|
error.details.type === 'unhandled_http_status' &&
|
||||||
(error.details.statusCode === 503 || error.details.statusCode === 502)
|
(error.details.statusCode === 503 || error.details.statusCode === 502))
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,11 +351,12 @@ class URIBasedGlobalTransformCache {
|
||||||
this._store.store(this.keyOf(props), result);
|
this._store.store(this.keyOf(props), result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
URIBasedGlobalTransformCache.fetchResultFromURI =
|
URIBasedGlobalTransformCache.fetchResultFromURI = throat(
|
||||||
throat(500, URIBasedGlobalTransformCache._fetchResultFromURIWithRetry);
|
500,
|
||||||
|
URIBasedGlobalTransformCache._fetchResultFromURIWithRetry,
|
||||||
|
);
|
||||||
|
|
||||||
class OptionsHasher {
|
class OptionsHasher {
|
||||||
_rootPath: string;
|
_rootPath: string;
|
||||||
|
@ -383,15 +395,20 @@ class OptionsHasher {
|
||||||
* many different fields including the optional Babel fields, and some serious
|
* many different fields including the optional Babel fields, and some serious
|
||||||
* cleanup will be necessary to enable rock-solid typing.
|
* cleanup will be necessary to enable rock-solid typing.
|
||||||
*/
|
*/
|
||||||
hashTransformWorkerOptions(hash: crypto$Hash, options: TransformWorkerOptions): crypto$Hash {
|
hashTransformWorkerOptions(
|
||||||
|
hash: crypto$Hash,
|
||||||
|
options: TransformWorkerOptions,
|
||||||
|
): crypto$Hash {
|
||||||
const {dev, minify, platform, transform, ...unknowns} = options;
|
const {dev, minify, platform, transform, ...unknowns} = options;
|
||||||
const unknownKeys = Object.keys(unknowns);
|
const unknownKeys = Object.keys(unknowns);
|
||||||
if (unknownKeys.length > 0) {
|
if (unknownKeys.length > 0) {
|
||||||
const message = `these worker option fields are unknown: ${JSON.stringify(unknownKeys)}`;
|
const message = `these worker option fields are unknown: ${JSON.stringify(
|
||||||
|
unknownKeys,
|
||||||
|
)}`;
|
||||||
throw new CannotHashOptionsError(message);
|
throw new CannotHashOptionsError(message);
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line no-undef, no-bitwise
|
// eslint-disable-next-line no-undef, no-bitwise
|
||||||
hash.update(new Buffer([+dev | +minify << 1]));
|
hash.update(new Buffer([+dev | (+minify << 1)]));
|
||||||
hash.update(JSON.stringify(platform));
|
hash.update(JSON.stringify(platform));
|
||||||
return this.hashTransformOptions(hash, transform);
|
return this.hashTransformOptions(hash, transform);
|
||||||
}
|
}
|
||||||
|
@ -404,25 +421,45 @@ class OptionsHasher {
|
||||||
* of the cache key as they should not affect the transformation of a single
|
* of the cache key as they should not affect the transformation of a single
|
||||||
* particular file.
|
* particular file.
|
||||||
*/
|
*/
|
||||||
hashTransformOptions(hash: crypto$Hash, options: TransformOptionsStrict): crypto$Hash {
|
hashTransformOptions(
|
||||||
|
hash: crypto$Hash,
|
||||||
|
options: TransformOptionsStrict,
|
||||||
|
): crypto$Hash {
|
||||||
const {
|
const {
|
||||||
generateSourceMaps, dev, hot, inlineRequires, platform, projectRoot,
|
generateSourceMaps,
|
||||||
|
dev,
|
||||||
|
hot,
|
||||||
|
inlineRequires,
|
||||||
|
platform,
|
||||||
|
projectRoot,
|
||||||
...unknowns
|
...unknowns
|
||||||
} = options;
|
} = options;
|
||||||
const unknownKeys = Object.keys(unknowns);
|
const unknownKeys = Object.keys(unknowns);
|
||||||
if (unknownKeys.length > 0) {
|
if (unknownKeys.length > 0) {
|
||||||
const message = `these transform option fields are unknown: ${JSON.stringify(unknownKeys)}`;
|
const message = `these transform option fields are unknown: ${JSON.stringify(
|
||||||
|
unknownKeys,
|
||||||
|
)}`;
|
||||||
throw new CannotHashOptionsError(message);
|
throw new CannotHashOptionsError(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
hash.update(new Buffer([
|
hash.update(
|
||||||
|
new Buffer([
|
||||||
// eslint-disable-next-line no-bitwise
|
// eslint-disable-next-line no-bitwise
|
||||||
+dev | +generateSourceMaps << 1 | +hot << 2 | +!!inlineRequires << 3,
|
+dev |
|
||||||
]));
|
// eslint-disable-next-line no-bitwise
|
||||||
|
(+generateSourceMaps << 1) |
|
||||||
|
// eslint-disable-next-line no-bitwise
|
||||||
|
(+hot << 2) |
|
||||||
|
// eslint-disable-next-line no-bitwise
|
||||||
|
(+!!inlineRequires << 3),
|
||||||
|
]),
|
||||||
|
);
|
||||||
hash.update(JSON.stringify(platform));
|
hash.update(JSON.stringify(platform));
|
||||||
let blacklistWithLocalPaths = [];
|
let blacklistWithLocalPaths = [];
|
||||||
if (typeof inlineRequires === 'object') {
|
if (typeof inlineRequires === 'object') {
|
||||||
blacklistWithLocalPaths = this.pathsToLocal(Object.keys(inlineRequires.blacklist));
|
blacklistWithLocalPaths = this.pathsToLocal(
|
||||||
|
Object.keys(inlineRequires.blacklist),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
const localProjectRoot = this.toLocalPath(projectRoot);
|
const localProjectRoot = this.toLocalPath(projectRoot);
|
||||||
const optionTuple = [blacklistWithLocalPaths, localProjectRoot];
|
const optionTuple = [blacklistWithLocalPaths, localProjectRoot];
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
*
|
*
|
||||||
* @flow
|
* @flow
|
||||||
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
@ -14,7 +15,6 @@
|
||||||
import {Writable} from 'stream';
|
import {Writable} from 'stream';
|
||||||
|
|
||||||
class JsonReporter<TEvent: {}> {
|
class JsonReporter<TEvent: {}> {
|
||||||
|
|
||||||
_stream: Writable;
|
_stream: Writable;
|
||||||
|
|
||||||
constructor(stream: Writable) {
|
constructor(stream: Writable) {
|
||||||
|
@ -37,7 +37,6 @@ class JsonReporter<TEvent: {}> {
|
||||||
}
|
}
|
||||||
this._stream.write(JSON.stringify(event) + '\n');
|
this._stream.write(JSON.stringify(event) + '\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = JsonReporter;
|
module.exports = JsonReporter;
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
*
|
*
|
||||||
* @flow
|
* @flow
|
||||||
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
@ -24,7 +25,6 @@ type Metadata = {
|
||||||
};
|
};
|
||||||
|
|
||||||
class ModuleTransport {
|
class ModuleTransport {
|
||||||
|
|
||||||
name: string;
|
name: string;
|
||||||
id: number;
|
id: number;
|
||||||
code: string;
|
code: string;
|
||||||
|
@ -67,7 +67,6 @@ class ModuleTransport {
|
||||||
|
|
||||||
Object.freeze(this);
|
Object.freeze(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = ModuleTransport;
|
module.exports = ModuleTransport;
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
*
|
*
|
||||||
* @flow
|
* @flow
|
||||||
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
@ -32,7 +33,7 @@ export type FBIndexMap = IndexMap & FBExtensions;
|
||||||
export type SourceMap = IndexMap | MappingsMap;
|
export type SourceMap = IndexMap | MappingsMap;
|
||||||
export type FBSourceMap = FBIndexMap | (MappingsMap & FBExtensions);
|
export type FBSourceMap = FBIndexMap | (MappingsMap & FBExtensions);
|
||||||
|
|
||||||
function isMappingsMap(map: SourceMap)/*: %checks*/ {
|
function isMappingsMap(map: SourceMap): %checks {
|
||||||
return map.mappings !== undefined;
|
return map.mappings !== undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
*
|
*
|
||||||
* @flow
|
* @flow
|
||||||
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
@ -49,12 +50,14 @@ function getProgressBar(ratio: number, length: number) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TerminalReportableEvent = ReportableEvent | {
|
export type TerminalReportableEvent =
|
||||||
|
| ReportableEvent
|
||||||
|
| {
|
||||||
buildID: string,
|
buildID: string,
|
||||||
type: 'bundle_transform_progressed_throttled',
|
type: 'bundle_transform_progressed_throttled',
|
||||||
transformedFileCount: number,
|
transformedFileCount: number,
|
||||||
totalFileCount: number,
|
totalFileCount: number,
|
||||||
};
|
};
|
||||||
|
|
||||||
type BuildPhase = 'in_progress' | 'done' | 'failed';
|
type BuildPhase = 'in_progress' | 'done' | 'failed';
|
||||||
|
|
||||||
|
@ -63,7 +66,6 @@ type BuildPhase = 'in_progress' | 'done' | 'failed';
|
||||||
* This implements the `Reporter` interface from the './reporting' module.
|
* This implements the `Reporter` interface from the './reporting' module.
|
||||||
*/
|
*/
|
||||||
class TerminalReporter {
|
class TerminalReporter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The bundle builds for which we are actively maintaining the status on the
|
* The bundle builds for which we are actively maintaining the status on the
|
||||||
* terminal, ie. showing a progress bar. There can be several bundles being
|
* terminal, ie. showing a progress bar. There can be several bundles being
|
||||||
|
@ -115,7 +117,7 @@ class TerminalReporter {
|
||||||
(100 * ratio).toFixed(1),
|
(100 * ratio).toFixed(1),
|
||||||
transformedFileCount,
|
transformedFileCount,
|
||||||
totalFileCount,
|
totalFileCount,
|
||||||
phase === 'done' ? ', done.' : (phase === 'failed' ? ', failed.' : ''),
|
phase === 'done' ? ', done.' : phase === 'failed' ? ', failed.' : '',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,11 +144,14 @@ class TerminalReporter {
|
||||||
_logBundleBuildDone(buildID: string) {
|
_logBundleBuildDone(buildID: string) {
|
||||||
const progress = this._activeBundles.get(buildID);
|
const progress = this._activeBundles.get(buildID);
|
||||||
if (progress != null) {
|
if (progress != null) {
|
||||||
const msg = this._getBundleStatusMessage({
|
const msg = this._getBundleStatusMessage(
|
||||||
|
{
|
||||||
...progress,
|
...progress,
|
||||||
ratio: 1,
|
ratio: 1,
|
||||||
transformedFileCount: progress.totalFileCount,
|
transformedFileCount: progress.totalFileCount,
|
||||||
}, 'done');
|
},
|
||||||
|
'done',
|
||||||
|
);
|
||||||
this.terminal.log(msg);
|
this.terminal.log(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -166,21 +171,21 @@ class TerminalReporter {
|
||||||
port +
|
port +
|
||||||
'.\n\n' +
|
'.\n\n' +
|
||||||
'Keep this packager running while developing on any JS projects. ' +
|
'Keep this packager running while developing on any JS projects. ' +
|
||||||
'Feel free to close this tab and run your own packager instance if you ' +
|
'Feel free to close this tab and run your own packager instance ' +
|
||||||
'prefer.\n\n' +
|
'if you prefer.\n\n' +
|
||||||
'https://github.com/facebook/react-native',
|
'https://github.com/facebook/react-native',
|
||||||
{
|
{
|
||||||
marginLeft: 1,
|
marginLeft: 1,
|
||||||
marginRight: 1,
|
marginRight: 1,
|
||||||
paddingBottom: 1,
|
paddingBottom: 1,
|
||||||
}
|
},
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
this.terminal.log(
|
this.terminal.log(
|
||||||
'Looking for JS files in\n ',
|
'Looking for JS files in\n ',
|
||||||
chalk.dim(projectRoots.join('\n ')),
|
chalk.dim(projectRoots.join('\n ')),
|
||||||
'\n'
|
'\n',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,9 +193,11 @@ class TerminalReporter {
|
||||||
if (error.code === 'EADDRINUSE') {
|
if (error.code === 'EADDRINUSE') {
|
||||||
this.terminal.log(
|
this.terminal.log(
|
||||||
chalk.bgRed.bold(' ERROR '),
|
chalk.bgRed.bold(' ERROR '),
|
||||||
chalk.red("Packager can't listen on port", chalk.bold(port))
|
chalk.red("Packager can't listen on port", chalk.bold(port)),
|
||||||
|
);
|
||||||
|
this.terminal.log(
|
||||||
|
'Most likely another process is already using this port',
|
||||||
);
|
);
|
||||||
this.terminal.log('Most likely another process is already using this port');
|
|
||||||
this.terminal.log('Run the following command to find out which process:');
|
this.terminal.log('Run the following command to find out which process:');
|
||||||
this.terminal.log('\n ', chalk.bold('lsof -i :' + port), '\n');
|
this.terminal.log('\n ', chalk.bold('lsof -i :' + port), '\n');
|
||||||
this.terminal.log('Then, you can either shut down the other process:');
|
this.terminal.log('Then, you can either shut down the other process:');
|
||||||
|
@ -258,9 +265,9 @@ class TerminalReporter {
|
||||||
const he = error.hasteError;
|
const he = error.hasteError;
|
||||||
const message =
|
const message =
|
||||||
'ambiguous resolution: module `' +
|
'ambiguous resolution: module `' +
|
||||||
`${error.fromModulePath}\` tries to require \`${he.hasteName}\`, but ` +
|
`${error.fromModulePath}\` tries to require \`${he.hasteName}\`, ` +
|
||||||
`there are several files providing this module. You can delete or ` +
|
`but there are several files providing this module. You can delete ` +
|
||||||
'fix them: \n\n' +
|
'or fix them: \n\n' +
|
||||||
Object.keys(he.duplicatesSet)
|
Object.keys(he.duplicatesSet)
|
||||||
.sort()
|
.sort()
|
||||||
.map(dupFilePath => ` * \`${dupFilePath}\`\n`)
|
.map(dupFilePath => ` * \`${dupFilePath}\`\n`)
|
||||||
|
@ -269,10 +276,11 @@ class TerminalReporter {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let message = (error.snippet == null && error.stack != null)
|
let message =
|
||||||
|
error.snippet == null && error.stack != null
|
||||||
? error.stack
|
? error.stack
|
||||||
//$FlowFixMe T19379628
|
: //$FlowFixMe T19379628
|
||||||
: error.message;
|
error.message;
|
||||||
//$FlowFixMe T19379628
|
//$FlowFixMe T19379628
|
||||||
if (error.filename && !message.includes(error.filename)) {
|
if (error.filename && !message.includes(error.filename)) {
|
||||||
//$FlowFixMe T19379628
|
//$FlowFixMe T19379628
|
||||||
|
@ -305,13 +313,15 @@ class TerminalReporter {
|
||||||
* we know the `totalCount` is going to progressively increase as well. We
|
* we know the `totalCount` is going to progressively increase as well. We
|
||||||
* also prevent the ratio from going backwards.
|
* also prevent the ratio from going backwards.
|
||||||
*/
|
*/
|
||||||
_updateBundleProgress(
|
_updateBundleProgress({
|
||||||
{buildID, transformedFileCount, totalFileCount}: {
|
buildID,
|
||||||
|
transformedFileCount,
|
||||||
|
totalFileCount,
|
||||||
|
}: {
|
||||||
buildID: string,
|
buildID: string,
|
||||||
transformedFileCount: number,
|
transformedFileCount: number,
|
||||||
totalFileCount: number,
|
totalFileCount: number,
|
||||||
},
|
}) {
|
||||||
) {
|
|
||||||
const currentProgress = this._activeBundles.get(buildID);
|
const currentProgress = this._activeBundles.get(buildID);
|
||||||
if (currentProgress == null) {
|
if (currentProgress == null) {
|
||||||
return;
|
return;
|
||||||
|
@ -377,12 +387,14 @@ class TerminalReporter {
|
||||||
* different callsites overriding each other status messages.
|
* different callsites overriding each other status messages.
|
||||||
*/
|
*/
|
||||||
_getStatusMessage(): string {
|
_getStatusMessage(): string {
|
||||||
return [
|
return [this._getDepGraphStatusMessage()]
|
||||||
this._getDepGraphStatusMessage(),
|
.concat(
|
||||||
].concat(Array.from(this._activeBundles.entries()).map(
|
Array.from(this._activeBundles.entries()).map(([_, progress]) =>
|
||||||
([_, progress]) =>
|
|
||||||
this._getBundleStatusMessage(progress, 'in_progress'),
|
this._getBundleStatusMessage(progress, 'in_progress'),
|
||||||
)).filter(str => str != null).join('\n');
|
),
|
||||||
|
)
|
||||||
|
.filter(str => str != null)
|
||||||
|
.join('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -394,7 +406,6 @@ class TerminalReporter {
|
||||||
this._updateState(event);
|
this._updateState(event);
|
||||||
this.terminal.status(this._getStatusMessage());
|
this.terminal.status(this._getStatusMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = TerminalReporter;
|
module.exports = TerminalReporter;
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
*
|
*
|
||||||
* @flow
|
* @flow
|
||||||
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*
|
||||||
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
@ -15,14 +17,22 @@ const jsonStableStringify = require('json-stable-stringify');
|
||||||
const transformCache = new Map();
|
const transformCache = new Map();
|
||||||
|
|
||||||
const transformCacheKeyOf = props =>
|
const transformCacheKeyOf = props =>
|
||||||
props.filePath + '-' + crypto.createHash('md5')
|
props.filePath +
|
||||||
|
'-' +
|
||||||
|
crypto
|
||||||
|
.createHash('md5')
|
||||||
.update(props.sourceCode)
|
.update(props.sourceCode)
|
||||||
.update(props.getTransformCacheKey(props.sourceCode, props.filePath, props.transformOptions))
|
.update(
|
||||||
|
props.getTransformCacheKey(
|
||||||
|
props.sourceCode,
|
||||||
|
props.filePath,
|
||||||
|
props.transformOptions,
|
||||||
|
),
|
||||||
|
)
|
||||||
.update(jsonStableStringify(props.transformOptions || {}))
|
.update(jsonStableStringify(props.transformOptions || {}))
|
||||||
.digest('hex');
|
.digest('hex');
|
||||||
|
|
||||||
class TransformCacheMock {
|
class TransformCacheMock {
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.mock = {
|
this.mock = {
|
||||||
lastWrite: null,
|
lastWrite: null,
|
||||||
|
@ -39,9 +49,11 @@ class TransformCacheMock {
|
||||||
}
|
}
|
||||||
|
|
||||||
readSync(props) {
|
readSync(props) {
|
||||||
return {result: transformCache.get(transformCacheKeyOf(props)), outdatedDependencies: []};
|
return {
|
||||||
|
result: transformCache.get(transformCacheKeyOf(props)),
|
||||||
|
outdatedDependencies: [],
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {mocked: () => new TransformCacheMock()};
|
module.exports = {mocked: () => new TransformCacheMock()};
|
||||||
|
|
|
@ -5,7 +5,10 @@
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*
|
||||||
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
module.exports = function(declared) {
|
module.exports = function(declared) {
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*
|
||||||
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
@ -14,7 +16,6 @@ jest.useRealTimers();
|
||||||
const BatchProcessor = require('../BatchProcessor');
|
const BatchProcessor = require('../BatchProcessor');
|
||||||
|
|
||||||
describe('BatchProcessor', () => {
|
describe('BatchProcessor', () => {
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
maximumDelayMs: 500,
|
maximumDelayMs: 500,
|
||||||
maximumItems: 3,
|
maximumItems: 3,
|
||||||
|
@ -27,7 +28,10 @@ describe('BatchProcessor', () => {
|
||||||
const batches = [];
|
const batches = [];
|
||||||
let concurrency = 0;
|
let concurrency = 0;
|
||||||
let maxConcurrency = 0;
|
let maxConcurrency = 0;
|
||||||
const bp = new BatchProcessor(options, items => new Promise(resolve => {
|
const bp = new BatchProcessor(
|
||||||
|
options,
|
||||||
|
items =>
|
||||||
|
new Promise(resolve => {
|
||||||
++concurrency;
|
++concurrency;
|
||||||
expect(concurrency).toBeLessThanOrEqual(options.concurrency);
|
expect(concurrency).toBeLessThanOrEqual(options.concurrency);
|
||||||
maxConcurrency = Math.max(maxConcurrency, concurrency);
|
maxConcurrency = Math.max(maxConcurrency, concurrency);
|
||||||
|
@ -36,31 +40,38 @@ describe('BatchProcessor', () => {
|
||||||
resolve(items.map(transform));
|
resolve(items.map(transform));
|
||||||
--concurrency;
|
--concurrency;
|
||||||
}, 0);
|
}, 0);
|
||||||
}));
|
}),
|
||||||
|
);
|
||||||
const results = [];
|
const results = [];
|
||||||
await Promise.all(input.map(e => bp.queue(e).then(
|
await Promise.all(
|
||||||
|
input.map(e =>
|
||||||
|
bp.queue(e).then(
|
||||||
res => results.push(res),
|
res => results.push(res),
|
||||||
error => process.nextTick(() => { throw error; }),
|
error =>
|
||||||
)));
|
process.nextTick(() => {
|
||||||
expect(batches).toEqual([
|
throw error;
|
||||||
[1, 2, 3],
|
}),
|
||||||
[4, 5, 6],
|
),
|
||||||
[7, 8],
|
),
|
||||||
]);
|
);
|
||||||
|
expect(batches).toEqual([[1, 2, 3], [4, 5, 6], [7, 8]]);
|
||||||
expect(maxConcurrency).toEqual(options.concurrency);
|
expect(maxConcurrency).toEqual(options.concurrency);
|
||||||
expect(results).toEqual(input.map(transform));
|
expect(results).toEqual(input.map(transform));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('report errors', async () => {
|
it('report errors', async () => {
|
||||||
const error = new Error('oh noes');
|
const error = new Error('oh noes');
|
||||||
const bp = new BatchProcessor(options, items => new Promise((_, reject) => {
|
const bp = new BatchProcessor(
|
||||||
|
options,
|
||||||
|
items =>
|
||||||
|
new Promise((_, reject) => {
|
||||||
setTimeout(reject.bind(null, error), 0);
|
setTimeout(reject.bind(null, error), 0);
|
||||||
}));
|
}),
|
||||||
let receivedError;
|
|
||||||
await bp.queue('foo').catch(
|
|
||||||
err => { receivedError = err; },
|
|
||||||
);
|
);
|
||||||
|
let receivedError;
|
||||||
|
await bp.queue('foo').catch(err => {
|
||||||
|
receivedError = err;
|
||||||
|
});
|
||||||
expect(receivedError).toBe(error);
|
expect(receivedError).toBe(error);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*
|
||||||
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
@ -18,7 +20,9 @@ const {URIBasedGlobalTransformCache} = require('../GlobalTransformCache');
|
||||||
const FetchError = require('node-fetch/lib/fetch-error');
|
const FetchError = require('node-fetch/lib/fetch-error');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
async function fetchResultURIs(keys: Array<string>): Promise<Map<string, string>> {
|
async function fetchResultURIs(
|
||||||
|
keys: Array<string>,
|
||||||
|
): Promise<Map<string, string>> {
|
||||||
return new Map(keys.map(key => [key, `http://globalcache.com/${key}`]));
|
return new Map(keys.map(key => [key, `http://globalcache.com/${key}`]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +35,6 @@ async function fetchResultFromURI(uri: string): Promise<?CachedResult> {
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('GlobalTransformCache', () => {
|
describe('GlobalTransformCache', () => {
|
||||||
|
|
||||||
it('fetches results', async () => {
|
it('fetches results', async () => {
|
||||||
const cache = new URIBasedGlobalTransformCache({
|
const cache = new URIBasedGlobalTransformCache({
|
||||||
fetchResultFromURI,
|
fetchResultFromURI,
|
||||||
|
@ -53,22 +56,24 @@ describe('GlobalTransformCache', () => {
|
||||||
projectRoot: path.join(__dirname, 'root'),
|
projectRoot: path.join(__dirname, 'root'),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const result = await Promise.all([cache.fetch({
|
const result = await Promise.all([
|
||||||
|
cache.fetch({
|
||||||
localPath: 'some/where/foo.js',
|
localPath: 'some/where/foo.js',
|
||||||
sourceCode: '/* beep */',
|
sourceCode: '/* beep */',
|
||||||
getTransformCacheKey: () => 'abcd',
|
getTransformCacheKey: () => 'abcd',
|
||||||
transformOptions,
|
transformOptions,
|
||||||
}), cache.fetch({
|
}),
|
||||||
|
cache.fetch({
|
||||||
localPath: 'some/where/else/bar.js',
|
localPath: 'some/where/else/bar.js',
|
||||||
sourceCode: '/* boop */',
|
sourceCode: '/* boop */',
|
||||||
getTransformCacheKey: () => 'abcd',
|
getTransformCacheKey: () => 'abcd',
|
||||||
transformOptions,
|
transformOptions,
|
||||||
})]);
|
}),
|
||||||
|
]);
|
||||||
expect(result).toMatchSnapshot();
|
expect(result).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('fetchResultFromURI', () => {
|
describe('fetchResultFromURI', () => {
|
||||||
|
|
||||||
const defaultFetchMockImpl = async uri => ({
|
const defaultFetchMockImpl = async uri => ({
|
||||||
status: 200,
|
status: 200,
|
||||||
json: async () => ({
|
json: async () => ({
|
||||||
|
@ -84,8 +89,9 @@ describe('GlobalTransformCache', () => {
|
||||||
|
|
||||||
it('fetches result', async () => {
|
it('fetches result', async () => {
|
||||||
mockFetch.mockImplementation(defaultFetchMockImpl);
|
mockFetch.mockImplementation(defaultFetchMockImpl);
|
||||||
const result = await URIBasedGlobalTransformCache
|
const result = await URIBasedGlobalTransformCache.fetchResultFromURI(
|
||||||
.fetchResultFromURI('http://globalcache.com/foo');
|
'http://globalcache.com/foo',
|
||||||
|
);
|
||||||
expect(result).toMatchSnapshot();
|
expect(result).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -94,11 +100,10 @@ describe('GlobalTransformCache', () => {
|
||||||
mockFetch.mockImplementation(defaultFetchMockImpl);
|
mockFetch.mockImplementation(defaultFetchMockImpl);
|
||||||
throw new FetchError('timeout!', 'request-timeout');
|
throw new FetchError('timeout!', 'request-timeout');
|
||||||
});
|
});
|
||||||
const result = await URIBasedGlobalTransformCache
|
const result = await URIBasedGlobalTransformCache.fetchResultFromURI(
|
||||||
.fetchResultFromURI('http://globalcache.com/foo');
|
'http://globalcache.com/foo',
|
||||||
|
);
|
||||||
expect(result).toMatchSnapshot();
|
expect(result).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*
|
||||||
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
@ -12,10 +14,13 @@
|
||||||
jest.mock('readline', () => ({
|
jest.mock('readline', () => ({
|
||||||
moveCursor: (stream, dx, dy) => {
|
moveCursor: (stream, dx, dy) => {
|
||||||
const {cursor, columns} = stream;
|
const {cursor, columns} = stream;
|
||||||
stream.cursor = Math.max(cursor - cursor % columns, cursor + dx) + dy * columns;
|
stream.cursor =
|
||||||
|
Math.max(cursor - cursor % columns, cursor + dx) + dy * columns;
|
||||||
},
|
},
|
||||||
clearLine: (stream, dir) => {
|
clearLine: (stream, dir) => {
|
||||||
if (dir !== 0) {throw new Error('unsupported');}
|
if (dir !== 0) {
|
||||||
|
throw new Error('unsupported');
|
||||||
|
}
|
||||||
const {cursor, columns} = stream;
|
const {cursor, columns} = stream;
|
||||||
const curLine = cursor - cursor % columns;
|
const curLine = cursor - cursor % columns;
|
||||||
const nextLine = curLine + columns;
|
const nextLine = curLine + columns;
|
||||||
|
@ -26,7 +31,6 @@ jest.mock('readline', () => ({
|
||||||
}));
|
}));
|
||||||
|
|
||||||
describe('Terminal', () => {
|
describe('Terminal', () => {
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.resetModules();
|
jest.resetModules();
|
||||||
});
|
});
|
||||||
|
@ -46,7 +50,7 @@ describe('Terminal', () => {
|
||||||
write(str) {
|
write(str) {
|
||||||
for (let i = 0; i < str.length; ++i) {
|
for (let i = 0; i < str.length; ++i) {
|
||||||
if (str[i] === '\n') {
|
if (str[i] === '\n') {
|
||||||
this.cursor = this.cursor - (this.cursor % columns) + columns;
|
this.cursor = this.cursor - this.cursor % columns + columns;
|
||||||
} else {
|
} else {
|
||||||
this.buffer[this.cursor] = str[i];
|
this.buffer[this.cursor] = str[i];
|
||||||
++this.cursor;
|
++this.cursor;
|
||||||
|
@ -81,10 +85,14 @@ describe('Terminal', () => {
|
||||||
terminal.status('status2');
|
terminal.status('status2');
|
||||||
terminal.log('bar');
|
terminal.log('bar');
|
||||||
jest.runAllTimers();
|
jest.runAllTimers();
|
||||||
expect(stream.buffer.join('').trim()).toEqual('foo bar status2');
|
expect(stream.buffer.join('').trim()).toEqual(
|
||||||
|
'foo bar status2',
|
||||||
|
);
|
||||||
terminal.log('beep');
|
terminal.log('beep');
|
||||||
jest.runAllTimers();
|
jest.runAllTimers();
|
||||||
expect(stream.buffer.join('').trim()).toEqual('foo bar beep status2');
|
expect(stream.buffer.join('').trim()).toEqual(
|
||||||
|
'foo bar beep status2',
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('updates status when logging, multi-line', () => {
|
it('updates status when logging, multi-line', () => {
|
||||||
|
@ -93,8 +101,9 @@ describe('Terminal', () => {
|
||||||
terminal.status('status\nanother');
|
terminal.status('status\nanother');
|
||||||
terminal.log('bar');
|
terminal.log('bar');
|
||||||
jest.runAllTimers();
|
jest.runAllTimers();
|
||||||
expect(stream.buffer.join('').trim())
|
expect(stream.buffer.join('').trim()).toEqual(
|
||||||
.toEqual('foo bar status another');
|
'foo bar status another',
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('persists status', () => {
|
it('persists status', () => {
|
||||||
|
@ -106,5 +115,4 @@ describe('Terminal', () => {
|
||||||
jest.runAllTimers();
|
jest.runAllTimers();
|
||||||
expect(stream.buffer.join('').trim()).toEqual('foo status bar');
|
expect(stream.buffer.join('').trim()).toEqual('foo status bar');
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*
|
||||||
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
@ -43,13 +45,14 @@ function cartesianProductOf(a1, a2) {
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('TransformCaching.FileBasedCache', () => {
|
describe('TransformCaching.FileBasedCache', () => {
|
||||||
|
|
||||||
let transformCache;
|
let transformCache;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.resetModules();
|
jest.resetModules();
|
||||||
mockFS.clear();
|
mockFS.clear();
|
||||||
transformCache = new (require('../TransformCaching').FileBasedCache)('/cache');
|
transformCache = new (require('../TransformCaching')).FileBasedCache(
|
||||||
|
'/cache',
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('is caching different files and options separately', () => {
|
it('is caching different files and options separately', () => {
|
||||||
|
@ -60,8 +63,10 @@ describe('TransformCaching.FileBasedCache', () => {
|
||||||
getTransformCacheKey: () => 'abcdef',
|
getTransformCacheKey: () => 'abcdef',
|
||||||
filePath,
|
filePath,
|
||||||
transformOptions,
|
transformOptions,
|
||||||
transformOptionsKey: crypto.createHash('md5')
|
transformOptionsKey: crypto
|
||||||
.update(jsonStableStringify(transformOptions)).digest('hex'),
|
.createHash('md5')
|
||||||
|
.update(jsonStableStringify(transformOptions))
|
||||||
|
.digest('hex'),
|
||||||
result: {
|
result: {
|
||||||
code: `/* result for ${key} */`,
|
code: `/* result for ${key} */`,
|
||||||
dependencies: ['foo', `dep of ${key}`],
|
dependencies: ['foo', `dep of ${key}`],
|
||||||
|
@ -74,9 +79,7 @@ describe('TransformCaching.FileBasedCache', () => {
|
||||||
['/some/project/sub/dir/file.js', '/some/project/other.js'],
|
['/some/project/sub/dir/file.js', '/some/project/other.js'],
|
||||||
[{foo: 1}, {foo: 2}],
|
[{foo: 1}, {foo: 2}],
|
||||||
);
|
);
|
||||||
allCases.forEach(
|
allCases.forEach(entry => transformCache.writeSync(argsFor(entry)));
|
||||||
entry => transformCache.writeSync(argsFor(entry)),
|
|
||||||
);
|
|
||||||
allCases.forEach(entry => {
|
allCases.forEach(entry => {
|
||||||
const args = argsFor(entry);
|
const args = argsFor(entry);
|
||||||
const {result} = args;
|
const {result} = args;
|
||||||
|
@ -129,5 +132,4 @@ describe('TransformCaching.FileBasedCache', () => {
|
||||||
expect(cachedResult.outdatedDependencies).toEqual(['foo', 'bar']);
|
expect(cachedResult.outdatedDependencies).toEqual(['foo', 'bar']);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,7 +5,10 @@
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*
|
||||||
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var _ = require('lodash');
|
var _ = require('lodash');
|
||||||
|
@ -82,12 +85,20 @@ function formatBanner(message, options) {
|
||||||
|
|
||||||
var horizontalBorderLine = repeatString(
|
var horizontalBorderLine = repeatString(
|
||||||
HORIZONTAL_LINE,
|
HORIZONTAL_LINE,
|
||||||
width - marginLeft - marginRight - 2
|
width - marginLeft - marginRight - 2,
|
||||||
);
|
);
|
||||||
var top = spaces(marginLeft) + TOP_LEFT + horizontalBorderLine + TOP_RIGHT +
|
var top =
|
||||||
|
spaces(marginLeft) +
|
||||||
|
TOP_LEFT +
|
||||||
|
horizontalBorderLine +
|
||||||
|
TOP_RIGHT +
|
||||||
|
spaces(marginRight);
|
||||||
|
var bottom =
|
||||||
|
spaces(marginLeft) +
|
||||||
|
BOTTOM_LEFT +
|
||||||
|
horizontalBorderLine +
|
||||||
|
BOTTOM_RIGHT +
|
||||||
spaces(marginRight);
|
spaces(marginRight);
|
||||||
var bottom = spaces(marginLeft) + BOTTOM_LEFT + horizontalBorderLine +
|
|
||||||
BOTTOM_RIGHT + spaces(marginRight);
|
|
||||||
return _.flattenDeep([top, bodyLines, bottom]).join('\n');
|
return _.flattenDeep([top, bodyLines, bottom]).join('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
*
|
*
|
||||||
* @flow
|
* @flow
|
||||||
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
@ -17,7 +18,10 @@ const {isMappingsMap} = require('./SourceMap');
|
||||||
|
|
||||||
import type {SourceMap} from './SourceMap';
|
import type {SourceMap} from './SourceMap';
|
||||||
|
|
||||||
function relativizeSourceMapInternal(sourceMap: SourceMap, sourcesRoot: string) {
|
function relativizeSourceMapInternal(
|
||||||
|
sourceMap: SourceMap,
|
||||||
|
sourcesRoot: string,
|
||||||
|
) {
|
||||||
if (!isMappingsMap(sourceMap)) {
|
if (!isMappingsMap(sourceMap)) {
|
||||||
for (let i = 0; i < sourceMap.sections.length; i++) {
|
for (let i = 0; i < sourceMap.sections.length; i++) {
|
||||||
relativizeSourceMapInternal(sourceMap.sections[i].map, sourcesRoot);
|
relativizeSourceMapInternal(sourceMap.sections[i].map, sourcesRoot);
|
||||||
|
@ -29,7 +33,10 @@ function relativizeSourceMapInternal(sourceMap: SourceMap, sourcesRoot: string)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function relativizeSourceMap(sourceMap: SourceMap, sourcesRoot?: string): SourceMap {
|
function relativizeSourceMap(
|
||||||
|
sourceMap: SourceMap,
|
||||||
|
sourcesRoot?: string,
|
||||||
|
): SourceMap {
|
||||||
if (!sourcesRoot) {
|
if (!sourcesRoot) {
|
||||||
return sourceMap;
|
return sourceMap;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
*
|
*
|
||||||
* @flow
|
* @flow
|
||||||
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
@ -23,53 +24,68 @@ export type GlobalCacheDisabledReason = 'too_many_errors' | 'too_many_misses';
|
||||||
* A tagged union of all the actions that may happen and we may want to
|
* A tagged union of all the actions that may happen and we may want to
|
||||||
* report to the tool user.
|
* report to the tool user.
|
||||||
*/
|
*/
|
||||||
export type ReportableEvent = {
|
export type ReportableEvent =
|
||||||
|
| {
|
||||||
port: number,
|
port: number,
|
||||||
projectRoots: $ReadOnlyArray<string>,
|
projectRoots: $ReadOnlyArray<string>,
|
||||||
type: 'initialize_packager_started',
|
type: 'initialize_packager_started',
|
||||||
} | {
|
}
|
||||||
|
| {
|
||||||
type: 'initialize_packager_done',
|
type: 'initialize_packager_done',
|
||||||
} | {
|
}
|
||||||
|
| {
|
||||||
type: 'initialize_packager_failed',
|
type: 'initialize_packager_failed',
|
||||||
port: number,
|
port: number,
|
||||||
error: Error,
|
error: Error,
|
||||||
} | {
|
}
|
||||||
|
| {
|
||||||
buildID: string,
|
buildID: string,
|
||||||
type: 'bundle_build_done',
|
type: 'bundle_build_done',
|
||||||
} | {
|
}
|
||||||
|
| {
|
||||||
buildID: string,
|
buildID: string,
|
||||||
type: 'bundle_build_failed',
|
type: 'bundle_build_failed',
|
||||||
} | {
|
}
|
||||||
|
| {
|
||||||
buildID: string,
|
buildID: string,
|
||||||
bundleOptions: BundleOptions,
|
bundleOptions: BundleOptions,
|
||||||
type: 'bundle_build_started',
|
type: 'bundle_build_started',
|
||||||
} | {
|
}
|
||||||
|
| {
|
||||||
error: Error,
|
error: Error,
|
||||||
type: 'bundling_error',
|
type: 'bundling_error',
|
||||||
} | {
|
}
|
||||||
|
| {
|
||||||
type: 'dep_graph_loading',
|
type: 'dep_graph_loading',
|
||||||
} | {
|
}
|
||||||
|
| {
|
||||||
type: 'dep_graph_loaded',
|
type: 'dep_graph_loaded',
|
||||||
} | {
|
}
|
||||||
|
| {
|
||||||
buildID: string,
|
buildID: string,
|
||||||
type: 'bundle_transform_progressed',
|
type: 'bundle_transform_progressed',
|
||||||
transformedFileCount: number,
|
transformedFileCount: number,
|
||||||
totalFileCount: number,
|
totalFileCount: number,
|
||||||
} | {
|
}
|
||||||
|
| {
|
||||||
type: 'global_cache_error',
|
type: 'global_cache_error',
|
||||||
error: Error,
|
error: Error,
|
||||||
} | {
|
}
|
||||||
|
| {
|
||||||
type: 'global_cache_disabled',
|
type: 'global_cache_disabled',
|
||||||
reason: GlobalCacheDisabledReason,
|
reason: GlobalCacheDisabledReason,
|
||||||
} | {
|
}
|
||||||
|
| {
|
||||||
type: 'transform_cache_reset',
|
type: 'transform_cache_reset',
|
||||||
} | {
|
}
|
||||||
|
| {
|
||||||
type: 'worker_stdout_chunk',
|
type: 'worker_stdout_chunk',
|
||||||
chunk: string,
|
chunk: string,
|
||||||
} | {
|
}
|
||||||
|
| {
|
||||||
type: 'worker_stderr_chunk',
|
type: 'worker_stderr_chunk',
|
||||||
chunk: string,
|
chunk: string,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Code across the application takes a reporter as an option and calls the
|
* Code across the application takes a reporter as an option and calls the
|
||||||
|
@ -99,7 +115,11 @@ export type Reporter = {
|
||||||
* calling this, add a new type of ReportableEvent instead, and implement a
|
* calling this, add a new type of ReportableEvent instead, and implement a
|
||||||
* proper handler in the reporter(s).
|
* proper handler in the reporter(s).
|
||||||
*/
|
*/
|
||||||
function logWarning(terminal: Terminal, format: string, ...args: Array<mixed>): void {
|
function logWarning(
|
||||||
|
terminal: Terminal,
|
||||||
|
format: string,
|
||||||
|
...args: Array<mixed>
|
||||||
|
): void {
|
||||||
const str = util.format(format, ...args);
|
const str = util.format(format, ...args);
|
||||||
terminal.log('%s: %s', chalk.yellow('warning'), str);
|
terminal.log('%s: %s', chalk.yellow('warning'), str);
|
||||||
}
|
}
|
||||||
|
@ -107,7 +127,11 @@ function logWarning(terminal: Terminal, format: string, ...args: Array<mixed>):
|
||||||
/**
|
/**
|
||||||
* Similar to `logWarning`, but for messages that require the user to act.
|
* Similar to `logWarning`, but for messages that require the user to act.
|
||||||
*/
|
*/
|
||||||
function logError(terminal: Terminal, format: string, ...args: Array<mixed>): void {
|
function logError(
|
||||||
|
terminal: Terminal,
|
||||||
|
format: string,
|
||||||
|
...args: Array<mixed>
|
||||||
|
): void {
|
||||||
const str = util.format(format, ...args);
|
const str = util.format(format, ...args);
|
||||||
terminal.log('%s: %s', chalk.red('error'), str);
|
terminal.log('%s: %s', chalk.red('error'), str);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
*
|
*
|
||||||
* @flow
|
* @flow
|
||||||
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
Loading…
Reference in New Issue