refactor(manager/pip-compile): Move topological sort to utils (#27398)

This commit is contained in:
Norbert Szulc 2024-02-19 13:43:34 +01:00 committed by GitHub
parent 1ffa44c4fe
commit 82651110a0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 38 additions and 28 deletions

View file

@ -1,4 +1,3 @@
import { Graph } from 'graph-data-structure';
import { logger } from '../../../logger';
import { readLocalFile } from '../../../util/fs';
import { normalizeDepName } from '../../datasource/pypi/common';
@ -11,7 +10,7 @@ import type {
PipCompileArgs,
SupportedManagers,
} from './types';
import { generateMermaidGraph } from './utils';
import { generateMermaidGraph, sortPackageFiles } from './utils';
function matchManager(filename: string): SupportedManagers | 'unknown' {
if (filename.endsWith('setup.py')) {
@ -178,32 +177,10 @@ export async function extractAllPackageFiles(
if (packageFiles.size === 0) {
return null;
}
const result: PackageFile[] = [];
const graph: ReturnType<typeof Graph> = Graph();
depsBetweenFiles.forEach(({ sourceFile, outputFile }) => {
graph.addEdge(sourceFile, outputFile);
});
const sorted = graph.topologicalSort();
for (const file of sorted) {
if (packageFiles.has(file)) {
const packageFile = packageFiles.get(file)!;
const sortedLockFiles = [];
// TODO(not7cd): this needs better test case
for (const lockFile of packageFile.lockFiles!) {
if (sorted.includes(lockFile)) {
sortedLockFiles.push(lockFile);
}
}
packageFile.lockFiles = sortedLockFiles;
result.push(packageFile);
}
}
// istanbul ignore if: should never happen
if (result.length !== packageFiles.size) {
throw new Error(
'pip-compile: topological sort failed to include all package files',
const result: PackageFile[] = sortPackageFiles(
depsBetweenFiles,
packageFiles,
);
}
logger.debug(
'pip-compile: dependency graph:\n' +
generateMermaidGraph(depsBetweenFiles, lockFileArgs),

View file

@ -1,5 +1,38 @@
import { Graph } from 'graph-data-structure';
import type { PackageFile } from '../types';
import type { DependencyBetweenFiles, PipCompileArgs } from './types';
export function sortPackageFiles(
depsBetweenFiles: DependencyBetweenFiles[],
packageFiles: Map<string, PackageFile>,
): PackageFile[] {
const result: PackageFile[] = [];
const graph: ReturnType<typeof Graph> = Graph();
depsBetweenFiles.forEach(({ sourceFile, outputFile }) => {
graph.addEdge(sourceFile, outputFile);
});
const sorted = graph.topologicalSort();
for (const file of sorted) {
if (packageFiles.has(file)) {
const packageFile = packageFiles.get(file)!;
const sortedLockFiles = [];
// TODO(not7cd): this needs better test case
for (const lockFile of packageFile.lockFiles!) {
if (sorted.includes(lockFile)) {
sortedLockFiles.push(lockFile);
}
}
packageFile.lockFiles = sortedLockFiles;
result.push(packageFile);
}
}
// istanbul ignore if: should never happen
if (result.length !== packageFiles.size) {
throw new Error('Topological sort failed to include all package files');
}
return result;
}
export function generateMermaidGraph(
depsBetweenFiles: DependencyBetweenFiles[],
lockFileArgs: Map<string, PipCompileArgs>,