Exemple #1
0
        public async Task <PackagesLock> DownloadModuleLock(string outputPath, IEnumerable <string> loadOnStartup)
        {
            var modulesLock = await ModulesResource.FetchModules(PrismModule.ClientFramework, _restClient);

            var requiredPackages = new Dictionary <PackageIdentity, IImmutableList <PackageIdentity> >();

            void AddPackages(IEnumerable <PackageIdentity> identities)
            {
                foreach (var identity in identities)
                {
                    if (!requiredPackages.ContainsKey(identity))
                    {
                        var dependencies = modulesLock[identity];
                        requiredPackages.Add(identity, dependencies);
                        AddPackages(dependencies);
                    }
                }
            }

            AddPackages(loadOnStartup.Select(x => modulesLock.First(y => y.Key.Id.Equals(x, StringComparison.OrdinalIgnoreCase)).Key));

            var requiredPackagesLock = new PackagesLock(requiredPackages);

            _fileSystem.File.WriteAllText(_fileSystem.Path.Combine(outputPath, "modules.lock"), JsonConvert.SerializeObject(requiredPackagesLock));

            return(requiredPackagesLock);
        }
Exemple #2
0
        private PackageLockStatus CheckPackageLockStatus(PackagesLock currentLock, PackagesLock newLock)
        {
            foreach (var packageLockEntry in newLock)
            {
                if (currentLock.TryGetValue(packageLockEntry.Key, out var dependencies))
                {
                    if (!packageLockEntry.Value.ScrambledEquals(dependencies))
                    {
                        return
                            (PackageLockStatus.Changed); //something seems fishy as the dependencies don't match even if the package versions are equal
                    }
                }
                else if (currentLock.Any(x => string.Equals(x.Key.Id, packageLockEntry.Key.Id, StringComparison.OrdinalIgnoreCase)))
                {
                    //version changed
                    return(PackageLockStatus.Changed);
                }
                else
                {
                    return(PackageLockStatus.PackagesAddedOrRemoved);
                }
            }

            if (currentLock.Any(x => !newLock.Any(y => string.Equals(y.Key.Id, x.Key.Id, StringComparison.OrdinalIgnoreCase))))
            {
                return(PackageLockStatus.PackagesAddedOrRemoved);
            }

            //we don't really care if packages were removed
            return(PackageLockStatus.Equal);
        }
Exemple #3
0
        public bool Verify(PackagesLock packagesLock)
        {
            var packagesLockFile = _fileSystem.FileInfo.FromFileName(Environment.ExpandEnvironmentVariables(_options.ModulesLockPath));

            if (!packagesLockFile.Exists)
            {
                _fileSystem.File.WriteAllText(packagesLockFile.FullName, JsonConvert.SerializeObject(packagesLock));
                return(true);
            }

            var currentPackagesLock = JsonConvert.DeserializeObject <PackagesLock>(_fileSystem.File.ReadAllText(packagesLockFile.FullName));
            var status = CheckPackageLockStatus(currentPackagesLock, packagesLock);

            if (status == PackageLockStatus.Equal)
            {
                return(true);
            }

            _fileSystem.File.WriteAllText(packagesLockFile.FullName, JsonConvert.SerializeObject(packagesLock));

            if (status == PackageLockStatus.PackagesAddedOrRemoved)
            {
                return(true); //packages can be added
            }
            //if status == PackageLockStatus.Changed
            return(false);
        }
Exemple #4
0
        public async Task Load(IEnumerable <PackageIdentity> primaryPackages, PackagesLock packagesLock)
        {
            var mapper = new ModuleMapper(_project.Framework, _project.ModulesDirectory, _project.Runtime, _project.Architecture);
            var map    = mapper.BuildMap(packagesLock);

            var dependencyPaths = new Dictionary <AssemblyName, AssemblyInfo>(new AssemblyNameComparer());

            _dependencyAssemblies = dependencyPaths;

            while (map.TryPop(out var dependencyLayer))
            {
                foreach (var context in dependencyLayer.Where(x => !x.IsMazeModule))
                {
                    foreach (var file in Directory.GetFiles(context.LibraryDirectory, "*.dll"))
                    {
                        dependencyPaths.Add(AssemblyName.GetAssemblyName(file), new AssemblyInfo(file));
                    }
                }

                await TaskCombinators.ThrottledAsync(dependencyLayer.Where(x => x.IsMazeModule), (context, token) => Task.Run(() =>
                {
                    foreach (var file in Directory.GetFiles(context.LibraryDirectory, "*.dll"))
                    {
                        var assembly = _assemblyLoadContext.LoadFromAssemblyPath(file);

                        var typeDiscoveryService = new TypeDiscoveryService(assembly, context.Package);
                        typeDiscoveryService.DiscoverTypes(ModuleTypeMap);
                    }
                }), CancellationToken.None);
            }
        }
