Exemplo n.º 1
0
        public override void Handle(
            IImmutableDictionary <string, IProjectChangeDescription> changesByRuleName,
            ITargetFramework targetFramework,
            CrossTargetDependenciesChangesBuilder changesBuilder)
        {
            var caseInsensitiveUnresolvedChanges = new HashSet <string>(StringComparer.OrdinalIgnoreCase);

            if (changesByRuleName.TryGetValue(UnresolvedRuleName, out IProjectChangeDescription unresolvedChanges))
            {
                caseInsensitiveUnresolvedChanges.AddRange(unresolvedChanges.After.Items.Keys);

                if (unresolvedChanges.Difference.AnyChanges)
                {
                    HandleChangesForRule(
                        unresolvedChanges,
                        changesBuilder,
                        targetFramework,
                        resolved: false);
                }
            }

            if (changesByRuleName.TryGetValue(ResolvedRuleName, out IProjectChangeDescription resolvedChanges) &&
                resolvedChanges.Difference.AnyChanges)
            {
                HandleChangesForRule(
                    resolvedChanges,
                    changesBuilder,
                    targetFramework,
                    resolved: true,
                    unresolvedChanges: caseInsensitiveUnresolvedChanges);
            }
        }
Exemplo n.º 2
0
        public virtual void Handle(
            IImmutableDictionary <string, IProjectChangeDescription> changesByRuleName,
            ITargetFramework targetFramework,
            CrossTargetDependenciesChangesBuilder changesBuilder)
        {
            // We receive unresolved and resolved changes separately.

            // Process all unresolved changes.
            if (changesByRuleName.TryGetValue(UnresolvedRuleName, out IProjectChangeDescription unresolvedChanges))
            {
                HandleChangesForRule(
                    resolved: false,
                    projectChange: unresolvedChanges,
                    targetFramework,
                    changesBuilder,
                    shouldProcess: dependencyId => true);
            }

            // Process only resolved changes that have a corresponding unresolved item.
            if (unresolvedChanges != null &&
                changesByRuleName.TryGetValue(ResolvedRuleName, out IProjectChangeDescription resolvedChanges))
            {
                HandleChangesForRule(
                    resolved: true,
                    projectChange: resolvedChanges,
                    targetFramework,
                    changesBuilder,
                    shouldProcess: unresolvedChanges.After.Items.ContainsKey);
            }
        }
