Example #1
0
        private void UpdateFromFolderLayout(PackageIndex index, string path, bool filter = false)
        {
            var version = NuGetVersion.Parse(Path.GetFileName(path));
            var id      = Path.GetFileName(Path.GetDirectoryName(path));

            if (filter && !ShouldInclude(id))
            {
                return;
            }

            string refFolder = Path.Combine(path, "ref");

            if (!Directory.Exists(refFolder))
            {
                refFolder = Path.Combine(path, "lib");
            }

            IEnumerable <Version> assemblyVersions = null;

            if (Directory.Exists(refFolder))
            {
                assemblyVersions = Directory.EnumerateFiles(refFolder, "*.dll", SearchOption.AllDirectories)
                                   .Select(f => VersionUtility.GetAssemblyVersion(f));
            }

            UpdateFromValues(index, id, version, assemblyVersions);
        }
Example #2
0
        public void MergeInboxFromLayout(NuGetFramework framework, string layoutDirectory, bool addPackages = true)
        {
            foreach (var file in Directory.EnumerateFiles(layoutDirectory, "*.dll", SearchOption.AllDirectories))
            {
                var assemblyName    = Path.GetFileNameWithoutExtension(file);
                var assemblyVersion = VersionUtility.GetAssemblyVersion(file);

                TryAddInbox(assemblyName, framework, assemblyVersion, addPackages);
            }
        }
Example #3
0
        public void HarvestFilesFromPackage()
        {
            string pathToPackage = Path.Combine(PackagesFolder, PackageId, PackageVersion);

            if (!Directory.Exists(pathToPackage))
            {
                Log.LogError($"Cannot harvest from package {PackageId}/{PackageVersion} because {pathToPackage} does not exist.");
                return;
            }

            var harvestedFiles = new List <ITaskItem>();

            foreach (var extension in includedExtensions)
            {
                foreach (var packageFile in Directory.EnumerateFiles(pathToPackage, $"*{extension}", SearchOption.AllDirectories))
                {
                    string packagePath = packageFile.Substring(pathToPackage.Length + 1).Replace('\\', '/');

                    if (ShouldExclude(packagePath))
                    {
                        Log.LogMessage($"Preferring live build of package path {packagePath} over the asset from last stable package.");
                        continue;
                    }
                    else
                    {
                        Log.LogMessage($"Including {packagePath} from last stable package {PackageId}/{PackageVersion}.");
                    }

                    var item       = new TaskItem(packageFile);
                    var targetPath = Path.GetDirectoryName(packagePath).Replace('\\', '/');
                    item.SetMetadata("TargetPath", targetPath);
                    item.SetMetadata("TargetFramework", GetTargetFrameworkFromPackagePath(targetPath));
                    item.SetMetadata("HarvestDependencies", "true");
                    item.SetMetadata("IsReferenceAsset", IsReferencePackagePath(targetPath).ToString());
                    var assemblyVersion = VersionUtility.GetAssemblyVersion(packageFile);
                    if (assemblyVersion != null)
                    {
                        item.SetMetadata("AssemblyVersion", assemblyVersion.ToString());
                    }

                    harvestedFiles.Add(item);
                }
            }

            Files = harvestedFiles.ToArray();
        }
Example #4
0
        private void UpdateFromFolderLayout(PackageIndex index, string path, bool filter = false)
        {
            var version = NuGetVersion.Parse(Path.GetFileName(path));
            var id      = Path.GetFileName(Path.GetDirectoryName(path));

            if (filter && !ShouldInclude(id))
            {
                return;
            }

            var dlls = Directory.EnumerateFiles(path, "*.dll", SearchOption.AllDirectories);

            var assemblyVersions = dlls.Select(f => VersionUtility.GetAssemblyVersion(f));
            var dllNames         = dlls.Select(f => Path.GetFileNameWithoutExtension(f)).Distinct();

            UpdateFromValues(index, id, version, assemblyVersions, dllNames);
        }
