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

feat: store dependencies graph in component model #9214

Open
wants to merge 121 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 107 commits
Commits
Show all changes
121 commits
Select commit Hold shift + click to select a range
3f7d624
feat: add dependenciesGraph to the model
zkochan Sep 23, 2024
6c129b3
feat: add deps graph to the model
zkochan Sep 24, 2024
77779c5
fix: save dependenciesGraphRef
zkochan Sep 24, 2024
9952238
feat: deps graph in comp model
zkochan Sep 25, 2024
cfc5c19
feat: read lockfile from model on sign
zkochan Sep 26, 2024
7a01886
fix: read dependencies graph from root components
zkochan Oct 1, 2024
30d52e5
test: deps graph
zkochan Oct 4, 2024
f450ea1
test: deps graph
zkochan Oct 4, 2024
d701084
fix: installing from generated lockfile
zkochan Oct 7, 2024
4074f5a
save dev deps in dependency graph
zkochan Oct 8, 2024
b172534
fix: generate the correct lockfile after capsules dedupe
zkochan Oct 9, 2024
c968a38
test: snapping multiple components
zkochan Oct 10, 2024
4a34cbe
test: signing a component with dependencies graph
zkochan Oct 10, 2024
3bac3b7
Merge remote-tracking branch 'origin/master' into store-deps-graph
zkochan Oct 11, 2024
c317508
test: lockfile used by sign is written by bit
zkochan Oct 11, 2024
d6b34f9
feat: generate lockfile on import
zkochan Oct 14, 2024
0a33536
test: generating a lockfile on import
zkochan Oct 14, 2024
76af54f
test: run local registry
zkochan Oct 14, 2024
17be0dd
test: deps are not updated
zkochan Oct 15, 2024
f9c4463
test: merging dependency graphs
zkochan Oct 15, 2024
0d38327
fix: mergin dep graphs
zkochan Oct 15, 2024
eecee4d
feat: properly resolve dependencies with peer dependencies
zkochan Oct 16, 2024
88fdc7b
test: publishing to registry
zkochan Oct 16, 2024
c13c229
test: imported component is not installed as a package dep
zkochan Oct 17, 2024
b983c67
test: fix
zkochan Oct 17, 2024
49acf81
test: importing component
zkochan Oct 17, 2024
87cbb8c
fix: don't fail on empty graph
zkochan Oct 18, 2024
a522d40
feat: updating package integrities on tag from scope
zkochan Oct 18, 2024
f6338da
fix: optimize the deps graph format saved in the model
zkochan Oct 21, 2024
aa38916
fix: replacing pending versions
zkochan Oct 28, 2024
24a0193
replace integrities in the model
zkochan Oct 29, 2024
d6903c3
test: fix
zkochan Oct 29, 2024
aebbce3
feat: add lockfile converter
zkochan Oct 29, 2024
0a505a5
test: converting the lockfile
zkochan Oct 29, 2024
488ff5d
test: fix
zkochan Oct 29, 2024
81ac9c8
test: fix
zkochan Oct 30, 2024
18cc929
test: fix
zkochan Oct 30, 2024
ca8e425
feat: add component ID to dep graph
zkochan Oct 30, 2024
48388de
refactor: types
zkochan Oct 31, 2024
fa239cd
fix: converting lockfile to graph
zkochan Oct 31, 2024
acbde62
fix: replace file deps in direct deps
zkochan Nov 4, 2024
29fb0ad
refactor: change direct deps data structure
zkochan Nov 4, 2024
f7bfd96
test: fix
zkochan Nov 5, 2024
d40865a
feat: add deps-graph feature flag
zkochan Nov 5, 2024
b8e8995
fix: update pnpm
zkochan Nov 6, 2024
20acc56
Merge remote-tracking branch 'origin/master' into store-deps-graph
zkochan Nov 6, 2024
0afa437
fix: compile
zkochan Nov 6, 2024
d1fe382
fix: types
zkochan Nov 6, 2024
0db3c10
fix: types
zkochan Nov 6, 2024
099ed91
style: fix
zkochan Nov 6, 2024
0066a70
test: fix
zkochan Nov 6, 2024
bf0b921
test: fix
zkochan Nov 6, 2024
86ff144
fix: move deps to package.json
zkochan Nov 6, 2024
7a1d727
remove commented code
zkochan Nov 6, 2024
fc0209e
test: fix
zkochan Nov 6, 2024
98bf497
test: fix
zkochan Nov 6, 2024
763db45
test: fix
zkochan Nov 6, 2024
2e5ec64
always write the deps graph data to the model
zkochan Nov 6, 2024
a270851
Merge branch 'master' into store-deps-graph
zkochan Nov 6, 2024
95bdef9
refactor: apply suggestions from the code review
zkochan Nov 7, 2024
998335a
Merge remote-tracking branch 'origin/master' into store-deps-graph
zkochan Nov 11, 2024
9046990
fix: compile
zkochan Nov 11, 2024
f88b8ae
refactor: apply suggestions from the code review
zkochan Nov 11, 2024
b75f99c
refactor: apply suggestions from the code review
zkochan Nov 11, 2024
b45dd47
refactor: apply suggestions from the code review
zkochan Nov 11, 2024
0c2fe71
refactor: apply suggestions from the code review
zkochan Nov 11, 2024
631cae0
refactor: apply suggestions from the code review
zkochan Nov 11, 2024
fed2b00
refactor: graph
zkochan Nov 11, 2024
73cb5c3
refactor: implement suggestions
zkochan Nov 12, 2024
0187a76
refactor: implement suggestions
zkochan Nov 12, 2024
ae3f4c2
refactor: dependencies graph
zkochan Nov 13, 2024
f6c45bc
refactor: dependencies graph
zkochan Nov 13, 2024
1934ef3
test: fix
zkochan Nov 14, 2024
2300757
style: fix
zkochan Nov 14, 2024
40396b9
Merge remote-tracking branch 'origin/master' into store-deps-graph
zkochan Nov 14, 2024
cb5b390
test: fix
zkochan Nov 14, 2024
aab84fd
test: fix
zkochan Nov 15, 2024
d57aa09
style: fix
zkochan Nov 15, 2024
671069f
fix: build
zkochan Nov 18, 2024
fa21dc6
Merge remote-tracking branch 'origin/master' into store-deps-graph
zkochan Nov 18, 2024
6e83e65
refactor: implement suggestions
zkochan Nov 18, 2024
7b83856
fix: types
zkochan Nov 18, 2024
b775dd1
Merge remote-tracking branch 'origin/master' into store-deps-graph
zkochan Nov 18, 2024
92f75b4
refactor: implement suggestions
zkochan Nov 19, 2024
7a8d730
refactor: dependencies graph
zkochan Nov 19, 2024
260d62d
refactor: don't store empty edges
zkochan Nov 19, 2024
0c03c06
refactor: add lifecycle to direct deps in graph
zkochan Nov 19, 2024
1322d1b
refactor: convert lockfile
zkochan Nov 20, 2024
af64291
refactor: convert lockfile
zkochan Nov 20, 2024
f3a2690
refactor: remove specifiers from deps graph
zkochan Nov 20, 2024
32af787
Merge remote-tracking branch 'origin/master' into store-deps-graph
zkochan Nov 20, 2024
4f940aa
fix: compile
zkochan Nov 20, 2024
d6dcd36
refactor: implement suggestions
zkochan Nov 20, 2024
2ab3888
test: fix
zkochan Nov 20, 2024
19b2963
style: fix
zkochan Nov 21, 2024
ff3df60
Merge remote-tracking branch 'origin/master' into store-deps-graph
zkochan Nov 21, 2024
a8ed78d
feat: write dependency graph on sign
zkochan Nov 21, 2024
45fc29b
refactor: lockfile to graph
zkochan Nov 22, 2024
8c7a10b
refactor: lockfile to graph
zkochan Nov 22, 2024
96b4c7c
style: fix
zkochan Nov 22, 2024
4bc17cc
refactor: dependencies graph
zkochan Nov 22, 2024
0cd2d1e
style: fix
zkochan Nov 22, 2024
9d14a7e
test: fix
zkochan Nov 22, 2024
58cf941
Merge remote-tracking branch 'origin/master' into store-deps-graph
zkochan Nov 22, 2024
2d2f411
refactor: lockfile converter
zkochan Nov 22, 2024
42b03dc
refactor: lockfile converter
zkochan Nov 22, 2024
3cb2b2e
Merge remote-tracking branch 'origin/master' into store-deps-graph
zkochan Nov 25, 2024
954ed1d
test: fix
zkochan Nov 26, 2024
6c13ae9
Merge remote-tracking branch 'origin/master' into store-deps-graph
zkochan Nov 26, 2024
eb81dcc
refactor: implement suggestions
zkochan Nov 26, 2024
625faf2
refactor: implement suggestions
zkochan Nov 26, 2024
e0149ec
refactor: implement suggestions
zkochan Nov 26, 2024
96b007b
fix: linting error
zkochan Nov 26, 2024
a0c13fc
refactor: rename lockfile-converter
zkochan Nov 26, 2024
73302e1
refactor: implement suggestions
zkochan Nov 26, 2024
8e032d9
test: rename cases
zkochan Nov 26, 2024
efa6dc7
Merge remote-tracking branch 'origin/master' into store-deps-graph
zkochan Nov 26, 2024
21caa93
Merge remote-tracking branch 'origin/master' into store-deps-graph
zkochan Nov 27, 2024
d78d9b5
Merge branch 'master' into store-deps-graph
zkochan Nov 27, 2024
f7f6628
fix: never dry run when deps graph is used
zkochan Nov 27, 2024
485999d
Merge remote-tracking branch 'origin/master' into store-deps-graph
zkochan Nov 28, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
402 changes: 402 additions & 0 deletions e2e/harmony/deps-graph.e2e.ts

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@
"memoizee": "0.4.15",
"socks-proxy-agent": "5.0.0",
"yaml": "1.10.2",
"@pnpm/dependency-path": "5.1.7",
"@pnpm/lockfile.types": "^1.0.3",
"@pnpm/node-fetch": "^1.0.0",
"@teambit/defender.fs.global-bit-temp-dir": "0.0.1",
"@teambit/legacy.analytics": "~0.0.1",
Expand Down
11,930 changes: 6,072 additions & 5,858 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions scopes/component/apply/apply.main.runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ export class ApplyMain {
const shouldTag = Boolean(params.tag);
const results = await tagModelComponent({
...params,
components,
consumerComponents,
tagDataPerComp: snapDataPerComp.map((s) => ({
componentId: s.componentId,
Expand Down Expand Up @@ -339,6 +340,7 @@ export class ApplyMain {
const shouldTag = Boolean(params.tag);
const results = await tagModelComponent({
...params,
components,
consumerComponents,
tagDataPerComp: snapDataPerComp.map((s) => ({
componentId: s.componentId,
Expand Down
12 changes: 10 additions & 2 deletions scopes/component/component-writer/component-writer.main.runtime.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { MainRuntime } from '@teambit/cli';
import { ComponentID } from '@teambit/component-id';
import { CompilerAspect, CompilerMain } from '@teambit/compiler';
import { InstallAspect, InstallMain } from '@teambit/install';
import { Logger, LoggerAspect, LoggerMain } from '@teambit/logger';
Expand Down Expand Up @@ -79,22 +80,29 @@ export class ComponentWriterMain {
);
}
if (!opts.skipDependencyInstallation) {
installationError = await this.installPackagesGracefully(opts.skipWriteConfigFiles);
installationError = await this.installPackagesGracefully(
opts.components.map(({ id }) => id),
opts.skipWriteConfigFiles
);
// no point to compile if the installation is not running. the environment is not ready.
compilationError = await this.compileGracefully();
}
this.logger.debug('writeMany, completed!');
return { installationError, compilationError, workspaceConfigUpdateResult };
}

private async installPackagesGracefully(skipWriteConfigFiles = false): Promise<Error | undefined> {
private async installPackagesGracefully(
componentIds: ComponentID[],
skipWriteConfigFiles = false
): Promise<Error | undefined> {
this.logger.debug('installPackagesGracefully, start installing packages');
try {
const installOpts = {
dedupe: true,
updateExisting: false,
import: false,
writeConfigFiles: !skipWriteConfigFiles,
dependenciesGraph: await this.workspace.scope.getDependenciesGraphByComponentIds(componentIds),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: if I imported a few components (a,b), then I imported a few others (c,d), I will get here with the new ones (c,d) which means I'll build a graph based on c,d ids. which won't include a,b deps. isn't it will result in a wrong merged lock file?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will override the lockfile with dependencies of c and d. Dependencies of a and b will be resolved from scratch.

};
await this.installer.install(undefined, installOpts);
this.logger.debug('installPackagesGracefully, completed installing packages successfully');
Expand Down
2 changes: 1 addition & 1 deletion scopes/component/forking/forking.main.runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ the reason is that the refactor changes the components using ${sourceId.toString
GraphqlMain,
RefactoringMain,
PkgMain,
InstallMain
InstallMain,
]) {
const forkingMain = new ForkingMain(
workspace,
Expand Down
3 changes: 3 additions & 0 deletions scopes/component/isolator/capsule-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ export default class CapsuleList extends Array<Capsule> {
getAllComponents(): Component[] {
return this.map((c) => c.component);
}
getAllComponentIDs(): ComponentID[] {
return this.map((c) => c.component.id);
}
getGraphIds(): Graph<Component, string> {
const components = this.getAllComponents();
const graph = new Graph<Component, string>();
Expand Down
33 changes: 33 additions & 0 deletions scopes/component/isolator/isolator.main.runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import { pathNormalizeToLinux, PathOsBasedAbsolute } from '@teambit/legacy.utils
import { concurrentComponentsLimit } from '@teambit/harmony.modules.concurrency';
import { componentIdToPackageName } from '@teambit/pkg.modules.component-package-name';
import { Scope } from '@teambit/legacy/dist/scope';
import { type DependenciesGraph } from '@teambit/legacy/dist/scope/models/version';
import fs, { copyFile } from 'fs-extra';
import hash from 'object-hash';
import path, { basename } from 'path';
Expand Down Expand Up @@ -699,13 +700,22 @@ export class IsolatorMain {
})
);
} else {
const dependenciesGraph = await legacyScope?.getDependenciesGraphByComponentIds(
capsuleList.getAllComponentIDs()
);
const linkedDependencies = await this.linkInCapsules(capsuleList, capsulesWithPackagesData);
linkedDependencies[capsulesDir] = rootLinks;
await this.installInCapsules(capsulesDir, capsuleList, installOptions, {
cachePackagesOnCapsulesRoot,
linkedDependencies,
packageManager: opts.packageManager,
dependenciesGraph,
});
if (dependenciesGraph == null) {
// If the graph was not present in the model, we use the just created lockfile inside the capsules
// to populate the graph.
await this.calcDependenciesGraph(capsuleList, components, capsulesDir);
}
}
if (installLongProcessLogger) {
installLongProcessLogger.end('success');
Expand Down Expand Up @@ -737,6 +747,27 @@ export class IsolatorMain {
return allCapsuleList;
}

private async calcDependenciesGraph(
zkochan marked this conversation as resolved.
Show resolved Hide resolved
capsuleList: CapsuleList,
components: Component[],
capsulesDir: string
): Promise<void> {
const componentIdByPkgName = this.dependencyResolver.getComponentIdByPkgNameMap(components);
const opts = {
componentIdByPkgName,
capsulesDir,
};
await Promise.all(
capsuleList.map(async (capsule) => {
capsule.component.state._consumer.dependenciesGraph =
await this.dependencyResolver.calcDependenciesGraphFromCapsule(
path.relative(capsulesDir, capsule.path),
opts
);
zkochan marked this conversation as resolved.
Show resolved Hide resolved
})
);
}

private async markCapsulesAsReady(capsuleList: CapsuleList): Promise<void> {
await Promise.all(
capsuleList.map(async (capsule) => {
Expand Down Expand Up @@ -777,6 +808,7 @@ export class IsolatorMain {
linkedDependencies?: Record<string, Record<string, string>>;
packageManager?: string;
nodeLinker?: NodeLinker;
dependenciesGraph?: DependenciesGraph;
}
) {
const installer = this.dependencyResolver.getInstaller({
Expand All @@ -798,6 +830,7 @@ export class IsolatorMain {
forceTeambitHarmonyLink: !this.dependencyResolver.hasHarmonyInRootPolicy(),
excludeExtensionsDependencies: true,
dedupeInjectedDeps: true,
dependenciesGraph: opts.dependenciesGraph,
};

const packageManagerInstallOptions: PackageManagerInstallOptions = {
Expand Down
7 changes: 3 additions & 4 deletions scopes/component/merging/merging.main.runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,9 +269,8 @@ export class MergingMain {

let workspaceConfigConflictWriteError: Error | undefined;
if (workspaceDepsConflicts) {
workspaceConfigConflictWriteError = await this.configMerger.writeWorkspaceJsoncWithConflictsGracefully(
workspaceDepsConflicts
);
workspaceConfigConflictWriteError =
await this.configMerger.writeWorkspaceJsoncWithConflictsGracefully(workspaceDepsConflicts);
}
if (this.workspace) await this.configMerger.generateConfigMergeConflictFileForAll(allConfigMerge);

Expand Down Expand Up @@ -721,7 +720,7 @@ export class MergingMain {
RemoveMain,
GlobalConfigMain,
ConfigMergerMain,
DependencyResolverMain
DependencyResolverMain,
]) {
const logger = loggerMain.createLogger(MergingAspect.id);
const merging = new MergingMain(
Expand Down
55 changes: 48 additions & 7 deletions scopes/component/snapping/snapping.main.runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ import { LaneNotFound } from '@teambit/legacy.scope-api';
import { createLaneInScope } from '@teambit/lanes.modules.create-lane';
import { RemoveAspect, RemoveMain } from '@teambit/remove';

export type PackageIntegritiesByPublishedPackages = Map<string, string | undefined>;

export type TagDataPerComp = {
componentId: ComponentID;
dependencies: ComponentID[];
Expand Down Expand Up @@ -212,6 +214,7 @@ export class SnappingMain {
const { taggedComponents, autoTaggedResults, publishedPackages, stagedConfig, removedComponents } =
await tagModelComponent({
snapping: this,
components,
consumerComponents,
ids: compIds,
message,
Expand Down Expand Up @@ -336,6 +339,7 @@ if you're willing to lose the history from the head to the specified version, us
});
const results = await tagModelComponent({
...params,
components,
consumerComponents,
tagDataPerComp,
populateArtifactsFrom: shouldUsePopulateArtifactsFrom ? components.map((c) => c.id) : undefined,
Expand Down Expand Up @@ -500,6 +504,7 @@ if you're willing to lose the history from the head to the specified version, us
const shouldTag = Boolean(params.tag);
const results = await tagModelComponent({
...params,
components,
consumerComponents,
tagDataPerComp: snapDataPerComp.map((s) => ({
componentId: s.componentId,
Expand Down Expand Up @@ -588,6 +593,7 @@ if you're willing to lose the history from the head to the specified version, us
const { taggedComponents, autoTaggedResults, stagedConfig, removedComponents } = await tagModelComponent({
snapping: this,
editor,
components,
consumerComponents,
ids,
ignoreNewestVersion: false,
Expand Down Expand Up @@ -748,6 +754,31 @@ in case you're unsure about the pattern syntax, use "bit pattern [--help]"`);
this.logger.profile('snap._addFlattenedDependenciesToComponents');
}

async _addDependenciesGraphToComponents(components: Component[]): Promise<void> {
if (this.workspace == null) {
return;
}
this.logger.profile('snap._addDependenciesGraphToComponents');
const componentIdByPkgName = this.dependencyResolver.getComponentIdByPkgNameMap(components);
const options = {
workspacePath: this.workspace.path,
rootComponentsPath: this.workspace.rootComponentsPath,
componentIdByPkgName,
};
await Promise.all(
components.map(async (component) => {
if (component.state._consumer.componentMap?.rootDir) {
component.state._consumer.dependenciesGraph = await this.dependencyResolver.calcDependenciesGraph(
zkochan marked this conversation as resolved.
Show resolved Hide resolved
component,
component.state._consumer.componentMap.rootDir,
options
);
}
})
);
this.logger.profile('snap._addDependenciesGraphToComponents');
}

async throwForDepsFromAnotherLane(components: ConsumerComponent[]) {
const lane = await this.scope.legacyScope.getCurrentLaneObject();
const allIds = ComponentIdList.fromArray(components.map((c) => c.id));
Expand Down Expand Up @@ -912,13 +943,16 @@ another option, in case this dependency is not in main yet is to remove all refe
});
}

_getPublishedPackages(components: ConsumerComponent[]): string[] {
const publishedPackages = components.map((comp) => {
_getPublishedPackages(components: ConsumerComponent[]): PackageIntegritiesByPublishedPackages {
const publishedPackages: PackageIntegritiesByPublishedPackages = new Map();
for (const comp of components) {
const builderExt = comp.extensions.findCoreExtension(Extensions.builder);
const pkgData = builderExt?.data?.aspectsData?.find((a) => a.aspectId === Extensions.pkg);
return pkgData?.data?.publishedPackage;
});
return compact(publishedPackages);
if (pkgData?.data?.publishedPackage != null) {
publishedPackages.set(pkgData.data.publishedPackage, pkgData.data.integrity);
}
}
return publishedPackages;
}

async _addCompToObjects({
Expand Down Expand Up @@ -985,13 +1019,15 @@ another option, in case this dependency is not in main yet is to remove all refe
const component = await this.scope.legacyScope.sources.findOrAddComponent(source as any);
const artifactFiles = getArtifactsFiles(source.extensions);
const artifacts = this.transformArtifactsFromVinylToSource(artifactFiles);
const { version, files, flattenedEdges } = await this.scope.legacyScope.sources.consumerComponentToVersion(source);
const { version, files, flattenedEdges, dependenciesGraph } =
await this.scope.legacyScope.sources.consumerComponentToVersion(source);
version.origin = {
id: { scope: source.scope || (source.defaultScope as string), name: source.name },
lane: lane ? { scope: lane.scope, name: lane.name, hash: lane.hash().toString() } : undefined,
};
objectRepo.add(version);
if (flattenedEdges) this.objectsRepo.add(flattenedEdges);
if (dependenciesGraph) this.objectsRepo.add(dependenciesGraph);
if (!source.version) throw new Error(`addSource expects source.version to be set`);
component.addVersion(version, source.version, lane, source.previouslyUsedVersion, updateDependentsOnLane);
objectRepo.add(component);
Expand All @@ -1018,7 +1054,12 @@ another option, in case this dependency is not in main yet is to remove all refe
version.extensions = consumerComponent.extensions;
version.buildStatus = consumerComponent.buildStatus;
const artifactObjects = artifacts.map((file) => file.source);
return [version, ...artifactObjects];
const dependenciesGraph = Version.dependenciesGraphToSource(consumerComponent.dependenciesGraph);
version.dependenciesGraphRef = dependenciesGraph ? dependenciesGraph.hash() : undefined;

const result = [version, ...artifactObjects];
if (dependenciesGraph) result.push(dependenciesGraph);
return result;
}

private transformArtifactsFromVinylToSource(artifactsFiles: ArtifactFiles[]): ArtifactSource[] {
Expand Down
Loading