Exemple #5
0
        public async Task <IReadOnlyList <PackageCarrier> > Load(PackagesLock packagesLock)
        {
            var mapper       = new ModuleMapper(_framework, _modulesDirectory, Runtime.Windows, Environment.Is64BitProcess ? Architecture.x64 : Architecture.x86);
            var packageStack = mapper.BuildMap(packagesLock);

            var loadedPackages = new ConcurrentBag <PackageCarrier>();

            while (packageStack.Any())
            {
                var dependencyLayer = packageStack.Pop();

                await TaskCombinators.ThrottledAsync(dependencyLayer, (context, token) =>
                {
                    return(Task.Run(() =>
                    {
                        foreach (var module in LoadModule(context))
                        {
                            loadedPackages.Add(module);
                        }
                    }));
                }, CancellationToken.None);
            }

            Packages = Packages.AddRange(loadedPackages);

            return(loadedPackages.ToList());
        }
        public void Synchronize(List <ClientConfigurationDataDto> configurations, PackagesLock packagesLock)
        {
            var configurationDirectory = _fileSystem.DirectoryInfo.FromDirectoryName(Environment.ExpandEnvironmentVariables(Program.ConfigDirectory));
            var existingConfigurations = configurationDirectory.GetFiles("mazesettings*.json")
                                         .Select(x => Regex.Match(x.Name, "mazesettings([0-9])\\.json")).Select(x => x.Success ? int.Parse(x.Groups[0].Value) : (int?)null);

            foreach (var configurationId in existingConfigurations.Where(x => configurations.All(y => y.ClientGroupId != x)))
            {
                _fileSystem.File.Delete(Path.Combine(Program.ConfigDirectory, $"mazesettings{configurationId}.json"));
            }

//            var filesProvider = new MemoryFileProvider(configurations.ToDictionary(x => $"mazesettings{x.ClientGroupId}.json", x => x.Content));
//            var configBuilder = new ConfigurationBuilder();
//#if DEBUG
//            configBuilder.AddJsonFile("mazesettings.json");
//#endif
//            foreach (var configuration in configurations)
//            {
//                configBuilder.AddJsonFile(filesProvider, $"mazesettings{configuration.ClientGroupId}.json", optional: false, reloadOnChange: false);
//            }

            //var configurationRoot = configBuilder.Build();
            ////var modules = configurationRoot.GetSection("LoadOnStartup").GetChildren();
            ////var packagesConfig = packagesLock; //TrimPackagesLock(modules.Select(x => x.Key), packagesLock);

            //_fileSystem.File.WriteAllText(Environment.ExpandEnvironmentVariables(_options.ModulesLockPath),
            //    JsonConvert.SerializeObject(packagesConfig));

            foreach (var configuration in configurations)
            {
                var filename = Path.Combine(Environment.ExpandEnvironmentVariables(Program.ConfigDirectory), $"mazesettings{configuration.ClientGroupId}.json");
                _fileSystem.File.WriteAllText(filename, configuration.Content);
            }
        }
        public async Task EnsurePackagesInstalled(PackagesLock packagesLock)
        {
            var resources = _project.PrimarySources.Concat(_project.DependencySources)
                            .ToImmutableDictionary(x => x.GetResource <FindPackageByIdResource>(), x => x);
            var cache = GetDefaultResolutionContext().SourceCacheContext;

            var actions = (await TaskCombinators.ThrottledAsync(packagesLock, async(package, token) =>
            {
                if (!_project.ModulesDirectory.ModuleExists(package.Key))
                {
                    foreach (var(resource, repo) in resources)
                    {
                        var versions =
                            await resource.GetAllVersionsAsync(package.Key.Id, cache, _logger, CancellationToken.None);
                        if (versions.Any(x => x == package.Key.Version))
                        {
                            return(ResolvedAction.CreateInstall(package.Key, repo));
                        }
                    }
                }
                return(null);
            }, CancellationToken.None)).Where(x => x != null).ToList();

            if (actions.Any())
            {
                await ExecuteActionsAsync(actions, GetDefaultDownloadContext(), CancellationToken.None);
            }
        }
