rychlym / dotnet-tools-outdated

A simple command line utility to find out / check, whether any of installed .NET Core global tools are outdated
MIT License
20 stars 3 forks source link

IndexOutOfRangeException on newest release 0.5.0 when all versions are unlisted #3

Closed augustoproiete closed 3 years ago

augustoproiete commented 3 years ago

@rychlym FYI the fix of #2 with the new API that doesn't include versions that have been unlisted uncovered another issue that didn't happen before, which is when no versions are returned for a package, because all versions of a package have been unlisted.

image

I have the tool dotnet-try v1.0.19553.4 installed on my machine and more recently Microsoft released a new package Microsoft.dotnet-try that replaces it, and all versions of dotnet-try have been unlisted.

When running dotnet-tools-outdated v0.5.0 in that state I get this exception:

C:\augustoproiete>dotnet tools-outdated
Unhandled exception. System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at DotNetToolsOutdated.OutdatedCommand.OnExecuteAsync()
   at McMaster.Extensions.CommandLineUtils.Conventions.ExecuteMethodConvention.InvokeAsync(MethodInfo method, Object instance, Object[] arguments)
   at McMaster.Extensions.CommandLineUtils.Conventions.ExecuteMethodConvention.OnExecute(ConventionContext context, CancellationToken cancellationToken)
   at McMaster.Extensions.CommandLineUtils.Conventions.ExecuteMethodConvention.<>c__DisplayClass0_0.<<Apply>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at McMaster.Extensions.CommandLineUtils.CommandLineApplication.ExecuteAsync(String[] args, CancellationToken cancellationToken)
   at McMaster.Extensions.CommandLineUtils.CommandLineApplication.ExecuteAsync[TApp](CommandLineContext context, CancellationToken cancellationToken)
   at DotNetToolsOutdated.Program.MainAsync(String[] args) in C:\Users\mr\Source\repos\my\console\dotnet-tools-outdated\src\DotNetToolsOutdated\Program.cs:line 15
   at DotNetToolsOutdated.Program.Main(String[] args) in C:\Users\mr\Source\repos\my\console\dotnet-tools-outdated\src\DotNetToolsOutdated\Program.cs:line 10
rychlym commented 3 years ago

Hi @augustoproiete,

Thanks for posting this bug. I have just fixed it. (The new 0.5.1 version has been released) I was quickly thinking how to do it to be compatible for future. It recognizes the package as outdated, (so e.g. dotnet-try will be listed) and the available version field is be empty.

(I was thinking to write statistics row in future in case of the default table output type (there are also json and xml output types - parameter -f). In case of the package become unlisted at all, it will tell it on that row)

augustoproiete commented 3 years ago

Thanks @rychlym! You're a machine! :robot:

Yes, it would be nice if there was a message to the user saying that the package they are using has been unlisted, so that they can look for more information to understand why - and can decide to look for a replacement.

BTW, when a package author unlists a package in nuget.org, they have the option to suggest an alternative package to users, and I would hope this information is available through the API and as such it's something dotnet-tools-outdated could potentially leverage in the future and show the user what is the recommended replacement by the author.

e.g. https://www.nuget.org/packages/Ookii.Dialogs/3.0.1

image


Unfortunately in the case of dotnet-try, they didn't link Microsoft.dotnet-try as an alternative package (though they should have), so in this particular case dotnet-tools-outdated wouldn't be able to do more than telling the user the dotnet-try package has been unlisted.

rychlym commented 3 years ago

Hi @augustoproiete, thanks for the sharing. I like the idea with that alternative package. It would be also good if there is possibility to post a short (limited text) general description, why the product become unlisted to show it. Anyway for any such enhancements is needed to find appropriate nuget api call, and unfortunately I am not very familiar with the nuget api. But if I found it, I would "enjoy" to add that enhancement..

augustoproiete commented 3 years ago

@rychlym Awesome! I can help on the API front. In fact, instead of calling the API yourself, parsing the JSON, mapping to DTOs, etc. you use the client provided by the NuGet team (NuGet.Protocol) which does all the hard work for you (and it's the same client used by nuget.exe).

Here is an example of as simple request for metadata of a specific package by ID:

async Task Main()
{
    using (var cacheContext = new SourceCacheContext())
    {
        var repository = Repository.Factory.GetCoreV3("https://api.nuget.org/v3/index.json");

        var resource = await repository.GetResourceAsync<PackageMetadataResource>();

        var packages = await resource.GetMetadataAsync("Ookii.Dialogs", includePrerelease: true,
            includeUnlisted: true, cacheContext, NullLogger.Instance, CancellationToken.None);

        var latestVersion = packages.OfType<PackageSearchMetadataRegistration>()
            .OrderByDescending(p => p.Version)
            .FirstOrDefault();

        latestVersion.IsListed.Dump();
        latestVersion.Version.IsPrerelease.Dump();
        latestVersion.DeprecationMetadata.Dump();
    }
}

image