diff --git a/src/scripts/taglist-order.js b/src/scripts/taglist-order.js index 42d274d..3e6bde7 100644 --- a/src/scripts/taglist-order.js +++ b/src/scripts/taglist-order.js @@ -56,3 +56,35 @@ export const splitTagToArray = (tag) => .split('') .reduce(tagReduce, []) .map((e) => (isDigit(e.charAt(0)) ? parseInt(e) : e)); + +const applyOrder = (order, e1, e2) => { + if (e1 === e2) { + return 0; + } + if (order.numFirst) { + if (typeof e1 === 'number') { + const factor = order.numAsc ? 1 : -1; + return typeof e2 === 'number' ? (e1 - e2) * factor : -1; + } else if (typeof e2 === 'number') { + return 1; + } else { + const factor = order.alphaAsc ? 1 : -1; + return e1.localeCompare(e2) * factor + } + } +}; + +export const getTagComparator = (order) => { + return (e1, e2) => { + const tag1 = splitTagToArray(e1.tag || e1); + const tag2 = splitTagToArray(e2.tag || e2); + + for (var i = 0; i < tag1.length && i < tag2.length; i++) { + const compare = applyOrder(order, tag1[i], tag2[i]); + if (compare != 0) { + return compare; + } + } + return (e1.tag || e1).length - (e2.tag || e2).length; + }; +}; diff --git a/test/taglist-order.test.js b/test/taglist-order.test.js index 0736786..96dea87 100644 --- a/test/taglist-order.test.js +++ b/test/taglist-order.test.js @@ -1,4 +1,5 @@ import { taglistOrderVariants, taglistOrderParser, splitTagToArray } from '../src/scripts/taglist-order.js'; +import { getTagComparator } from '../src/scripts/taglist-order.js'; import { DockerRegistryUIError } from '../src/scripts/error.js'; import assert from 'assert'; @@ -84,4 +85,38 @@ describe('utils tests', () => { assert.deepEqual(splitTagToArray('alpine-lts'), ['alpine-lts']); }); }); + + describe('getTagComparator', () => { + it('should sort tags with `num-asc;alpha-asc`', () => { + const comparator = getTagComparator(taglistOrderParser('num-asc;alpha-asc')); + + assert.deepEqual(['0.2.4', '1.2.5', '0.2.5'].sort(comparator), ['0.2.4', '0.2.5', '1.2.5']); + assert.deepEqual(['latest', '0.2.4', 'main'].sort(comparator), ['0.2.4', 'latest', 'main']); + assert.deepEqual(['latest', '1.0.0-SNAPSHOT', '1.0.0'].sort(comparator), ['1.0.0', '1.0.0-SNAPSHOT', 'latest']); + }); + + it('should sort tags with `num-desc;alpha-asc`', () => { + const comparator = getTagComparator(taglistOrderParser('num-desc;alpha-asc')); + + assert.deepEqual(['0.2.4', '1.2.5', '0.2.5'].sort(comparator), ['1.2.5', '0.2.5', '0.2.4']); + assert.deepEqual(['latest', '0.2.4', 'main'].sort(comparator), ['0.2.4', 'latest', 'main']); + assert.deepEqual(['latest', '1.0.0-SNAPSHOT', '1.0.0'].sort(comparator), ['1.0.0', '1.0.0-SNAPSHOT', 'latest']); + }); + + it('should sort tags with `num-asc;alpha-desc`', () => { + const comparator = getTagComparator(taglistOrderParser('num-asc;alpha-desc')); + + assert.deepEqual(['0.2.4', '1.2.5', '0.2.5'].sort(comparator), ['0.2.4', '0.2.5', '1.2.5']); + assert.deepEqual(['latest', '0.2.4', 'main'].sort(comparator), ['0.2.4', 'main', 'latest']); + assert.deepEqual(['latest', '1.0.0-SNAPSHOT', '1.0.0'].sort(comparator), ['1.0.0', '1.0.0-SNAPSHOT', 'latest']); + }); + + it('should sort tags with `num-desc;alpha-desc`', () => { + const comparator = getTagComparator(taglistOrderParser('num-desc;alpha-desc')); + + assert.deepEqual(['0.2.4', '1.2.5', '0.2.5'].sort(comparator), ['1.2.5', '0.2.5', '0.2.4']); + assert.deepEqual(['latest', '0.2.4', 'main'].sort(comparator), ['0.2.4', 'main', 'latest']); + assert.deepEqual(['latest', '1.0.0-SNAPSHOT', '1.0.0'].sort(comparator), ['1.0.0', '1.0.0-SNAPSHOT', 'latest']); + }); + }); });