Example #5
0
        private void UpdateFromPackage(PackageIndex index, string packagePath, bool filter = false)
        {
            string                id;
            NuGetVersion          version;
            IEnumerable <Version> assemblyVersions;

            using (var reader = new PackageArchiveReader(packagePath))
            {
                var identity = reader.GetIdentity();
                id      = identity.Id;
                version = identity.Version;

                if (filter && !ShouldInclude(id))
                {
                    return;
                }

                var refFiles = reader.GetFiles("ref").Where(r => !NuGetAssetResolver.IsPlaceholder(r));

                if (!refFiles.Any())
                {
                    refFiles = reader.GetFiles("lib");
                }

                assemblyVersions = refFiles.Select(refFile =>
                {
                    using (var refStream = reader.GetStream(refFile))
                        using (var memStream = new MemoryStream())
                        {
                            refStream.CopyTo(memStream);
                            memStream.Seek(0, SeekOrigin.Begin);
                            return(VersionUtility.GetAssemblyVersion(memStream));
                        }
                }).ToArray();
            }

            UpdateFromValues(index, id, version, assemblyVersions);
        }
Example #6
0
        private void UpdateFromPackage(PackageIndex index, string packagePath, bool filter = false)
        {
            string                id;
            NuGetVersion          version;
            IEnumerable <Version> assemblyVersions;
            IEnumerable <string>  dllNames;

            using (var reader = new PackageArchiveReader(packagePath))
            {
                var identity = reader.GetIdentity();
                id      = identity.Id;
                version = identity.Version;

                if (filter && !ShouldInclude(id))
                {
                    return;
                }

                var dlls = reader.GetFiles().Where(f => Path.GetExtension(f).Equals(".dll", StringComparison.OrdinalIgnoreCase));

                assemblyVersions = dlls.Select(refFile =>
                {
                    using (var refStream = reader.GetStream(refFile))
                        using (var memStream = new MemoryStream())
                        {
                            refStream.CopyTo(memStream);
                            memStream.Seek(0, SeekOrigin.Begin);
                            return(VersionUtility.GetAssemblyVersion(memStream));
                        }
                }).ToArray();

                dllNames = dlls.Select(f => Path.GetFileNameWithoutExtension(f)).Distinct().ToArray();
            }

            UpdateFromValues(index, id, version, assemblyVersions, dllNames);
        }
Example #7
0
        private void HarvestSupportedFrameworks()
        {
            List <ITaskItem> supportedFrameworks = new List <ITaskItem>();

            AggregateNuGetAssetResolver resolver = new AggregateNuGetAssetResolver(RuntimeFile);
            string packagePath = Path.Combine(PackagesFolder, PackageId, PackageVersion);

            // add the primary package
            resolver.AddPackageItems(PackageId, GetPackageItems(packagePath));

            if (RuntimePackages != null)
            {
                // add any split runtime packages
                foreach (var runtimePackage in RuntimePackages)
                {
                    var runtimePackageId      = runtimePackage.ItemSpec;
                    var runtimePackageVersion = runtimePackage.GetMetadata("Version");

                    resolver.AddPackageItems(runtimePackageId, GetPackageItems(PackagesFolder, runtimePackageId, runtimePackageVersion));
                }
            }

            // create a resolver that can be used to determine the API version for inbox assemblies
            // since inbox assemblies are represented with placeholders we can remove the placeholders
            // and use the netstandard reference assembly to determine the API version
            var filesWithoutPlaceholders = GetPackageItems(packagePath)
                                           .Where(f => !NuGetAssetResolver.IsPlaceholder(f));
            NuGetAssetResolver resolverWithoutPlaceholders = new NuGetAssetResolver(RuntimeFile, filesWithoutPlaceholders);

            string package = $"{PackageId}/{PackageVersion}";

            foreach (var framework in Frameworks)
            {
                var runtimeIds = framework.GetMetadata("RuntimeIDs")?.Split(';');

                NuGetFramework fx;
                try
                {
                    fx = FrameworkUtilities.ParseNormalized(framework.ItemSpec);
                }
                catch (Exception ex)
                {
                    Log.LogError($"Could not parse Framework {framework.ItemSpec}. {ex}");
                    continue;
                }

                if (fx.Equals(NuGetFramework.UnsupportedFramework))
                {
                    Log.LogError($"Did not recognize {framework.ItemSpec} as valid Framework.");
                    continue;
                }

                var compileAssets = resolver.ResolveCompileAssets(fx, PackageId);

                bool hasCompileAsset, hasCompilePlaceHolder;
                NuGetAssetResolver.ExamineAssets(Log, "Compile", package, fx.ToString(), compileAssets, out hasCompileAsset, out hasCompilePlaceHolder);

                // start by making sure it has some asset available for compile
                var isSupported = hasCompileAsset || hasCompilePlaceHolder;

                if (!isSupported)
                {
                    Log.LogMessage(LogImportance.Low, $"Skipping {fx} because it is not supported.");
                    continue;
                }

                foreach (var runtimeId in runtimeIds)
                {
                    string target = String.IsNullOrEmpty(runtimeId) ? fx.ToString() : $"{fx}/{runtimeId}";

                    var runtimeAssets = resolver.ResolveRuntimeAssets(fx, runtimeId);

                    bool hasRuntimeAsset, hasRuntimePlaceHolder;
                    NuGetAssetResolver.ExamineAssets(Log, "Runtime", package, target, runtimeAssets, out hasRuntimeAsset, out hasRuntimePlaceHolder);

                    isSupported &= hasCompileAsset == hasRuntimeAsset;
                    isSupported &= hasCompilePlaceHolder == hasRuntimePlaceHolder;

                    if (!isSupported)
                    {
                        Log.LogMessage(LogImportance.Low, $"Skipping {fx} because it is not supported on {target}.");
                        break;
                    }
                }

                if (isSupported)
                {
                    var supportedFramework = new TaskItem(framework.ItemSpec);
                    supportedFramework.SetMetadata("HarvestedFromPackage", package);

                    // set version

                    // first try the resolved compile asset for this package
                    var refAssm = compileAssets.FirstOrDefault(r => !NuGetAssetResolver.IsPlaceholder(r))?.Substring(PackageId.Length + 1);

                    if (refAssm == null)
                    {
                        // if we didn't have a compile asset it means this framework is supported inbox with a placeholder
                        // resolve the assets without placeholders to pick up the netstandard reference assembly.
                        compileAssets = resolverWithoutPlaceholders.ResolveCompileAssets(fx);
                        refAssm       = compileAssets.FirstOrDefault(r => !NuGetAssetResolver.IsPlaceholder(r));
                    }

                    string version = "unknown";
                    if (refAssm != null)
                    {
                        version = VersionUtility.GetAssemblyVersion(Path.Combine(packagePath, refAssm))?.ToString() ?? version;
                    }

                    supportedFramework.SetMetadata("Version", version);

                    Log.LogMessage($"Validating version {version} for {supportedFramework.ItemSpec} because it was supported by {PackageId}/{PackageVersion}.");

                    supportedFrameworks.Add(supportedFramework);
                }
            }

            SupportedFrameworks = supportedFrameworks.ToArray();
        }
