<commit_before>﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Calamari.Integration.Packages;
using Calamari.Util;
using NuGet;

namespace Calamari.Integration.FileSystem
{
    public class PackageStore
    {
        readonly ICalamariFileSystem fileSystem = CalamariPhysicalFileSystem.GetPhysicalFileSystem();
        readonly string rootDirectory = Path.Combine(TentacleHome, "Files");

        private static string TentacleHome
        {
            get
            {
                var tentacleHome = Environment.GetEnvironmentVariable("TentacleHome");
                if (tentacleHome == null)
                {
                    Log.Error("Environment variable 'TentacleHome' has not been set.");
                }
                return tentacleHome;
            }
        }

        public string GetPackagesDirectory()
        {
            return rootDirectory;
        }

        public StoredPackage GetPackage(string packageFullPath)
        {
            var zip = ReadZipPackage(packageFullPath);
            if (zip == null)
                return null;
            
            var package = ReadPackageFile(new ZipPackage(packageFullPath));
            if (package == null)
                return null;

            return new StoredPackage(package, packageFullPath);
        }

        public StoredPackage GetPackage(PackageMetadata metadata)
        {
            var name = GetNameOfPackage(metadata);
            fileSystem.EnsureDirectoryExists(rootDirectory);

            var files = fileSystem.EnumerateFilesRecursively(rootDirectory, name + ".nupkg-*");

            foreach (var file in files)
            {
                var storedPackage = GetPackage(file);
                if (storedPackage == null)
                    continue;

                if (!string.Equals(storedPackage.Metadata.Id, metadata.Id, StringComparison.OrdinalIgnoreCase) || !string.Equals(storedPackage.Metadata.Version, metadata.Version, StringComparison.OrdinalIgnoreCase))
                    continue;

                if (string.IsNullOrWhiteSpace(metadata.Hash))
                    return storedPackage;

                if (metadata.Hash == storedPackage.Metadata.Hash)
                    return storedPackage;
            }

            return null;
        }

        public IEnumerable<StoredPackage> GetNearestPackages(string packageId, SemanticVersion version, int take = 5)
        {
            fileSystem.EnsureDirectoryExists(rootDirectory);

            var zipPackages =
                from filePath in fileSystem.EnumerateFilesRecursively(rootDirectory, packageId + "*.nupkg-*")
                let zip = ReadZipPackage(filePath)
                where zip != null && zip.Id == packageId && zip.Version < version
                orderby zip.Version descending
                select new {zip, filePath};

            return
                from zipPackage in zipPackages.Take(take)
                let package = ReadPackageFile(zipPackage.zip)
                where package != null
                select new StoredPackage(package, zipPackage.filePath);
        }

        static ZipPackage ReadZipPackage(string file)
        {
            try
            {
                return new ZipPackage(file);
            }
            catch (IOException)
            {
                return null;
            }
            catch (FileFormatException)
            {
                return null;
            }
        }

        static PackageMetadata ReadPackageFile(IPackage zip)
        {
            try
            {
                using (var zipStream = zip.GetStream())
                {
                   return new PackageMetadata
                    {
                        Id = zip.Id,
                        Version = zip.Version.ToString(),
                        Hash = HashCalculator.Hash(zipStream),
                    };
                }
            }
            catch (IOException)
            {
                return null;
            }
        }

        static string GetNameOfPackage(PackageMetadata metadata)
        {
            return metadata.Id + "." + metadata.Version;
        }
    }
}
<commit_msg>Allow `GetNearestPackages` method to match the exact same package version. If one already exists it will likely already have been selected so this is more to make its functionality clearer rather than changing behavior.<commit_after>﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Calamari.Integration.Packages;
using Calamari.Util;
using NuGet;

namespace Calamari.Integration.FileSystem
{
    public class PackageStore
    {
        readonly ICalamariFileSystem fileSystem = CalamariPhysicalFileSystem.GetPhysicalFileSystem();
        readonly string rootDirectory = Path.Combine(TentacleHome, "Files");

        private static string TentacleHome
        {
            get
            {
                var tentacleHome = Environment.GetEnvironmentVariable("TentacleHome");
                if (tentacleHome == null)
                {
                    Log.Error("Environment variable 'TentacleHome' has not been set.");
                }
                return tentacleHome;
            }
        }

        public string GetPackagesDirectory()
        {
            return rootDirectory;
        }

        public StoredPackage GetPackage(string packageFullPath)
        {
            var zip = ReadZipPackage(packageFullPath);
            if (zip == null)
                return null;
            
            var package = ReadPackageFile(new ZipPackage(packageFullPath));
            if (package == null)
                return null;

            return new StoredPackage(package, packageFullPath);
        }

        public StoredPackage GetPackage(PackageMetadata metadata)
        {
            var name = GetNameOfPackage(metadata);
            fileSystem.EnsureDirectoryExists(rootDirectory);

            var files = fileSystem.EnumerateFilesRecursively(rootDirectory, name + ".nupkg-*");

            foreach (var file in files)
            {
                var storedPackage = GetPackage(file);
                if (storedPackage == null)
                    continue;

                if (!string.Equals(storedPackage.Metadata.Id, metadata.Id, StringComparison.OrdinalIgnoreCase) || !string.Equals(storedPackage.Metadata.Version, metadata.Version, StringComparison.OrdinalIgnoreCase))
                    continue;

                if (string.IsNullOrWhiteSpace(metadata.Hash))
                    return storedPackage;

                if (metadata.Hash == storedPackage.Metadata.Hash)
                    return storedPackage;
            }

            return null;
        }

        public IEnumerable<StoredPackage> GetNearestPackages(string packageId, SemanticVersion version, int take = 5)
        {
            fileSystem.EnsureDirectoryExists(rootDirectory);

            var zipPackages =
                from filePath in fileSystem.EnumerateFilesRecursively(rootDirectory, packageId + "*.nupkg-*")
                let zip = ReadZipPackage(filePath)
                where zip != null && zip.Id == packageId && zip.Version <= version
                orderby zip.Version descending
                select new {zip, filePath};

            return
                from zipPackage in zipPackages.Take(take)
                let package = ReadPackageFile(zipPackage.zip)
                where package != null
                select new StoredPackage(package, zipPackage.filePath);
        }

        static ZipPackage ReadZipPackage(string file)
        {
            try
            {
                return new ZipPackage(file);
            }
            catch (IOException)
            {
                return null;
            }
            catch (FileFormatException)
            {
                return null;
            }
        }

        static PackageMetadata ReadPackageFile(IPackage zip)
        {
            try
            {
                using (var zipStream = zip.GetStream())
                {
                   return new PackageMetadata
                    {
                        Id = zip.Id,
                        Version = zip.Version.ToString(),
                        Hash = HashCalculator.Hash(zipStream),
                    };
                }
            }
            catch (IOException)
            {
                return null;
            }
        }

        static string GetNameOfPackage(PackageMetadata metadata)
        {
            return metadata.Id + "." + metadata.Version;
        }
    }
}

{'fraction_non_alphanumeric': 0.07019375797656341, 'fraction_numerical': 0.00023204548091425919, 'mean_word_length': 1.5219426565242833, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1367279', 'n_tokens_mistral': 2066, 'n_tokens_neox': 1930, 'n_words': 467}