Home: Some functions to find local packages in the V3 doesn't seems work

Created on 29 Jul 2017  路  2Comments  路  Source: NuGet/Home

Introduction

Thanks for this amazing library. I used the nugget v2 and everything works perfectly. Recently, I upgrade my v2 code to use the v3, because there are a lot of packages that throw errors indicating to use the nuget v3.

I try to find some documentation, but the only interesting thing I found is this guide.
It helps to understand the basics.

Details about the problem

Some v3 functions doesn't seems to return expected packages.

Specs

  • NuGet product used : Nuget.Client
  • NuGet.Client Version=4.2.0.0
  • Visual Studio 2017 Entreprise
  • OS version : Win10 v1703 15063.483:

Detailed repro steps so we can see the same problem

Here's some code.

  1. Initialize the source repository

```c#
List> providers = new List>();
providers.AddRange(Repository.Provider.GetCoreV3());

PackageSource packageSource = new PackageSource("https://api.nuget.org/v3/index.json");
SourceRepository sourceRepository = new SourceRepository(packageSource, providers);
Logger logger = new Logger();


2. Search Newtonsoft.Json package

```c#
PackageSearchResource searchResource = await sourceRepository
            .GetResourceAsync<PackageSearchResource>();
 var supportedFramework = new[] { ".NETFramework,Version=v4.6" };
            var searchFilter = new SearchFilter(true)
            {
                SupportedFrameworks = supportedFramework,
                IncludeDelisted = false
            };

 var jsonNugetPackages = await searchResource
            .SearchAsync("Newtonsoft.Json", searchFilter, 0, 10, logger, CancellationToken.None);
  1. Initialize the Nuget package manager

```c#
var rootPath = @"myPathToTheFolder";
ISettings settings = Settings.LoadDefaultSettings(rootPath, null, new MachineWideSettings());
PackageSourceProvider packageSourceProvider = new PackageSourceProvider(settings);
ISourceRepositoryProvider sourceRepositoryProvider =
new SourceRepositoryProvider(packageSourceProvider, providers);

FolderNuGetProject project = new FolderNuGetProject(rootPath);
NuGetPackageManager packageManager = new NuGetPackageManager(
sourceRepositoryProvider, settings, rootPath)
{
PackagesFolderNuGetProject = project
};


4. Install Newtonsoft.Json package

```c#
var allowPrereleaseVersions = true;
var allowUnlisted = false;
INuGetProjectContext projectContext = new ProjectContext();
ResolutionContext resolutionContext = new ResolutionContext(
                DependencyBehavior.Lowest,
                allowPrereleaseVersions,
                allowUnlisted,
                VersionConstraints.None);

var jsonPackage = jsonNugetPackages.First();
var identity = new PackageIdentity(jsonPackage.Identity.Id, jsonPackage.Identity.Version);
await packageManager.InstallPackageAsync(
                 project,
                 identity,
                 resolutionContext,
                 projectContext,
                 sourceRepository,
                 new List<SourceRepository>(),
                 CancellationToken.None);
  1. Use the functions to find the local package