Example #8
0
        public void HarvestFilesFromPackage()
        {
            string pathToPackage = Path.Combine(PackagesFolder, PackageId, PackageVersion);

            if (!Directory.Exists(pathToPackage))
            {
                Log.LogError($"Cannot harvest from package {PackageId}/{PackageVersion} because {pathToPackage} does not exist.");
                return;
            }

            var livePackageFiles = Files.NullAsEmpty()
                                   .Where(f => IsIncludedExtension(f.GetMetadata("Extension")))
                                   .Select(f => new PackageItem(f))
                                   .ToDictionary(p => p.TargetPath, StringComparer.OrdinalIgnoreCase);

            var harvestedFiles = new List <ITaskItem>();
            var removeFiles    = new List <ITaskItem>();

            // make sure we preserve refs that match desktop assemblies
            var liveDesktopDlls    = livePackageFiles.Values.Where(pi => pi.IsDll && pi.TargetFramework?.Framework == FrameworkConstants.FrameworkIdentifiers.Net);
            var desktopRefVersions = liveDesktopDlls.Where(d => d.IsRef && d.Version != null).Select(d => d.Version);
            var desktopLibVersions = liveDesktopDlls.Where(d => !d.IsRef && d.Version != null).Select(d => d.Version);

            // find destkop assemblies with no matching lib.
            var preserveRefVersion = new HashSet <Version>(desktopLibVersions);

            preserveRefVersion.ExceptWith(desktopRefVersions);

            foreach (var extension in s_includedExtensions)
            {
                foreach (var packageFile in Directory.EnumerateFiles(pathToPackage, $"*{extension}", SearchOption.AllDirectories))
                {
                    string packagePath = packageFile.Substring(pathToPackage.Length + 1).Replace('\\', '/');

                    // determine if we should include this file from the harvested package

                    // exclude if its specifically set for exclusion
                    if (ShouldExclude(packagePath))
                    {
                        Log.LogMessage(LogImportance.Low, $"Excluding package path {packagePath}.");
                        continue;
                    }

                    var assemblyVersion = extension == s_dll?VersionUtility.GetAssemblyVersion(packageFile) : null;

                    PackageItem liveFile = null;

                    // determine if the harvested file clashes with a live built file
                    // we'll prefer the harvested reference assembly so long as it's the same API
                    // version and not required to match implementation 1:1 as is the case for desktop
                    if (livePackageFiles.TryGetValue(packagePath, out liveFile))
                    {
                        // Not a dll, not a ref, or not a versioned assembly: prefer live built file.
                        if (extension != s_dll || !liveFile.IsRef || assemblyVersion == null || liveFile.Version == null)
                        {
                            Log.LogMessage(LogImportance.Low, $"Preferring live build of package path {packagePath} over the asset from last stable package.");
                            continue;
                        }

                        // preserve desktop references to ensure bindingRedirects will work.
                        if (liveFile.TargetFramework.Framework == FrameworkConstants.FrameworkIdentifiers.Net)
                        {
                            Log.LogMessage(LogImportance.Low, $"Preferring live build of package path {packagePath} over the asset from last stable package for desktop framework.");
                            continue;
                        }

                        // as above but handle the case where a netstandard ref may be used for a desktop impl.
                        if (preserveRefVersion.Contains(liveFile.Version))
                        {
                            Log.LogMessage(LogImportance.Low, $"Preferring live build of package path {packagePath} over the asset from last stable package for desktop framework.");
                            continue;
                        }

                        // preserve references with a different major.minor version
                        if (assemblyVersion.Major != liveFile.Version.Major ||
                            assemblyVersion.Minor != liveFile.Version.Minor)
                        {
                            Log.LogMessage(LogImportance.Low, $"Preferring live build of reference {packagePath} over the asset from last stable package since the live build is a different API version.");
                            continue;
                        }

                        // preserve references that specifically set the preserve metadata.
                        bool preserve = false;
                        bool.TryParse(liveFile.OriginalItem.GetMetadata("Preserve"), out preserve);
                        if (preserve)
                        {
                            Log.LogMessage(LogImportance.Low, $"Preferring live build of reference {packagePath} over the asset from last stable package since Preserve was set to true.");
                            continue;
                        }

                        // replace the live file with the harvested one, removing both the live file and PDB from the
                        // file list.
                        Log.LogMessage($"Using reference {packagePath} from last stable package {PackageId}/{PackageVersion} rather than the built reference {liveFile.SourcePath} since it is the same API version.  Set <Preserve>true</Preserve> on {liveFile.SourceProject} if you'd like to avoid this..");
                        removeFiles.Add(liveFile.OriginalItem);

                        PackageItem livePdbFile;
                        if (livePackageFiles.TryGetValue(Path.ChangeExtension(packagePath, ".pdb"), out livePdbFile))
                        {
                            removeFiles.Add(livePdbFile.OriginalItem);
                        }
                    }
                    else
                    {
                        Log.LogMessage(LogImportance.Low, $"Including {packagePath} from last stable package {PackageId}/{PackageVersion}.");
                    }

                    var item = new TaskItem(packageFile);

                    if (liveFile?.OriginalItem != null)
                    {
                        // preserve all the meta-data from the live file that was replaced.
                        liveFile.OriginalItem.CopyMetadataTo(item);
                    }
                    else
                    {
                        var targetPath = Path.GetDirectoryName(packagePath).Replace('\\', '/');
                        item.SetMetadata("TargetPath", targetPath);
                        string targetFramework = GetTargetFrameworkFromPackagePath(targetPath);
                        item.SetMetadata("TargetFramework", targetFramework);
                        // only harvest for non-portable frameworks, matches logic in packaging.targets.
                        bool harvestDependencies = !targetFramework.StartsWith("portable-");
                        item.SetMetadata("HarvestDependencies", harvestDependencies.ToString());
                        item.SetMetadata("IsReferenceAsset", IsReferencePackagePath(targetPath).ToString());
                    }

                    if (assemblyVersion != null)
                    {
                        // overwrite whatever metadata may have been copied from the live file.
                        item.SetMetadata("AssemblyVersion", assemblyVersion.ToString());
                    }

                    harvestedFiles.Add(item);
                }
            }

            HarvestedFiles = harvestedFiles.ToArray();

            if (Files != null)
            {
                UpdatedFiles = Files.Except(removeFiles).ToArray();
            }
        }