Exemplo n.º 3
0
        private void HandleChangesForRule(
            IProjectChangeDescription projectChange,
            CrossTargetDependenciesChangesBuilder changesBuilder,
            ITargetFramework targetFramework,
            bool resolved,
            HashSet <string>?unresolvedChanges = null)
        {
            Requires.NotNull(targetFramework, nameof(targetFramework));

            foreach (string removedItem in projectChange.Difference.RemovedItems)
            {
                if (PackageDependencyMetadata.TryGetMetadata(
                        removedItem,
                        resolved,
                        properties: projectChange.Before.GetProjectItemProperties(removedItem) ?? ImmutableDictionary <string, string> .Empty,
                        unresolvedChanges,
                        targetFramework,
                        _targetFrameworkProvider,
                        out PackageDependencyMetadata metadata))
                {
                    changesBuilder.Removed(targetFramework, ProviderTypeString, metadata.OriginalItemSpec);
                }
            }

            foreach (string changedItem in projectChange.Difference.ChangedItems)
            {
                if (PackageDependencyMetadata.TryGetMetadata(
                        changedItem,
                        resolved,
                        properties: projectChange.After.GetProjectItemProperties(changedItem) ?? ImmutableDictionary <string, string> .Empty,
                        unresolvedChanges,
                        targetFramework,
                        _targetFrameworkProvider,
                        out PackageDependencyMetadata metadata))
                {
                    changesBuilder.Removed(targetFramework, ProviderTypeString, metadata.OriginalItemSpec);
                    changesBuilder.Added(targetFramework, metadata.CreateDependencyModel());
                }
            }

            foreach (string addedItem in projectChange.Difference.AddedItems)
            {
                if (PackageDependencyMetadata.TryGetMetadata(
                        addedItem,
                        resolved,
                        properties: projectChange.After.GetProjectItemProperties(addedItem) ?? ImmutableDictionary <string, string> .Empty,
                        unresolvedChanges,
                        targetFramework,
                        _targetFrameworkProvider,
                        out PackageDependencyMetadata metadata))
                {
                    changesBuilder.Added(targetFramework, metadata.CreateDependencyModel());
                }
            }
        }
        private void ProcessSharedProjectsUpdates(
            IProjectSharedFoldersSnapshot sharedFolders,
            ITargetFramework targetFramework,
            CrossTargetDependenciesChangesBuilder changesBuilder)
        {
            Requires.NotNull(sharedFolders, nameof(sharedFolders));
            Requires.NotNull(targetFramework, nameof(targetFramework));
            Requires.NotNull(changesBuilder, nameof(changesBuilder));

            IDependenciesSnapshot snapshot = _dependenciesSnapshotProvider.CurrentSnapshot;

            if (!snapshot.Targets.TryGetValue(targetFramework, out ITargetedDependenciesSnapshot targetedSnapshot))
            {
                return;
            }

            IEnumerable <string> sharedFolderProjectPaths = sharedFolders.Value.Select(sf => sf.ProjectPath);
            var currentSharedImportNodes = targetedSnapshot.TopLevelDependencies
                                           .Where(x => x.Flags.Contains(DependencyTreeFlags.SharedProjectFlags))
                                           .ToList();
            IEnumerable <string> currentSharedImportNodePaths = currentSharedImportNodes.Select(x => x.Path);

            // process added nodes
            IEnumerable <string> addedSharedImportPaths = sharedFolderProjectPaths.Except(currentSharedImportNodePaths);

            foreach (string addedSharedImportPath in addedSharedImportPaths)
            {
                IDependencyModel added = new SharedProjectDependencyModel(
                    addedSharedImportPath,
                    addedSharedImportPath,
                    isResolved: true,
                    isImplicit: false,
                    properties: ImmutableStringDictionary <string> .EmptyOrdinal);
                changesBuilder.Added(targetFramework, added);
            }

            // process removed nodes
            IEnumerable <string> removedSharedImportPaths = currentSharedImportNodePaths.Except(sharedFolderProjectPaths);

            foreach (string removedSharedImportPath in removedSharedImportPaths)
            {
                bool exists = currentSharedImportNodes.Any(node => PathHelper.IsSamePath(node.Path, removedSharedImportPath));

                if (exists)
                {
                    changesBuilder.Removed(
                        targetFramework,
                        ProjectRuleHandler.ProviderTypeString,
                        dependencyId: removedSharedImportPath);
                }
            }
        }
Exemplo n.º 5
0
        private void HandleChangesForRule(
            bool resolved,
            IProjectChangeDescription projectChange,
            ITargetFramework targetFramework,
            CrossTargetDependenciesChangesBuilder changesBuilder,
            Func <string, bool> shouldProcess)
        {
            foreach (string removedItem in projectChange.Difference.RemovedItems)
            {
                string dependencyId = resolved
                    ? projectChange.Before.GetProjectItemProperties(removedItem).GetStringProperty(ResolvedAssemblyReference.OriginalItemSpecProperty)
                    : removedItem;

                if (shouldProcess(dependencyId))
                {
                    changesBuilder.Removed(targetFramework, ProviderType, removedItem);
                }
            }

            foreach (string changedItem in projectChange.Difference.ChangedItems)
            {
                IDependencyModel model = CreateDependencyModelForRule(changedItem, resolved, projectChange.After);
                if (shouldProcess(model.Id))
                {
                    // For changes we try to add new dependency. If it is a resolved dependency, it would just override
                    // old one with new properties. If it is unresolved dependency, it would be added only when there no
                    // resolved version in the snapshot.
                    changesBuilder.Added(targetFramework, model);
                }
            }

            foreach (string addedItem in projectChange.Difference.AddedItems)
            {
                IDependencyModel model = CreateDependencyModelForRule(addedItem, resolved, projectChange.After);
                if (shouldProcess(model.Id))
                {
                    changesBuilder.Added(targetFramework, model);
                }
            }
        }