```c#
//Old V2 code to find the package (works)
/*
LocalPackageRepository repo1 = new LocalPackageRepository(rootPath);
var newtonsoft = repo1.FindPackagesById(jsonPackage.Identity.Id).First();
//return the package and the assembly property because it's v2
*/

FindLocalPackagesResourceV3 repo2 = new FindLocalPackagesResourceV3(rootPath);
var packageNotFound = repo2.GetPackages(logger, CancellationToken.None).FirstOrDefault();
// I don't know why it is null. It should be found.

FindLocalPackagesResourceV2 repo3 = new FindLocalPackagesResourceV2(rootPath);
var packageFound2 = repo3.GetPackages(logger, CancellationToken.None).FirstOrDefault();
//found and missing assemblies property (dll)

NuGetv3LocalRepository localRepositoryV3 = new NuGetv3LocalRepository(rootPath);
var newtonsoftToFound = localRepositoryV3.FindPackagesById(jsonPackage.Identity.Id)
.FirstOrDefault();
// return empty why?

PackageSource localSource = new PackageSource(rootPath);
SourceRepository localRepoNotLegit = new SourceRepository(localSource, providers);
PackageSearchResource searchLocalResource = await localRepoNotLegit
.GetResourceAsync();
var packageFound3 = await searchLocalResource.SearchAsync(
jsonPackage.Identity.Id,
searchFilter,
0,
10,
logger,
CancellationToken.None);
var thePackage = packageFound3.First();
// no assemblies are returned => missing property


6. Utilities classes

```c#
public class MachineWideSettings : IMachineWideSettings
 {
      private readonly Lazy<IEnumerable<Settings>> _settings;

      public MachineWideSettings()
      {
          var baseDirectory = NuGetEnvironment.GetFolderPath(NuGetFolderPath.MachineWideConfigDirectory);
           _settings = new Lazy<IEnumerable<Settings>>(
                    () => global::NuGet.Configuration.Settings.LoadMachineWideSettings(baseDirectory));
       }

      public IEnumerable<Settings> Settings => _settings.Value;
}

public class Logger : ILogger
{
    private List<string> logs = new List<string>();

    public void LogDebug(string data)
    {
        logs.Add(data);
    }

    public void LogVerbose(string data)
    {
        logs.Add(data);
    }

    public void LogInformation(string data)
    {
        logs.Add(data);
    }

    public void LogMinimal(string data)
    {
        logs.Add(data);
    }

    public void LogWarning(string data)
    {
        logs.Add(data);
    }

    public void LogError(string data)
    {
        logs.Add(data);
    }

    public void LogInformationSummary(string data)
    {
        logs.Add(data);
    }

    public void LogErrorSummary(string data)
    {
        logs.Add(data);
    }
}

public class ProjectContext : INuGetProjectContext
{
private List<string> logs = new List<string>();

    public List<string> GetLogs()
    {
        return logs;
    }

    public void Log(MessageLevel level, string message, params object[] args)
    {
        var formattedMessage = String.Format(message, args);
        logs.Add(formattedMessage);
        // Do your logging here...
    }

    public FileConflictAction ResolveFileConflict(string message)
    {
        logs.Add(message);
        return FileConflictAction.Ignore;
    }


    public PackageExtractionContext PackageExtractionContext
    {
        get;
        set;
    }

    public NuGet.ProjectManagement.ExecutionContext ExecutionContext
    {
        get;
    }

    public XDocument OriginalPackagesConfig
    {
        get; set;
    }

    public ISourceControlManagerProvider SourceControlManagerProvider
    {
        get;
        set;
    }

    public void ReportError(string message)
    {
        logs.Add(message);
    }

    public NuGetActionType ActionType
    {
        get; set;
    }

    public TelemetryServiceHelper TelemetryService
    {
        get; set;
    }
}

Questions

  1. Why some V3 functions don't seem to work?
  2. Why the v2 FindPackagesById return a IPackage and now it return a IPackageSearchMetadata?
  3. Does a v3 local search function return an object similar to IPackage (for the assemblies files)?
  4. How can you extract assemblies (dll) for local package? Do I need to implement it?

Thank you

Question

All 2 comments

@devwhyst what is the end goal you are trying achieve?

For finding packages in local folders take a look at: https://github.com/NuGet/NuGet.Client/blob/dev/src/NuGet.Core/NuGet.Protocol/Utility/LocalFolderUtility.cs

Note that v2 and v3 folders expect different structures and files to be present, so if a package is not returned it is likely because it isn't in the expected location or additional files beyond the nupkg were not in place.

You can read a package using PackageArchiveReader which gives you data similar to IPackage

Thanks for your quick answer!

@emgarten My goal is to get the assembly file and import it in my project programmatically.

I realize that my folder was missing files for finding packages with V3. My folder structure was a V2 structure. I tried finding NuGet local packages with the Visual Studio NuGet packages folder and the listing was working. So, I'm using the V2 functions for finding my local packages.

I used the PackageArchiveReader for listings assemblies files and it worked perfectly.

Thanks again!

Was this page helpful?
0 / 5 - 0 ratings