Search code examples
nugetversionartifactoryjqjfrog-cli

How to sort Artifactory package search result by version number with JFrog CLI?


I need to get the latest version of a specific NuGet package in Artifactory. I use following JFrog CLI command to receive a list of all versions (later on with --limit=1), including JSON parsing with jq:

jfrog rt s myRepo/Path/ --props "nuget.id=MyLib" --sort-by=name --sort-order=desc  | jq -M -r ".[] | .props.\"nuget.version\" | .[]"

The above example results in raw string output like this:

1.2.3.101
1.2.3.103
1.2.3.95
1.2.3.99
1.2.3.99-beta10
1.2.3.99-beta9

My target is to get an output sorted by version:

1.2.3.95
1.2.3.99
1.2.3.99-beta9
1.2.3.99-beta10
1.2.3.101
1.2.3.103

Unfortunately I can not use --sort-by=created as it can differ from version-sorting. Even if I do not use --sort-byoption it does not work. Also the version numbers can contain letters like "-beta".

In the Artifactory TreeView it is correct, but not in CLI.

How can I get a result sorted-by version number?


Solution

  • You can use jq to sort version number strings.

    If the strings are "raw" strings, one per line, then you could use this jq program:

    def parse:
     sub("alpha"; "alpha.")
     | sub("beta"; "beta.") 
     | sub("gamma"; "gamma.")
     | sub("prerelease"; "prerelease.")
     | sub("debug"); "debug.")
     | [splits("[-.]")]
     | map(tonumber? // .) ;
    
    [inputs]
    | sort_by(parse)[]
    

    This jq program could be run like so:

    jq -nrR -f program.jq versions.txt
    

    With the sample version numbers, this would produce:

    1.2.3.95
    1.2.3.99
    1.2.3.99-beta9
    1.2.3.99-beta10
    1.2.3.101
    1.2.3.103
    

    In your case, the result can be achieved without invoking jq a second time by modifying your program to use parse along the lines shown above. The main part of the jq program would probably look something like this:

    map(.props["nuget.version"]) | sort_by(parse)[]
    

    (Of course the -n option is only needed when using inputs to read.)

    Highest version number

    If (as indicated in a comment is the case) you just want the highest version number, you could simply change the final [] to [-1]:

    ... | sort_by(parse)[-1]