<commit_before>﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="PackageManager.cs" company="Naos">
//   Copyright 2015 Naos
// </copyright>
// --------------------------------------------------------------------------------------------------------------------

namespace Naos.Deployment.Core
{
    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.IO;
    using System.IO.Compression;
    using System.Linq;
    using System.Net;
    using System.Reflection;
    using System.Text;

    using Naos.Deployment.Contract;

    using NuGet;

    /// <summary>
    /// Implementation of the IManagePackages interface.
    /// </summary>
    public class PackageManager : IManagePackages
    {
        private readonly PackageRepositoryConfiguration repoConfig;
        private readonly string defaultWorkingDirectory;

        /// <summary>
        /// Initializes a new instance of the <see cref="PackageManager"/> class.
        /// </summary>
        /// <param name="repoConfig">Package repository configuration.</param>
        /// <param name="defaultWorkingDirectory">Working directory to download temporary files to.</param>
        public PackageManager(PackageRepositoryConfiguration repoConfig, string defaultWorkingDirectory)
        {
            this.repoConfig = repoConfig;
            this.defaultWorkingDirectory = defaultWorkingDirectory;
        }

        /// <summary>
        /// Designed to chain with the constructor this will make sure the default working directory is cleaned up (for failed previous runs).
        /// </summary>
        /// <returns>Current object to allow chaining with constructor.</returns>
        public PackageManager WithCleanWorkingDirectory()
        {
            if (Directory.Exists(this.defaultWorkingDirectory))
            {
                Directory.Delete(this.defaultWorkingDirectory, true);
            }

            Directory.CreateDirectory(this.defaultWorkingDirectory);
            return this;
        }

        /// <summary>
        /// Compares the distinct package IDs of two sets for equality.
        /// </summary>
        /// <param name="firstSet">First set of packages to compare.</param>
        /// <param name="secondSet">Second set of packages to compare.</param>
        /// <returns>Whether or not the distinct package IDs match exactly.</returns>
        public static bool DistinctPackageIdsMatchExactly(ICollection<PackageDescription> firstSet, ICollection<PackageDescription> secondSet)
        {
            if (firstSet.Count == 0 && secondSet.Count == 0)
            {
                return true;
            }

            var firstSetDistinctOrderedIds = firstSet.Select(_ => _.Id).ToList().Distinct().OrderBy(_ => _);
            var secondSetDistinctOrderedIds = secondSet.Select(_ => _.Id).ToList().Distinct().OrderBy(_ => _);

            var ret = firstSetDistinctOrderedIds.SequenceEqual(secondSetDistinctOrderedIds);
            return ret;
        }

        /// <inheritdoc />
        public ICollection<string> DownloadPackages(
            ICollection<PackageDescription> packageDescriptions,
            string workingDirectory,
            bool includeDependencies = false)
        {
            /*
             * This doesn't actually work, most likely because of the type of credentials I'm returning in the credential provider but I'm hacking around it for now...
                // credential override for below taken from: http://stackoverflow.com/questions/18594613/setting-the-package-credentials-using-nuget-core-dll
             */
            var settings = Settings.LoadDefaultSettings(null, null, null);
            var packageSource = new PackageSource(this.repoConfig.Source, this.repoConfig.SourceName)
                                    {
                                        UserName = this.repoConfig.Username,
                                        Password = this.repoConfig.<PASSWORD>,
                                        IsPasswordClearText = true
                                    };

            var packageSourceProvider = new PackageSourceProvider(settings, new[] { packageSource });
            var customCredentialProvider = new CustomCredentialProvider(this.repoConfig);
            var credentialProvider = new SettingsCredentialProvider(customCredentialProvider, packageSourceProvider);

            HttpClient.DefaultCredentialProvider = credentialProvider;

            // logic taken from: http://blog.nuget.org/20130520/Play-with-packages.html
            var nugetSourcesFilePath = Path.Combine(Environment.GetEnvironmentVariable("APPDATA") ?? ".", "Nuget\\NuGet.Config");
            var nugetSourcesFileObject = NuGetConfigFile.BuildConfigFileFromRepositoryConfiguration(this.repoConfig);
            var nugetSourcesFileContents = NuGetConfigFile.Serialize(nugetSourcesFileObject);
            File.WriteAllText(nugetSourcesFilePath, nugetSourcesFileContents, Encoding.UTF8);

            // This is where the file get evaluated so it must exist before reaching here...
            var repo = packageSourceProvider.CreateAggregateRepository(PackageRepositoryFactory.Default, true);

            var packageManager = new NuGet.PackageManager(repo, workingDirectory);

            if (!Directory.Exists(workingDirectory))
            {
                Directory.CreateDirectory(workingDirectory);
            }

            var workingDirectorySnapshotBefore = Directory.GetFiles(workingDirectory, "*", SearchOption.AllDirectories);

            foreach (var packageDescription in packageDescriptions)
            {
                var version = SemanticVersion.ParseOptionalVersion(packageDescription.Version);
                var ignoreDependencies = !includeDependencies;
                packageManager.InstallPackage(packageDescription.Id, version, ignoreDependencies, true);
            }

            var workingDirectorySnapshotAfter = Directory.GetFiles(workingDirectory, "*", SearchOption.AllDirectories);

            var ret =
                workingDirectorySnapshotAfter.Except(workingDirectorySnapshotBefore)
                    .Where(_ => _.EndsWith(".nupkg"))
                    .ToList();

            return ret;
        }

