private void UpdateTemplateListFromCache(TemplateCache cache, ISet <ITemplateInfo> templates)
 {
     using (Timing.Over(_environmentSettings.Host, "Enumerate infos"))
         templates.UnionWith(cache.TemplateInfo);
 }
Exemple #2
0
        public static void InstallPackage(IReadOnlyList <string> packages, bool quiet)
        {
            Init();
            RemoteWalkContext context = new RemoteWalkContext();

            ILogger            logger       = new NullLogger();
            SourceCacheContext cacheContext = new SourceCacheContext
            {
                IgnoreFailedSources = true
            };

            foreach (SourceRepository repo in Repos)
            {
                if (!repo.PackageSource.IsLocal)
                {
                    context.RemoteLibraryProviders.Add(new SourceRepositoryDependencyProvider(repo, logger, cacheContext));
                }
                else
                {
                    context.LocalLibraryProviders.Add(new SourceRepositoryDependencyProvider(repo, logger, cacheContext));
                }
            }

            Paths.User.Content.CreateDirectory();
            RemoteDependencyWalker walker                        = new RemoteDependencyWalker(context);
            HashSet <Package>      remainingPackages             = new HashSet <Package>(packages.Select(x => new Package(x, VersionRange.All)));
            HashSet <Package>      encounteredPackages           = new HashSet <Package>();
            List <string>          templateRoots                 = new List <string>();
            List <KeyValuePair <string, string> > componentRoots = new List <KeyValuePair <string, string> >();

            while (remainingPackages.Count > 0)
            {
                HashSet <Package> nextRound = new HashSet <Package>();

                foreach (Package package in remainingPackages)
                {
                    string name = package.PackageId;
                    GraphNode <RemoteResolveResult> result = walker.WalkAsync(new LibraryRange(name, package.Version, LibraryDependencyTarget.All), NuGetFramework.AnyFramework, "", RuntimeGraph.Empty, true).Result;
                    RemoteMatch     match           = result.Item.Data.Match;
                    PackageIdentity packageIdentity = new PackageIdentity(match.Library.Name, match.Library.Version);

                    nextRound.UnionWith(result.Item.Data.Dependencies.Select(x => new Package(x.Name, x.LibraryRange.VersionRange)));

                    VersionFolderPathContext versionFolderPathContext = new VersionFolderPathContext(
                        packageIdentity,
                        Paths.User.PackageCache,
                        new NullLogger(),
                        packageSaveMode: PackageSaveMode.Defaultv3,
                        xmlDocFileSaveMode: XmlDocFileSaveMode.Skip,
                        fixNuspecIdCasing: true,
                        normalizeFileNames: true);

                    if (match.Library.Version == null)
                    {
                        if (!quiet)
                        {
                            throw new Exception($"Package '{package.PackageId}' version {package.Version} could not be located.");
                        }
                        else
                        {
                            continue;
                        }
                    }

                    string source = Path.Combine(Paths.User.PackageCache, match.Library.Name, match.Library.Version.ToString());

                    if (!source.Exists() && match.Provider != null)
                    {
                        PackageExtractor.InstallFromSourceAsync(
                            stream => match.Provider.CopyToAsync(match.Library, stream, CancellationToken.None),
                            versionFolderPathContext,
                            CancellationToken.None).Wait();

                        string target = Path.Combine(Paths.User.Content, match.Library.Name);
                        target.CreateDirectory();
                        target = Path.Combine(target, match.Library.Version.ToString());
                        target.CreateDirectory();
                        Paths.Copy(source, target);
                        target.Delete("*.nupkg", "*.nupkg.*");

                        string nuspec = target.EnumerateFiles("*.nuspec").FirstOrDefault();

                        //If there's a nuspec, figure out whether this package is a template and walk the dependency graph
                        if (nuspec?.Exists() ?? false)
                        {
                            XDocument doc = XDocument.Load(nuspec);
                            IReadOnlyList <PackageType> types = NuspecUtility.GetPackageTypes(doc.Root.Element(XName.Get("metadata", "http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd")), false);
                            //If the thing we got is a template...
                            if (types.Any(x => string.Equals(x.Name, "template", StringComparison.OrdinalIgnoreCase)))
                            {
                                templateRoots.Add(target);
                            }
                            else
                            {
                                componentRoots.Add(new KeyValuePair <string, string>(match.Library.Name, match.Library.Version.ToString()));
                            }
                        }
                    }
                }

                encounteredPackages.UnionWith(remainingPackages);
                nextRound.ExceptWith(encounteredPackages);
                remainingPackages = nextRound;
            }

            foreach (KeyValuePair <string, string> package in componentRoots)
            {
                foreach (string path in Path.Combine(Paths.User.Content, package.Key, package.Value).EnumerateFiles($"{package.Key}.dll", SearchOption.AllDirectories))
                {
                    if (path.IndexOf($"{Path.DirectorySeparatorChar}lib{Path.DirectorySeparatorChar}", StringComparison.OrdinalIgnoreCase) < 0 ||
                        (path.IndexOf($"{Path.DirectorySeparatorChar}netstandard1.", StringComparison.OrdinalIgnoreCase) < 0 &&
                         path.IndexOf($"{Path.DirectorySeparatorChar}netcoreapp1.", StringComparison.OrdinalIgnoreCase) < 0))
                    {
                        continue;
                    }

#if !NET451
                    Assembly asm = AssemblyLoadContext.Default.LoadFromAssemblyPath(path);
#else
                    Assembly asm = Assembly.LoadFile(path);
#endif
                    foreach (Type type in asm.GetTypes())
                    {
                        SettingsLoader.Components.Register(type);
                    }
                }
            }

            TemplateCache.Scan(templateRoots);
        }
