Fix edge case of moving a haste file to a different folder

Reviewed By: davidaurelio

Differential Revision: D5945574

fbshipit-source-id: 5fdd12c0af1b7a92012f4be71ce18f44e42ad4e1
This commit is contained in:
Jean Lauliac 2017-10-05 04:45:46 -07:00 committed by Facebook Github Bot
parent e235f6a9fd
commit 1349edad70
2 changed files with 54 additions and 36 deletions

View File

@ -189,4 +189,22 @@ describe('edge cases', () => {
deleted: new Set(['/baz']), deleted: new Set(['/baz']),
}); });
}); });
it('move a file to a different folder', async () => {
const edges = new Map();
await initialTraverseDependencies('/bundle', dependencyGraph, {}, edges);
const moduleBazMoved = createModule({path: '/baz-moved', name: 'baz'});
mockedDependencyTree.set(moduleFoo.path, [moduleBar, moduleBazMoved]);
mockedDependencies.add(moduleBazMoved);
mockedDependencies.delete(moduleBaz);
// Modify /baz, rename it to /qux and modify it again.
expect(
await traverseDependencies(['/foo'], dependencyGraph, {}, edges),
).toEqual({
added: new Set(['/baz-moved']),
deleted: new Set(['/baz']),
});
});
}); });

View File

@ -108,27 +108,45 @@ async function traverseDependenciesForSingleFile(
return {added: new Set(), deleted: new Set()}; return {added: new Set(), deleted: new Set()};
} }
const currentDependencies = new Set( // Get the absolute path of all sub-dependencies (some of them could have been
// moved but maintain the same relative path).
const currentDependencies = resolveDependencies(
path,
await dependencyGraph.getShallowDependencies(path, transformOptions), await dependencyGraph.getShallowDependencies(path, transformOptions),
dependencyGraph,
transformOptions,
); );
const previousDependencies = new Set(edge.dependencies.keys());
const previousDependencies = new Set(edge.dependencies.values());
const nonNullEdge = edge; const nonNullEdge = edge;
let numProcessed = 0; let numProcessed = 0;
let total = currentDependencies.size; let total = currentDependencies.size;
const deleted = Array.from(edge.dependencies.entries())
.map(([relativePath, absolutePath]) => {
if (!currentDependencies.has(absolutePath)) {
return removeDependency(nonNullEdge, relativePath, edges);
} else {
return undefined;
}
})
.filter(Boolean);
// Check all the module dependencies and start traversing the tree from each // Check all the module dependencies and start traversing the tree from each
// added and removed dependency, to get all the modules that have to be added // added and removed dependency, to get all the modules that have to be added
// and removed from the dependency graph. // and removed from the dependency graph.
const added = await Promise.all( const added = await Promise.all(
Array.from(currentDependencies).map(async dependency => { Array.from(
currentDependencies,
).map(async ([absolutePath, relativePath]) => {
let newDependencies; let newDependencies;
if (!previousDependencies.has(dependency)) { if (!previousDependencies.has(absolutePath)) {
newDependencies = await addDependency( newDependencies = await addDependency(
nonNullEdge, nonNullEdge,
dependency, relativePath,
dependencyGraph, dependencyGraph,
transformOptions, transformOptions,
edges, edges,
@ -149,26 +167,6 @@ async function traverseDependenciesForSingleFile(
}), }),
); );
// Check if all currentDependencies are still in the bundle (some files can
// have been removed).
checkModuleDependencies(
path,
currentDependencies,
dependencyGraph,
transformOptions,
edges,
);
const deleted = Array.from(previousDependencies)
.map(dependency => {
if (!currentDependencies.has(dependency)) {
return removeDependency(nonNullEdge, dependency, edges);
} else {
return undefined;
}
})
.filter(Boolean);
return { return {
added: flatten(added), added: flatten(added),
deleted: flatten(deleted), deleted: flatten(deleted),
@ -311,22 +309,24 @@ function resolveEdge(
return edges.get(absolutePath); return edges.get(absolutePath);
} }
function checkModuleDependencies( function resolveDependencies(
parentPath, parentPath,
dependencies: Set<string>, dependencies: Array<string>,
dependencyGraph: DependencyGraph, dependencyGraph: DependencyGraph,
transformOptions: JSTransformerOptions, transformOptions: JSTransformerOptions,
edges: DependencyEdges, ): Map<string, string> {
) {
const parentModule = dependencyGraph.getModuleForPath(parentPath); const parentModule = dependencyGraph.getModuleForPath(parentPath);
for (const dependency of dependencies.values()) { return new Map(
dependencyGraph.resolveDependency( dependencies.map(relativePath => [
parentModule, dependencyGraph.resolveDependency(
dependency, parentModule,
transformOptions.platform, relativePath,
); transformOptions.platform,
} ).path,
relativePath,
]),
);
} }
function flatten<T>(input: Iterable<Iterable<T>>): Set<T> { function flatten<T>(input: Iterable<Iterable<T>>): Set<T> {