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

1

1

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?

Harneen answered 7/5, 2019 at 14:31 Comment(0)
E
2

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]
Exceptionable answered 7/5, 2019 at 16:9 Comment(8)
Thanks for your reply. Is there a typo at split (at your second code snippet)? I tried several commands, but always got: jq: error (at <stdin>:150): split input and separator must be strings.Harneen
Your writeup says "something like this", but maybe .props["nuget.version"] is not always a string. This is why following the minimal reproducible example guidelines is generally a good idea.Exceptionable
I updated my question/example. With your first command snippet appended I got following (linearized) result: [["1","2","3","95"],["1","2","3","99"],["1","2","3","101"],["1","2","3","103"],["1","2","3","99-beta10"],["1","2","3","99-beta9"]], which sorts at least pure numbers, but not with "-beta" tags.Harneen
Wow, this works already pretty well! :) But strange is, that one output element is missing (the first?). Artifactory says to find all, but output is one less. (How) Is it possible to make a one-liner without external program.jq? I tried to put it into quotes (') and also escaped the double-quotes (\").Harneen
My bad - I forgot the -n option.Exceptionable
Thanks for correction! One last thing to close this SO question: How to put all into one command without calling external file (program.jq). Sorry, I am quite new to jq, but I tried here: jqplay.org/s/6_gBeGbXh-Harneen
One way would be to move the def to the front.Exceptionable
Here my final solution: Finally I've piped the program.jq into a file with echo def parse: sub("alpha"; "alpha.") ^| sub("beta"; "beta.") ^| sub("prerelease"; "prerelease.") ^| sub("debug"; "debug.") ^| sub("itk"; "itk.") ^| [splits("[-.]")] ^| map(tonumber? // .); [inputs] ^| sort_by(parse)[-1] > program.jq and executed jfrog rt s myRepo/Path/ --props "nuget.id=MyLib" | jq -M -r ".[] | .props.\"nuget.version\" | .[]" | jq -nrR -f program.jq. @peak: Thanks for your help! Feel free to edit your answer with this for others - nevertheless I tagged your answer as solution. :)Harneen

© 2022 - 2024 — McMap. All rights reserved.