Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add 'IdentifierRegistry' mechanism for debugging IDs #333

Merged
5 changes: 4 additions & 1 deletion packages/core/core/src/Dependency.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
import {toInternalSourceLocation} from './utils';
import {toProjectPath} from './projectPath';
import assert from 'assert';
import {identifierRegistry} from './IdentifierRegistry';

type DependencyOpts = {|
id?: string,
Expand Down Expand Up @@ -80,7 +81,9 @@ export function createDependencyId({
priority: priority ? Priority[priority] : Priority.sync,
packageConditions,
};
return createDependencyIdRust(params);
const id = createDependencyIdRust(params);
identifierRegistry.addIdentifier('dependency', id, params);
return id;
}

export function createDependency(
Expand Down
8 changes: 6 additions & 2 deletions packages/core/core/src/Environment.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {createEnvironmentId} from '@atlaspack/rust';
import {toInternalSourceLocation} from './utils';
import PublicEnvironment from './public/Environment';
import {environmentToInternalEnvironment} from './public/Environment';
import {identifierRegistry} from './IdentifierRegistry';

const DEFAULT_ENGINES = {
browsers: ['> 0.25%'],
Expand Down Expand Up @@ -137,7 +138,7 @@ export function mergeEnvironments(
}

function getEnvironmentHash(env: Environment): string {
return createEnvironmentId({
const data = {
context: env.context,
engines: env.engines,
includeNodeModules: env.includeNodeModules,
Expand All @@ -147,5 +148,8 @@ function getEnvironmentHash(env: Environment): string {
shouldOptimize: env.shouldOptimize,
shouldScopeHoist: env.shouldScopeHoist,
sourceMap: env.sourceMap,
});
};
const id = createEnvironmentId(data);
identifierRegistry.addIdentifier('environment', id, data);
return id;
}
32 changes: 32 additions & 0 deletions packages/core/core/src/IdentifierRegistry.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// @flow strict-local

import fs from 'fs';

export class IdentifierRegistry {
#enabled: boolean;
#createdDirectory: boolean = false;

constructor(enabled: boolean) {
this.#enabled = enabled;
}

addIdentifier(type: string, identifier: string, data: mixed) {
if (this.#enabled) {
if (!this.#createdDirectory) {
fs.mkdirSync('./.atlaspack', {recursive: true});
this.#createdDirectory = true;
}

fs.appendFile(
'./.atlaspack/atlaspack-identifiers.txt',
// $FlowFixMe
`${type} ${identifier} ${JSON.stringify(data)}\n`,
() => {},
);
}
}
}

export const identifierRegistry: IdentifierRegistry = new IdentifierRegistry(
process.env.ATLASPACK_IDENTIFIER_DEBUG === 'true',
);
8 changes: 6 additions & 2 deletions packages/core/core/src/assetUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import {
import {hashString, createAssetId as createAssetIdRust} from '@atlaspack/rust';
import {BundleBehavior as BundleBehaviorMap} from './types';
import {PluginTracer} from '@atlaspack/profiler';
import {identifierRegistry} from './IdentifierRegistry';

export type AssetOptions = {|
id?: string,
Expand Down Expand Up @@ -69,15 +70,18 @@ export type AssetOptions = {|
|};

export function createAssetIdFromOptions(options: AssetOptions): string {
return createAssetIdRust({
const data = {
environmentId: options.env.id,
filePath: options.filePath,
code: options.code,
pipeline: options.pipeline,
query: options.query,
uniqueKey: options.uniqueKey,
fileType: options.type,
});
};
const id = createAssetIdRust(data);
identifierRegistry.addIdentifier('asset', id, data);
return id;
}

export function createAsset(
Expand Down
30 changes: 24 additions & 6 deletions packages/core/core/src/public/MutableBundleGraph.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,24 @@ import {HASH_REF_PREFIX} from '../constants';
import {fromProjectPathRelative} from '../projectPath';
import {BundleBehavior} from '../types';
import BundleGroup, {bundleGroupToInternalBundleGroup} from './BundleGroup';
import type {ProjectPath} from '../projectPath';
import {identifierRegistry} from '../IdentifierRegistry';

function createBundleId(data: {|
entryAssetId: string | null,
uniqueKey: string | null,
distDir: ProjectPath,
bundleBehavior: string | null,
|}): string {
const {entryAssetId, uniqueKey, distDir, bundleBehavior} = data;
const id = hashString(
`bundle:${String(
entryAssetId != null ? entryAssetId : uniqueKey,
)}${fromProjectPathRelative(distDir)}${bundleBehavior ?? ''}`,
);
identifierRegistry.addIdentifier('bundle', id, data);
return id;
}

export default class MutableBundleGraph
extends BundleGraph<IBundle>
Expand Down Expand Up @@ -181,12 +199,12 @@ export default class MutableBundleGraph
: null;

let target = targetToInternalTarget(opts.target);
let bundleId = hashString(
'bundle:' +
(opts.entryAsset ? opts.entryAsset.id : opts.uniqueKey) +
fromProjectPathRelative(target.distDir) +
(opts.bundleBehavior ?? ''),
);
let bundleId = createBundleId({
entryAssetId: entryAsset?.id ?? null,
uniqueKey: opts.uniqueKey ?? null,
distDir: target.distDir,
bundleBehavior: opts.bundleBehavior ?? null,
});

let existing = this.#graph._graph.getNodeByContentKey(bundleId);
if (existing != null) {
Expand Down
64 changes: 64 additions & 0 deletions packages/core/core/test/IdentifierRegistry.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// @flow strict-local

import assert from 'assert';
import fs from 'fs';
import sinon from 'sinon';
import {IdentifierRegistry} from '../src/IdentifierRegistry';

describe('IdentifierRegistry', () => {
let mkdirSyncStub;
let fsStub;

beforeEach(() => {
mkdirSyncStub = sinon.stub(fs, 'mkdirSync');
fsStub = sinon.stub(fs, 'appendFile');
});

afterEach(() => {
mkdirSyncStub.restore();
fsStub.restore();
});

it("does nothing if the identifers flag isn't set", () => {
const identifierRegistry = new IdentifierRegistry(false);
identifierRegistry.addIdentifier('type', 'identifier', 'data');
assert(!mkdirSyncStub.called);
assert(!fsStub.called);
});

it('appends the identifier to the file', () => {
const identifierRegistry = new IdentifierRegistry(true);
identifierRegistry.addIdentifier('type', 'identifier', 'data');
assert(
fsStub.calledWith(
'./.atlaspack/atlaspack-identifiers.txt',
'type identifier "data"\n',
sinon.match.func,
),
);
});

it('only creates the directory once', () => {
const identifierRegistry = new IdentifierRegistry(true);
identifierRegistry.addIdentifier('type', 'identifier', '1');
identifierRegistry.addIdentifier('type', 'identifier', '2');

assert(mkdirSyncStub.calledOnce);

assert(mkdirSyncStub.calledWith('./.atlaspack', {recursive: true}));
assert(
fsStub.calledWith(
'./.atlaspack/atlaspack-identifiers.txt',
'type identifier "1"\n',
sinon.match.func,
),
);
assert(
fsStub.calledWith(
'./.atlaspack/atlaspack-identifiers.txt',
'type identifier "2"\n',
sinon.match.func,
),
);
});
});