Example #9
0
        public void HarvestFilesFromPackage()
        {
            string pathToPackage = _packageFolders[PackageId];

            var livePackageItems = Files.NullAsEmpty()
                                   .Where(f => IsIncludedExtension(f.GetMetadata("Extension")))
                                   .Select(f => new PackageItem(f));

            var livePackageFiles = new Dictionary <string, PackageItem>(StringComparer.OrdinalIgnoreCase);

            foreach (var livePackageItem in livePackageItems)
            {
                PackageItem existingitem;

                if (livePackageFiles.TryGetValue(livePackageItem.TargetPath, out existingitem))
                {
                    Log.LogError($"Package contains two files with same targetpath: {livePackageItem.TargetPath}, items:{livePackageItem.SourcePath}, {existingitem.SourcePath}.");
                }
                else
                {
                    livePackageFiles.Add(livePackageItem.TargetPath, livePackageItem);
                }
            }

            var harvestedFiles = new List <ITaskItem>();
            var removeFiles    = new List <ITaskItem>();

            // make sure we preserve refs that match desktop assemblies
            var liveDesktopDlls    = livePackageFiles.Values.Where(pi => pi.IsDll && pi.TargetFramework?.Framework == FrameworkConstants.FrameworkIdentifiers.Net);
            var desktopRefVersions = liveDesktopDlls.Where(d => d.IsRef && d.Version != null).Select(d => d.Version);
            var desktopLibVersions = liveDesktopDlls.Where(d => !d.IsRef && d.Version != null).Select(d => d.Version);

            // find desktop assemblies with no matching lib.
            var preserveRefVersion = new HashSet <Version>(desktopLibVersions);

            preserveRefVersion.ExceptWith(desktopRefVersions);

            foreach (var extension in s_includedExtensions)
            {
                foreach (var packageFile in Directory.EnumerateFiles(pathToPackage, $"*{extension}", SearchOption.AllDirectories))
                {
                    string harvestPackagePath = packageFile.Substring(pathToPackage.Length + 1).Replace('\\', '/');

                    // determine if we should include this file from the harvested package

                    // exclude if its specifically set for exclusion
                    if (ShouldExclude(harvestPackagePath))
                    {
                        Log.LogMessage(LogImportance.Low, $"Excluding package path {harvestPackagePath} because it is specifically excluded.");
                        continue;
                    }

                    ITaskItem includeItem = null;
                    if (!IncludeAllPaths && !ShouldInclude(harvestPackagePath, out includeItem))
                    {
                        Log.LogMessage(LogImportance.Low, $"Excluding package path {harvestPackagePath} because it is not included in {nameof(PathsToInclude)}.");
                        continue;
                    }

                    // allow for the harvested item to be moved
                    var remappedTargetPath = includeItem?.GetMetadata("TargetPath");
                    if (!String.IsNullOrEmpty(remappedTargetPath))
                    {
                        harvestPackagePath = remappedTargetPath + '/' + Path.GetFileName(packageFile);
                    }

                    List <string> targetPaths = new List <string>()
                    {
                        harvestPackagePath
                    };

                    var additionalTargetPaths = includeItem?.GetMetadata("AdditionalTargetPath");
                    if (!String.IsNullOrEmpty(additionalTargetPaths))
                    {
                        foreach (var additionalTargetPath in additionalTargetPaths.Split(';'))
                        {
                            if (!String.IsNullOrEmpty(additionalTargetPath))
                            {
                                targetPaths.Add(additionalTargetPath + '/' + Path.GetFileName(packageFile));
                            }
                        }
                    }

                    var assemblyVersion = extension == s_dll?VersionUtility.GetAssemblyVersion(packageFile) : null;

                    PackageItem liveFile = null;

                    foreach (var livePackagePath in targetPaths)
                    {
                        // determine if the harvested file clashes with a live built file
                        // we'll prefer the harvested reference assembly so long as it's the same API
                        // version and not required to match implementation 1:1 as is the case for desktop
                        if (livePackageFiles.TryGetValue(livePackagePath, out liveFile))
                        {
                            // Not a dll, or not a versioned assembly: prefer live built file.
                            if (extension != s_dll || assemblyVersion == null || liveFile.Version == null)
                            {
                                // we don't consider this an error even for explicitly included files
                                Log.LogMessage(LogImportance.Low, $"Preferring live build of package path {livePackagePath} over the asset from last stable package because the file is not versioned.");
                                continue;
                            }

                            // not a ref
                            if (!liveFile.IsRef)
                            {
                                LogSkipIncludedFile(livePackagePath, " because it is a newer implementation.");
                                continue;
                            }

                            // preserve desktop references to ensure bindingRedirects will work.
                            if (liveFile.TargetFramework.Framework == FrameworkConstants.FrameworkIdentifiers.Net)
                            {
                                LogSkipIncludedFile(livePackagePath, " because it is desktop reference.");
                                continue;
                            }

                            // as above but handle the case where a netstandard ref may be used for a desktop impl.
                            if (preserveRefVersion.Contains(liveFile.Version))
                            {
                                LogSkipIncludedFile(livePackagePath, " because it will be applicable for desktop projects.");
                                continue;
                            }

                            // preserve references with a different major.minor version
                            if (assemblyVersion.Major != liveFile.Version.Major ||
                                assemblyVersion.Minor != liveFile.Version.Minor)
                            {
                                LogSkipIncludedFile(livePackagePath, $" because it is a different API version ( {liveFile.Version.Major}.{liveFile.Version.Minor} vs {assemblyVersion.Major}.{assemblyVersion.Minor}.");
                                continue;
                            }

                            // preserve references that specifically set the preserve metadata.
                            bool preserve = false;
                            bool.TryParse(liveFile.OriginalItem.GetMetadata("Preserve"), out preserve);
                            if (preserve)
                            {
                                LogSkipIncludedFile(livePackagePath, " because it set metadata Preserve=true.");
                                continue;
                            }

                            // replace the live file with the harvested one, removing both the live file and PDB from the
                            // file list.
                            Log.LogMessage($"Using reference {livePackagePath} from last stable package {PackageId}/{PackageVersion} rather than the built reference {liveFile.SourcePath} since it is the same API version.  Set <Preserve>true</Preserve> on {liveFile.SourceProject} if you'd like to avoid this..");
                            removeFiles.Add(liveFile.OriginalItem);

                            PackageItem livePdbFile;
                            if (livePackageFiles.TryGetValue(Path.ChangeExtension(livePackagePath, ".pdb"), out livePdbFile))
                            {
                                removeFiles.Add(livePdbFile.OriginalItem);
                            }
                        }
                        else
                        {
                            Log.LogMessage(LogImportance.Low, $"Including {livePackagePath} from last stable package {PackageId}/{PackageVersion}.");
                        }

                        var item = new TaskItem(packageFile);

                        if (liveFile?.OriginalItem != null)
                        {
                            // preserve all the meta-data from the live file that was replaced.
                            liveFile.OriginalItem.CopyMetadataTo(item);
                        }
                        else
                        {
                            if (includeItem != null)
                            {
                                includeItem.CopyMetadataTo(item);
                            }
                            var targetPath = Path.GetDirectoryName(livePackagePath).Replace('\\', '/');
                            item.SetMetadata("TargetPath", targetPath);
                            string targetFramework = GetTargetFrameworkFromPackagePath(targetPath);
                            item.SetMetadata("TargetFramework", targetFramework);
                            // only harvest for non-portable frameworks, matches logic in packaging.targets.
                            bool harvestDependencies = !targetFramework.StartsWith("portable-");
                            item.SetMetadata("HarvestDependencies", harvestDependencies.ToString());
                            item.SetMetadata("IsReferenceAsset", IsReferencePackagePath(targetPath).ToString());
                        }

                        if (assemblyVersion != null)
                        {
                            // overwrite whatever metadata may have been copied from the live file.
                            item.SetMetadata("AssemblyVersion", assemblyVersion.ToString());
                        }

                        item.SetMetadata("HarvestedFrom", $"{PackageId}/{PackageVersion}/{harvestPackagePath}");

                        harvestedFiles.Add(item);
                    }
                }
            }

            HarvestedFiles = harvestedFiles.ToArray();

            if (_pathsNotIncluded != null)
            {
                foreach (var pathNotIncluded in _pathsNotIncluded)
                {
                    Log.LogError($"Path '{pathNotIncluded}' was specified in {nameof(PathsToInclude)} but was not found in the package {PackageId}/{PackageVersion}.");
                }
            }

            if (Files != null)
            {
                UpdatedFiles = Files.Except(removeFiles).ToArray();
            }
        }