Exemple #8
0
        public async Task <PackageLockContext> Load(PackagesLock packagesLock)
        {
            if (packagesLock?.Any() != true)
            {
                return(new PackageLockContext(_catalog));
            }

            var packages = await _catalog.Load(packagesLock);

            return(new PackageLockContext(packages, _packagesRegistrar, _catalog));
        }
        public async Task <Dictionary <PackageIdentity, PackagePreFetcherResult> > DownloadPackages(
            PackagesLock packagesLock, PackageDownloadContext downloadContext, ILogger logger, CancellationToken token)
        {
            var packages   = packagesLock.Keys.Concat(packagesLock.SelectMany(x => x.Value)).Distinct();
            var toDownload = new Queue <PackageIdentity>();
            var result     = new Dictionary <PackageIdentity, PackagePreFetcherResult>();

            foreach (var package in packages)
            {
                if (_modulesDirectory.ModuleExists(package))
                {
                    continue;
                }

                toDownload.Enqueue(package);
            }

            if (toDownload.Any())
            {
                var maxParallelTasks = PackageManagementConstants.DefaultMaxDegreeOfParallelism;

                var downloadResults = new List <PackagePreFetcherResult>(maxParallelTasks);

                while (toDownload.Count > 0)
                {
                    // Throttle tasks
                    if (downloadResults.Count == maxParallelTasks)
                    {
                        // Wait for a task to complete
                        // This will not throw, exceptions are stored in the result
                        await Task.WhenAny(downloadResults.Select(e => e.EnsureResultAsync()));

                        // Remove all completed tasks
                        downloadResults.RemoveAll(e => e.IsComplete);
                    }

                    var package = toDownload.Dequeue();

                    // Download the package if it does not exist in the packages folder already
                    // Start the download task
                    var task = Task.Run(
                        async() => await PackageDownloader.GetDownloadResourceResultAsync(_sourceRepository, package,
                                                                                          downloadContext, "NO_GLOBAL_CACHE_DIRECTORY", logger, token), token);

                    var downloadResult = new PackagePreFetcherResult(task, package, _sourceRepository.PackageSource);

                    downloadResults.Add(downloadResult);
                    result.Add(package, downloadResult);
                }
            }

            return(result);
        }
Exemple #10
0
        private static void SearchDependencies(PackageIdentity packageIdentity, PackagesLock packagesLock,
                                               IDictionary <PackageIdentity, int> map, int level)
        {
            if (!map.TryGetValue(packageIdentity, out var currentLevel) || level > currentLevel)
            {
                map[packageIdentity] = level;
            }

            foreach (var dependency in packagesLock[packageIdentity])
            {
                SearchDependencies(dependency, packagesLock, map, level + 1);
            }
        }
Exemple #11
0
        public async Task Load(PackagesLock packagesLock, IServerInfo serverInfo, CancellationToken token)
        {
            var serverRepo = new ServerRepository(new Uri(serverInfo.ServerUri, "nuget"));

            var context = new PackageDownloadContext(new SourceCacheContext {
                DirectDownload = true, NoCache = true
            },
                                                     Environment.ExpandEnvironmentVariables(_options.TempPath), true);

            var packageDownloadManager = new PackageDownloadManager(_modulesDirectory, serverRepo);
            var result =
                await packageDownloadManager.DownloadPackages(packagesLock, context, NullLogger.Instance, token);

            if (result.Any())
            {
                try
                {
                    foreach (var preFetchResult in result.Values)
                    {
                        using (var downloadPackageResult = await preFetchResult.GetResultAsync())
                        {
                            // use the version exactly as specified in the nuspec file
                            var packageIdentity = await downloadPackageResult.PackageReader.GetIdentityAsync(token);

                            var packageExtractionContext = new PackageExtractionContext(
                                PackageSaveMode.Defaultv3,
                                PackageExtractionBehavior.XmlDocFileSaveMode,
                                ClientPolicyContext.GetClientPolicy(new NullSettings(), new NullLogger()),
                                new NullLogger());

                            downloadPackageResult.PackageStream.Position = 0;

                            await PackageExtractor.InstallFromSourceAsync(serverRepo.PackageSource.Source,
                                                                          packageIdentity, stream => downloadPackageResult.PackageStream.CopyToAsync(stream),
                                                                          _modulesDirectory.VersionFolderPathResolver, packageExtractionContext, token);
                        }
                    }
                }
                finally
                {
                    foreach (var fetcherResult in result.Values)
                    {
                        await fetcherResult.EnsureResultAsync();

                        fetcherResult.Dispose();
                    }
                }
            }
        }