Exemple #3
0
 public SettingsLoader(IEngineEnvironmentSettings environmentSettings)
 {
     _environmentSettings = environmentSettings;
     _paths             = new Paths(environmentSettings);
     _userTemplateCache = new TemplateCache(environmentSettings);
 }
 private static void LoadTemplates(TemplateCache cache, ISet <ITemplateInfo> templates)
 {
     using (Timing.Over("Enumerate infos"))
         templates.UnionWith(cache.TemplateInfo);
 }
Exemple #5
0
        private async Task <TemplateCache> UpdateTemplateCacheAsync(bool needsRebuild)
        {
            // Kick off gathering template packages, so parsing cache can happen in parallel.
            Task <IReadOnlyList <ITemplatePackage> > getTemplatePackagesTask = _templatePackagesManager.GetTemplatePackagesAsync(needsRebuild);

            if (!(_userTemplateCache is TemplateCache cache))
            {
                cache = new TemplateCache(JObject.Parse(_paths.ReadAllText(_paths.TemplateCacheFile, "{}")));
            }

            if (cache.Version == null)
            {
                // Null version means, parsing cache failed.
                needsRebuild = true;
            }

            if (!needsRebuild && cache.Version != TemplateInfo.CurrentVersion)
            {
                _environmentSettings.Host.LogDiagnosticMessage(
                    $"Template cache file version is {cache.Version}, but template engine is {TemplateInfo.CurrentVersion}, rebuilding cache.",
                    "Debug");
                needsRebuild = true;
            }

            if (!needsRebuild && cache.Locale != CultureInfo.CurrentUICulture.Name)
            {
                _environmentSettings.Host.LogDiagnosticMessage(
                    $"Template cache locale is {cache.Locale}, but CurrentUICulture is {CultureInfo.CurrentUICulture.Name}, rebuilding cache.",
                    "Debug");
                needsRebuild = true;
            }

            var allTemplatePackages = await getTemplatePackagesTask.ConfigureAwait(false);

            var mountPoints = new Dictionary <string, DateTime>();

            foreach (var package in allTemplatePackages)
            {
                mountPoints[package.MountPointUri] = package.LastChangeTime;

                // We can stop comparing, but we need to keep looping to fill mountPoints
                if (!needsRebuild)
                {
                    if (cache.MountPointsInfo.TryGetValue(package.MountPointUri, out var cachedLastChangeTime))
                    {
                        if (package.LastChangeTime > cachedLastChangeTime)
                        {
                            needsRebuild = true;
                        }
                    }
                    else
                    {
                        needsRebuild = true;
                    }
                }
            }

            // Check that some mountpoint wasn't removed...
            if (!needsRebuild && mountPoints.Keys.Count != cache.MountPointsInfo.Count)
            {
                needsRebuild = true;
            }

            // Cool, looks like everything is up to date, exit
            if (!needsRebuild)
            {
                return(cache);
            }

            var scanResults = new List <(ITemplatePackage Package, ScanResult ScanResult)>();

            Parallel.ForEach(allTemplatePackages, (package) =>
            {
                try
                {
                    var scanResult = _installScanner.Scan(package.MountPointUri);
                    lock (scanResults)
                    {
                        scanResults.Add((package, scanResult));
                    }
                }
                catch (Exception ex)
                {
                    _environmentSettings.Host.OnNonCriticalError(null, $"Failed to scan \"{package.MountPointUri}\":{Environment.NewLine}{ex}", null, 0);
                }
            });

            cache = new TemplateCache(
                scanResults.OrderBy((p) => (p.Package.Provider.Factory as IPrioritizedComponent)?.Priority ?? 0).Select((pair) => pair.ScanResult),
                mountPoints
                );
            JObject serialized = JObject.FromObject(cache);

            _paths.WriteAllText(_paths.TemplateCacheFile, serialized.ToString());
            return(_userTemplateCache = cache);
        }