        /// <inheritdoc />
        public byte[] GetPackageFile(PackageDescription packageDescription, bool bundleAllDependencies = false)
        {
            var workingDirectory = Path.Combine(this.defaultWorkingDirectory, "Down-" + DateTime.Now.ToString("yyyy-MM-dd--HH-mm-ss--fff"));<commit_msg>Added public source and removed file writing logic.<commit_after>﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="PackageManager.cs" company="Naos">
//   Copyright 2015 Naos
// </copyright>
// --------------------------------------------------------------------------------------------------------------------

namespace Naos.Deployment.Core
{
    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.IO;
    using System.IO.Compression;
    using System.Linq;
    using System.Net;
    using System.Reflection;
    using System.Text;

    using Naos.Deployment.Contract;

    using NuGet;

    /// <summary>
    /// Implementation of the IManagePackages interface.
    /// </summary>
    public class PackageManager : IManagePackages
    {
        private readonly PackageRepositoryConfiguration repoConfig;
        private readonly string defaultWorkingDirectory;

        /// <summary>
        /// Initializes a new instance of the <see cref="PackageManager"/> class.
        /// </summary>
        /// <param name="repoConfig">Package repository configuration.</param>
        /// <param name="defaultWorkingDirectory">Working directory to download temporary files to.</param>
        public PackageManager(PackageRepositoryConfiguration repoConfig, string defaultWorkingDirectory)
        {
            this.repoConfig = repoConfig;
            this.defaultWorkingDirectory = defaultWorkingDirectory;
        }

        /// <summary>
        /// Designed to chain with the constructor this will make sure the default working directory is cleaned up (for failed previous runs).
        /// </summary>
        /// <returns>Current object to allow chaining with constructor.</returns>
        public PackageManager WithCleanWorkingDirectory()
        {
            if (Directory.Exists(this.defaultWorkingDirectory))
            {
                Directory.Delete(this.defaultWorkingDirectory, true);
            }

            Directory.CreateDirectory(this.defaultWorkingDirectory);
            return this;
        }

        /// <summary>
        /// Compares the distinct package IDs of two sets for equality.
        /// </summary>
        /// <param name="firstSet">First set of packages to compare.</param>
        /// <param name="secondSet">Second set of packages to compare.</param>
        /// <returns>Whether or not the distinct package IDs match exactly.</returns>
        public static bool DistinctPackageIdsMatchExactly(ICollection<PackageDescription> firstSet, ICollection<PackageDescription> secondSet)
        {
            if (firstSet.Count == 0 && secondSet.Count == 0)
            {
                return true;
            }

            var firstSetDistinctOrderedIds = firstSet.Select(_ => _.Id).ToList().Distinct().OrderBy(_ => _);
            var secondSetDistinctOrderedIds = secondSet.Select(_ => _.Id).ToList().Distinct().OrderBy(_ => _);

            var ret = firstSetDistinctOrderedIds.SequenceEqual(secondSetDistinctOrderedIds);
            return ret;
        }

        /// <inheritdoc />
        public ICollection<string> DownloadPackages(
            ICollection<PackageDescription> packageDescriptions,
            string workingDirectory,
            bool includeDependencies = false)
        {
            /*
             * This doesn't actually work, most likely because of the type of credentials I'm returning in the credential provider but I'm hacking around it for now...
                // credential override for below taken from: http://stackoverflow.com/questions/18594613/setting-the-package-credentials-using-nuget-core-dll
             */
            var settings = Settings.LoadDefaultSettings(null, null, null);
            var packageSource = new PackageSource(this.repoConfig.Source, this.repoConfig.SourceName)
                                    {
                                        UserName = this.repoConfig.Username,
                                        Password = <PASSWORD>,
                                        IsPasswordClearText = true
                                    };
            var publicPackageSource = new PackageSource(NuGetConfigFile.NuGetPublicGalleryUrl, NuGetConfigFile.NuGetPublicGalleryName);

            var packageSourceProvider = new PackageSourceProvider(settings, new[] { packageSource, publicPackageSource });
            var customCredentialProvider = new CustomCredentialProvider(this.repoConfig);
            var credentialProvider = new SettingsCredentialProvider(customCredentialProvider, packageSourceProvider);

            HttpClient.DefaultCredentialProvider = credentialProvider;
            /*
             * This was necessary for a while, it's unclear why it started working so leaving this for reference if necessary...
            var nugetSourcesFileDirectory = Path.Combine(Environment.GetEnvironmentVariable("APPDATA") ?? ".", "NuGet");
            var nugetSourcesFilePath = Path.Combine(nugetSourcesFileDirectory, "NuGet.Config");
            var nugetSourcesFileObject = NuGetConfigFile.BuildConfigFileFromRepositoryConfiguration(this.repoConfig);
            var nugetSourcesFileContents = NuGetConfigFile.Serialize(nugetSourcesFileObject);

            if (!Directory.Exists(nugetSourcesFileDirectory))
            {
                Directory.CreateDirectory(nugetSourcesFileDirectory);
            }

            File.WriteAllText(nugetSourcesFilePath, nugetSourcesFileContents, Encoding.UTF8);
            */

            // This is where the file get evaluated so it must exist before reaching here...
            var repo = packageSourceProvider.CreateAggregateRepository(PackageRepositoryFactory.Default, true);

            // logic taken from: http://blog.nuget.org/20130520/Play-with-packages.html
            var packageManager = new NuGet.PackageManager(repo, workingDirectory);

            if (!Directory.Exists(workingDirectory))
            {
                Directory.CreateDirectory(workingDirectory);
            }

            var workingDirectorySnapshotBefore = Directory.GetFiles(workingDirectory, "*", SearchOption.AllDirectories);

            foreach (var packageDescription in packageDescriptions)
            {
                var version = SemanticVersion.ParseOptionalVersion(packageDescription.Version);
                var ignoreDependencies = !includeDependencies;
                packageManager.InstallPackage(packageDescription.Id, version, ignoreDependencies, true);
            }

            var workingDirectorySnapshotAfter = Directory.GetFiles(workingDirectory, "*", SearchOption.AllDirectories);

            var ret =
                workingDirectorySnapshotAfter.Except(workingDirectorySnapshotBefore)
                    .Where(_ => _.EndsWith(".nupkg"))
                    .ToList();

            return ret;
        }

        /// <inheritdoc />
        public byte[] GetPackageFile(PackageDescription packageDescription, bool bundleAllDependencies = false)
        {
            var workingDirectory = Path.Combine(this.defaultWorkingDirectory, "Down-" + DateTime.Now.ToString("yyyy-MM-dd--HH-mm-ss--fff"));
{'fraction_non_alphanumeric': 0.11834703591518823, 'fraction_numerical': 0.0033174671859224, 'mean_word_length': 2.099463567277604, 'pattern_counts': {'":': 0, '<': 63, '<?xml version=': 0, '>': 73, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6186210', 'n_tokens_mistral': 3136, 'n_tokens_neox': 2967, 'n_words': 734}