Exemplo n.º 6
0
        private async Task HandleAsync(Tuple <IProjectSubscriptionUpdate, IProjectSharedFoldersSnapshot, IProjectCatalogSnapshot> e)
        {
            AggregateCrossTargetProjectContext?currentAggregateContext = await _host !.GetCurrentAggregateProjectContextAsync();

            if (currentAggregateContext == null)
            {
                return;
            }

            IProjectSubscriptionUpdate    projectUpdate        = e.Item1;
            IProjectSharedFoldersSnapshot sharedProjectsUpdate = e.Item2;
            IProjectCatalogSnapshot       catalogs             = e.Item3;

            // Get the target framework to update for this change.
            ITargetFramework?targetFrameworkToUpdate = currentAggregateContext.GetProjectFramework(projectUpdate.ProjectConfiguration);

            if (targetFrameworkToUpdate == null)
            {
                return;
            }

            var changesBuilder = new CrossTargetDependenciesChangesBuilder();

            ProcessSharedProjectsUpdates(sharedProjectsUpdate, targetFrameworkToUpdate, changesBuilder);

            ImmutableDictionary <ITargetFramework, IDependenciesChanges>?changes = changesBuilder.TryBuildChanges();

            if (changes != null)
            {
                DependenciesChanged?.Invoke(
                    this,
                    new DependencySubscriptionChangedEventArgs(
                        currentAggregateContext.TargetFrameworks,
                        currentAggregateContext.ActiveTargetFramework,
                        catalogs,
                        changes));
            }
        }
        public virtual void Handle(
            IImmutableDictionary <string, IProjectChangeDescription> changesByRuleName,
            ITargetFramework targetFramework,
            CrossTargetDependenciesChangesBuilder changesBuilder)
        {
            // We receive unresolved and resolved changes separately.

            // Process all unresolved changes.
            if (changesByRuleName.TryGetValue(UnresolvedRuleName, out IProjectChangeDescription unresolvedChanges))
            {
                HandleChangesForRule(
                    resolved: false,
                    projectChange: unresolvedChanges,
                    shouldProcess: dependencyId => true);
            }

            // Process only resolved changes that have a corresponding unresolved item.
            if (unresolvedChanges != null &&
                changesByRuleName.TryGetValue(ResolvedRuleName, out IProjectChangeDescription resolvedChanges))
            {
                HandleChangesForRule(
                    resolved: true,
                    projectChange: resolvedChanges,
                    shouldProcess: unresolvedChanges.After.Items.ContainsKey);
            }

            return;

            void HandleChangesForRule(bool resolved, IProjectChangeDescription projectChange, Func <string, bool> shouldProcess)
            {
                foreach (string removedItem in projectChange.Difference.RemovedItems)
                {
                    string dependencyId = resolved
                        ? projectChange.Before.GetProjectItemProperties(removedItem).GetStringProperty(ResolvedAssemblyReference.OriginalItemSpecProperty) ?? removedItem
                        : removedItem;

                    if (shouldProcess(dependencyId))
                    {
                        changesBuilder.Removed(targetFramework, ProviderType, removedItem);
                    }
                }

                foreach (string changedItem in projectChange.Difference.ChangedItems)
                {
                    IDependencyModel model = CreateDependencyModelForRule(changedItem, projectChange.After);
                    if (shouldProcess(model.Id))
                    {
                        // For changes we try to add new dependency. If it is a resolved dependency, it would just override
                        // old one with new properties. If it is unresolved dependency, it would be added only when there no
                        // resolved version in the snapshot.
                        changesBuilder.Added(targetFramework, model);
                    }
                }

                foreach (string addedItem in projectChange.Difference.AddedItems)
                {
                    IDependencyModel model = CreateDependencyModelForRule(addedItem, projectChange.After);
                    if (shouldProcess(model.Id))
                    {
                        changesBuilder.Added(targetFramework, model);
                    }
                }

                return;

                IDependencyModel CreateDependencyModelForRule(string itemSpec, IProjectRuleSnapshot projectRuleSnapshot)
                {
                    IImmutableDictionary <string, string> properties = projectRuleSnapshot.GetProjectItemProperties(itemSpec);

                    string originalItemSpec = resolved
                        ? properties.GetStringProperty(ResolvedAssemblyReference.OriginalItemSpecProperty)
                        : itemSpec;

                    bool isImplicit = properties.GetBoolProperty(ProjectItemMetadata.IsImplicitlyDefined) ?? false;

                    return(CreateDependencyModel(
                               itemSpec,
                               originalItemSpec,
                               resolved,
                               isImplicit,
                               properties));
                }
            }
        }