Exemple #12
0
        /// <summary>
        ///     Build a module loader map that determines in which order which packages must be loaded
        /// </summary>
        /// <param name="packagesLock">The packages lock</param>
        /// <returns>Return a stack of dependency lists that can be loaded in parallel</returns>
        public Stack <List <PackageLoadingContext> > BuildMap(PackagesLock packagesLock)
        {
            var levelMap = new Dictionary <PackageIdentity, int>(PackageIdentity.Comparer);

            foreach (var packageIdentity in packagesLock.Keys)
            {
                SearchDependencies(packageIdentity, packagesLock, levelMap, 0);
            }

            var result = new Stack <List <PackageLoadingContext> >();

            //the first item of this foreach loop must be loaded last (because it has the lowest level)
            foreach (var levelGroup in levelMap.GroupBy(x => x.Value).OrderBy(x => x.Key))
            {
                var levelList = new List <PackageLoadingContext>();

                foreach (var packageIdentity in levelGroup.Select(x => x.Key))
                {
                    if (!ModulesDirectory.ModuleExists(packageIdentity))
                    {
                        throw new FileNotFoundException($"The package {packageIdentity} was not found.");
                    }

                    var packageDirectory =
                        ModulesDirectory.VersionFolderPathResolver.GetInstallPath(packageIdentity.Id,
                                                                                  packageIdentity.Version);
                    var resolvedDirectory = LoadResolver.ResolveNuGetFolder(packageDirectory, MazeFramework, Runtime, Architecture);
                    if (resolvedDirectory == null) //maybe build only package?
                    {
                        continue;
                    }

                    levelList.Add(new PackageLoadingContext(packageIdentity, packageDirectory, resolvedDirectory.Directory.FullName,
                                                            resolvedDirectory.Framework, resolvedDirectory.Framework.Framework == MazeFramework.Framework));
                }

                result.Push(levelList);
            }

            return(result);
        }
Exemple #13
0
        public async Task <PackagesLock> DownloadModuleLock(string outputPath, IEnumerable <string> loadOnStartup)
        {
            var modulesLock = await ModulesResource.FetchModules(PrismModule.ClientFramework, _restClient);

            var requiredPackages = new Dictionary <PackageIdentity, IImmutableList <PackageIdentity> >();

            void AddPackages(IEnumerable <PackageIdentity> identities)
            {
                foreach (var identity in identities)
                {
                    if (!requiredPackages.ContainsKey(identity))
                    {
                        var dependencies = modulesLock[identity];
                        requiredPackages.Add(identity, dependencies);
                        AddPackages(dependencies);
                    }
                }
            }

            var loadOnStartupPackages = new List <PackageIdentity>();

            foreach (var module in loadOnStartup)
            {
                var lockedPackage = modulesLock.Where(y => y.Key.Id.Equals(module, StringComparison.OrdinalIgnoreCase));
                if (!lockedPackage.Any())
                {
                    _logger.LogWarning($"The module {module} is not installed on the server and cannot be loaded on startup. Please remove it from the config.");
                    continue;
                }

                loadOnStartupPackages.Add(lockedPackage.First().Key);
            }

            AddPackages(loadOnStartupPackages);

            var requiredPackagesLock = new PackagesLock(requiredPackages);

            _fileSystem.File.WriteAllText(_fileSystem.Path.Combine(outputPath, "modules.lock"), JsonConvert.SerializeObject(requiredPackagesLock));

            return(requiredPackagesLock);
        }
Exemple #14
0
 public ServerConnection(MazeRestClient restClient, PackagesLock packagesLock, MazeSocketOptions options)
 {
     _options     = options;
     RestClient   = restClient;
     PackagesLock = packagesLock;
 }
Exemple #15
0
        public async Task <Dictionary <PackageIdentity, FileInfoBase> > LoadPackages(PackagesLock packagesLock, DirectoryInfoBase tempDirectory,
                                                                                     CancellationToken cancellationToken)
        {
            var result             = new Dictionary <PackageIdentity, FileInfoBase>();
            var packagesToDownload = new List <PackageIdentity>();

            foreach (var packageId in packagesLock.Keys)
            {
                var filePath = _versionFolderPathResolver.GetPackageFilePath(packageId.Id, packageId.Version);
                var file     = _fileSystem.FileInfo.FromFileName(filePath);
                if (file.Exists)
                {
                    _logger.LogDebug("Package {packageId} could be resolved locally at {path}", packageId, file.FullName);
                    result.Add(packageId, file);
                }
                else
                {
                    _logger.LogDebug("Package {packageId} could not be resolved locally", packageId);
                    packagesToDownload.Add(packageId);
                }

                cancellationToken.ThrowIfCancellationRequested();
            }

            if (packagesToDownload.Any())
            {
                _logger.LogInformation("{0} package(s) were not found locally and will be downloaded.", packagesToDownload.Count);

                var nugetFolder            = tempDirectory.CreateSubdirectory("nuget");
                var tempFolderPathResolver = new VersionFolderPathResolverFlat(nugetFolder.FullName);

                var serverRepo = new ServerRepository(new Uri(_restClient.Server.ServerUri, "nuget"));
                var downloader = new PackageDownloadManager(new ModulesDirectory(tempFolderPathResolver), serverRepo);

                var results = await downloader.DownloadPackages(
                    new PackagesLock(packagesToDownload.ToDictionary(x => x,
                                                                     _ => (IImmutableList <PackageIdentity>)ImmutableList <PackageIdentity> .Empty)),
                    new PackageDownloadContext(new SourceCacheContext {
                    DirectDownload = true, NoCache = true
                }, nugetFolder.FullName, true),
                    new NuGetLoggerWrapper(_logger), cancellationToken);

                try
                {
                    foreach (var preFetchResult in results.Values)
                    {
                        using (var downloadPackageResult = await preFetchResult.GetResultAsync())
                        {
                            var packageIdentity = await downloadPackageResult.PackageReader.GetIdentityAsync(cancellationToken);

                            _logger.LogInformation("Package {0} was successfully downloaded.", packageIdentity);

                            var fileStream = (FileStream)downloadPackageResult.PackageStream;
                            var file       = _fileSystem.FileInfo.FromFileName(fileStream.Name);
                            if (!file.Exists)
                            {
                                _logger.LogError("Package {0} was not found at {1}. The download may have failed.", packageIdentity, file.FullName);
                                throw new FileNotFoundException($"The file {file.FullName} does not exist.");
                            }

                            var packagePath = _fileSystem.Path.Combine(_fileSystem.Path.GetDirectoryName(file.FullName), packageIdentity + ".nupkg");
                            using (var stream = _fileSystem.FileStream.Create(packagePath, FileMode.CreateNew))
                                await fileStream.CopyToAsync(stream);

                            result.Add(packageIdentity, _fileSystem.FileInfo.FromFileName(packagePath));
                        }
                    }
                }
                finally
                {
                    foreach (var fetcherResult in results.Values)
                    {
                        await fetcherResult.EnsureResultAsync();

                        fetcherResult.Dispose();
                    }
                }
            }

            return(result);
        }
Exemple #16
0
        public async Task SetServerModulesLock(IReadOnlyList <PackageIdentity> primaryModules, PackagesLock serverLock)
        {
            await _modulesConfig.Replace(primaryModules);

            await ModulesLock.Replace(new Dictionary <NuGetFramework, PackagesLock> {
                { Framework, serverLock }
            });
        }
Exemple #17
0
 public Task AddModulesLock(NuGetFramework framework, PackagesLock packagesLock)
 {
     return(ModulesLock.Add(framework, packagesLock));
 }