From 2b63fb725c3c4c2de70cc48f9de618a15422ed08 Mon Sep 17 00:00:00 2001 From: Joxit Date: Mon, 1 May 2023 23:22:48 +0200 Subject: [PATCH 01/11] feat(utils): add taglistOrderVariants function to format taglist order --- package.json | 4 +++- src/scripts/utils.js | 19 +++++++++++++++++++ test/utils.test.js | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 test/utils.test.js diff --git a/package.json b/package.json index 5370fc8..e002059 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,8 @@ "format-riot": "find src rollup rollup.config.js -name '*.riot' -exec prettier --config .prettierrc -w --parser html {} \\;", "start": "rollup -c -w --environment ROLLUP_SERVE:true", "build": "rollup -c", - "build:electron": "npm run build && cd examples/electron && npm install && npm run dist" + "build:electron": "npm run build && cd examples/electron && npm install && npm run dist", + "test": "mocha" }, "repository": { "type": "git", @@ -31,6 +32,7 @@ "@rollup/plugin-node-resolve": "^15.0.1", "@rollup/plugin-terser": "^0.2.1", "core-js": "^3.27.1", + "mocha": "^10.2.0", "node-sass": "^8.0.0", "prettier": "^2.8.1", "riot": "^7.1.0", diff --git a/src/scripts/utils.js b/src/scripts/utils.js index 81e4328..adf3314 100644 --- a/src/scripts/utils.js +++ b/src/scripts/utils.js @@ -220,3 +220,22 @@ export function truthy(value) { export function stringToArray(value) { return value && typeof value === 'string' ? value.split(',') : []; } + +export const taglistOrderVariants = (taglistOrder) => { + switch (taglistOrder) { + case 'desc': + case 'alpha-desc': + return 'alpha-desc;num-desc'; + case 'asc': + case 'num-asc': + return 'num-asc;alpha-asc'; + default: + if (!taglistOrder) { + return 'num-asc;alpha-asc'; + } else if (taglistOrder.indexOf(';') === -1) { + return taglistOrder.startsWith('num-') ? `${taglistOrder};alpha-asc` : `${taglistOrder};num-asc`; + } else { + return taglistOrder; + } + } +}; diff --git a/test/utils.test.js b/test/utils.test.js new file mode 100644 index 0000000..8ff84d1 --- /dev/null +++ b/test/utils.test.js @@ -0,0 +1,34 @@ +import { taglistOrderVariants } from '../src/scripts/utils.js'; +import assert from 'assert'; + +describe('utils tests', () => { + describe('taglistOrderVariants', () => { + it(`should return the input when it's well formed and num first`, () => { + const expected = ['num-asc;alpha-asc', 'num-asc;alpha-desc', 'num-desc;alpha-asc', 'num-desc;alpha-asc']; + expected.forEach( + (e) => assert.deepEqual(taglistOrderVariants(e), e) + ); + }); + + it(`should return the input when it's well formed and alpha first`, () => { + const expected = ['alpha-asc;num-asc', 'alpha-asc;num-desc', 'alpha-desc;num-asc', 'alpha-desc;num-asc']; + expected.forEach( + (e) => assert.deepEqual(taglistOrderVariants(e), e) + ); + }); + + it('should return correct variant of `num-asc;alpha-asc`', () => { + const expected = 'num-asc;alpha-asc'; + ['asc', 'num-asc'].forEach( + (e) => assert.deepEqual(taglistOrderVariants(e), expected) + ); + }); + + it('should return correct variant of `alpha-desc;num-desc`', () => { + const expected = 'alpha-desc;num-desc'; + ['desc', 'alpha-desc'].forEach( + (e) => assert.deepEqual(taglistOrderVariants(e), expected) + ); + }); + }); +}); From a3e987482e93ee8e970265cc7807ecd53f91f24c Mon Sep 17 00:00:00 2001 From: Joxit Date: Tue, 2 May 2023 01:26:11 +0200 Subject: [PATCH 02/11] fix(utils): taglistOrderVariants improved format --- src/scripts/utils.js | 15 ++++++++++----- test/utils.test.js | 26 +++++++++++++++----------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/src/scripts/utils.js b/src/scripts/utils.js index adf3314..778226d 100644 --- a/src/scripts/utils.js +++ b/src/scripts/utils.js @@ -1,3 +1,4 @@ +import { DockerRegistryUIError } from './error.js'; const LOCAL_STORAGE_KEY = 'registryServer'; export function bytesToSize(bytes) { @@ -221,21 +222,25 @@ export function stringToArray(value) { return value && typeof value === 'string' ? value.split(',') : []; } +const TAGLIST_ORDER_REGEX = /(alpha-(asc|desc);num-(asc|desc))|(num-(asc|desc);alpha-(asc|desc))/; + export const taglistOrderVariants = (taglistOrder) => { switch (taglistOrder) { case 'desc': - case 'alpha-desc': return 'alpha-desc;num-desc'; case 'asc': - case 'num-asc': return 'num-asc;alpha-asc'; + case 'alpha-desc': + case 'alpha-asc': + case 'num-desc': + case 'num-asc': + return `${taglistOrder};${taglistOrder.startsWith('num') ? 'alpha' : 'num'}-asc`; default: if (!taglistOrder) { return 'num-asc;alpha-asc'; - } else if (taglistOrder.indexOf(';') === -1) { - return taglistOrder.startsWith('num-') ? `${taglistOrder};alpha-asc` : `${taglistOrder};num-asc`; - } else { + } else if (TAGLIST_ORDER_REGEX.test(taglistOrder)) { return taglistOrder; } + throw new DockerRegistryUIError(`The order \`${taglistOrder}\` is not recognized.`); } }; diff --git a/test/utils.test.js b/test/utils.test.js index 8ff84d1..c87c8d3 100644 --- a/test/utils.test.js +++ b/test/utils.test.js @@ -1,33 +1,37 @@ import { taglistOrderVariants } from '../src/scripts/utils.js'; +import { DockerRegistryUIError } from '../src/scripts/error.js'; import assert from 'assert'; describe('utils tests', () => { describe('taglistOrderVariants', () => { it(`should return the input when it's well formed and num first`, () => { const expected = ['num-asc;alpha-asc', 'num-asc;alpha-desc', 'num-desc;alpha-asc', 'num-desc;alpha-asc']; - expected.forEach( - (e) => assert.deepEqual(taglistOrderVariants(e), e) - ); + expected.forEach((e) => assert.deepEqual(taglistOrderVariants(e), e)); }); it(`should return the input when it's well formed and alpha first`, () => { const expected = ['alpha-asc;num-asc', 'alpha-asc;num-desc', 'alpha-desc;num-asc', 'alpha-desc;num-asc']; - expected.forEach( - (e) => assert.deepEqual(taglistOrderVariants(e), e) - ); + expected.forEach((e) => assert.deepEqual(taglistOrderVariants(e), e)); }); it('should return correct variant of `num-asc;alpha-asc`', () => { const expected = 'num-asc;alpha-asc'; - ['asc', 'num-asc'].forEach( - (e) => assert.deepEqual(taglistOrderVariants(e), expected) - ); + [undefined, '', 'asc', 'num-asc'].forEach((e) => assert.deepEqual(taglistOrderVariants(e), expected)); }); it('should return correct variant of `alpha-desc;num-desc`', () => { const expected = 'alpha-desc;num-desc'; - ['desc', 'alpha-desc'].forEach( - (e) => assert.deepEqual(taglistOrderVariants(e), expected) + ['desc'].forEach((e) => assert.deepEqual(taglistOrderVariants(e), expected)); + }); + + it('should extend correctly orders', () => { + ['alpha-desc', 'alpha-asc'].forEach((e) => assert.deepEqual(taglistOrderVariants(e), `${e};num-asc`)); + ['num-desc', 'num-asc'].forEach((e) => assert.deepEqual(taglistOrderVariants(e), `${e};alpha-asc`)); + }); + + it('should throw error on incorrect values', () => { + ['alpha-desc;alpha-asc', 'foobar'].forEach((e) => + assert.throws(() => taglistOrderVariants(e), DockerRegistryUIError, `Did not throw on ${e}`) ); }); }); From edb5aa97e8c6ef29c7f9fdcf1d1eb917fa50b2b0 Mon Sep 17 00:00:00 2001 From: Joxit Date: Fri, 5 May 2023 00:07:29 +0200 Subject: [PATCH 03/11] feat(utils): add talgistOrderParser will parse the order string into object --- src/scripts/error.js | 5 +++++ src/scripts/utils.js | 18 ++++++++++++++++++ test/utils.test.js | 34 +++++++++++++++++++++++++++++++++- 3 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 src/scripts/error.js diff --git a/src/scripts/error.js b/src/scripts/error.js new file mode 100644 index 0000000..3133d2f --- /dev/null +++ b/src/scripts/error.js @@ -0,0 +1,5 @@ +export class DockerRegistryUIError extends Error { + constructor(msg) { + super(msg); + } +} diff --git a/src/scripts/utils.js b/src/scripts/utils.js index 778226d..f6e39cc 100644 --- a/src/scripts/utils.js +++ b/src/scripts/utils.js @@ -244,3 +244,21 @@ export const taglistOrderVariants = (taglistOrder) => { throw new DockerRegistryUIError(`The order \`${taglistOrder}\` is not recognized.`); } }; + +export function talgistOrderParser(taglistOrder) { + const orders = taglistOrderVariants(taglistOrder) + .split(';') + .filter((e) => e) + .map((e) => e.split('-').filter((e) => e)) + .reduce((acc, e, idx) => { + if (e.length > 1) { + acc[e[0] + 'Asc'] = e[1] === 'asc'; + } + if (idx === 0) { + acc.numFirst = e[0] === 'num'; + } + return acc; + }, {}); + + return orders; +} diff --git a/test/utils.test.js b/test/utils.test.js index c87c8d3..09239a7 100644 --- a/test/utils.test.js +++ b/test/utils.test.js @@ -1,4 +1,4 @@ -import { taglistOrderVariants } from '../src/scripts/utils.js'; +import { taglistOrderVariants, talgistOrderParser } from '../src/scripts/utils.js'; import { DockerRegistryUIError } from '../src/scripts/error.js'; import assert from 'assert'; @@ -35,4 +35,36 @@ describe('utils tests', () => { ); }); }); + + describe('talgistOrderParser', () => { + it('should have default configuration when empty or undefined', () => { + const expected = { numAsc: true, alphaAsc: true, numFirst: true }; + assert.deepEqual(talgistOrderParser(), expected); + assert.deepEqual(talgistOrderParser(''), expected); + }); + + it('should parse correctly `num-asc;alpha-asc` and variants', () => { + const expected = { numAsc: true, alphaAsc: true, numFirst: true }; + ['asc', 'num-asc;alpha-asc', 'num-asc'].forEach((e) => + assert.deepEqual(talgistOrderParser(e), expected, `wrong result for ${e}`) + ); + }); + + it('should parse correctly `alpha-desc;num-desc` and variants', () => { + const expected = { numAsc: false, alphaAsc: false, numFirst: false }; + ['desc', 'alpha-desc;num-desc'].forEach((e) => + assert.deepEqual(talgistOrderParser(e), expected, `wrong result for ${e}`) + ); + }); + + it('should parse correctly `alpha-asc;num-desc` and variants', () => { + const expected = { numAsc: false, alphaAsc: true, numFirst: false }; + assert.deepEqual(talgistOrderParser('alpha-asc;num-desc'), expected) + }); + + it('should parse correctly `num-desc;alpha-desc` and variants', () => { + const expected = { numAsc: false, alphaAsc: false, numFirst: true }; + assert.deepEqual(talgistOrderParser('num-desc;alpha-desc'), expected) + }); + }); }); From b0ea4e5fb86d823872f70f89f278e9f73d700433 Mon Sep 17 00:00:00 2001 From: Joxit Date: Sat, 6 May 2023 22:55:33 +0200 Subject: [PATCH 04/11] fix(utils): rename `talgistOrderParser` to `taglistOrderParser` :facepalm: --- src/scripts/utils.js | 4 ++-- test/utils.test.js | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/scripts/utils.js b/src/scripts/utils.js index f6e39cc..0ca3642 100644 --- a/src/scripts/utils.js +++ b/src/scripts/utils.js @@ -245,7 +245,7 @@ export const taglistOrderVariants = (taglistOrder) => { } }; -export function talgistOrderParser(taglistOrder) { +export const taglistOrderParser = (taglistOrder) => { const orders = taglistOrderVariants(taglistOrder) .split(';') .filter((e) => e) @@ -261,4 +261,4 @@ export function talgistOrderParser(taglistOrder) { }, {}); return orders; -} +}; diff --git a/test/utils.test.js b/test/utils.test.js index 09239a7..feb6d02 100644 --- a/test/utils.test.js +++ b/test/utils.test.js @@ -1,4 +1,4 @@ -import { taglistOrderVariants, talgistOrderParser } from '../src/scripts/utils.js'; +import { taglistOrderVariants, taglistOrderParser } from '../src/scripts/utils.js'; import { DockerRegistryUIError } from '../src/scripts/error.js'; import assert from 'assert'; @@ -36,35 +36,35 @@ describe('utils tests', () => { }); }); - describe('talgistOrderParser', () => { + describe('taglistOrderParser', () => { it('should have default configuration when empty or undefined', () => { const expected = { numAsc: true, alphaAsc: true, numFirst: true }; - assert.deepEqual(talgistOrderParser(), expected); - assert.deepEqual(talgistOrderParser(''), expected); + assert.deepEqual(taglistOrderParser(), expected); + assert.deepEqual(taglistOrderParser(''), expected); }); it('should parse correctly `num-asc;alpha-asc` and variants', () => { const expected = { numAsc: true, alphaAsc: true, numFirst: true }; ['asc', 'num-asc;alpha-asc', 'num-asc'].forEach((e) => - assert.deepEqual(talgistOrderParser(e), expected, `wrong result for ${e}`) + assert.deepEqual(taglistOrderParser(e), expected, `wrong result for ${e}`) ); }); it('should parse correctly `alpha-desc;num-desc` and variants', () => { const expected = { numAsc: false, alphaAsc: false, numFirst: false }; ['desc', 'alpha-desc;num-desc'].forEach((e) => - assert.deepEqual(talgistOrderParser(e), expected, `wrong result for ${e}`) + assert.deepEqual(taglistOrderParser(e), expected, `wrong result for ${e}`) ); }); it('should parse correctly `alpha-asc;num-desc` and variants', () => { const expected = { numAsc: false, alphaAsc: true, numFirst: false }; - assert.deepEqual(talgistOrderParser('alpha-asc;num-desc'), expected) + assert.deepEqual(taglistOrderParser('alpha-asc;num-desc'), expected) }); it('should parse correctly `num-desc;alpha-desc` and variants', () => { const expected = { numAsc: false, alphaAsc: false, numFirst: true }; - assert.deepEqual(talgistOrderParser('num-desc;alpha-desc'), expected) + assert.deepEqual(taglistOrderParser('num-desc;alpha-desc'), expected) }); }); }); From a135c0086697d2623d74dd7b23dcb2b69e307a0e Mon Sep 17 00:00:00 2001 From: Joxit Date: Tue, 9 May 2023 22:34:59 +0200 Subject: [PATCH 05/11] feat(utils): add splitTagToArray that will transform a tag into an array alpha and num splited --- src/scripts/taglist-order.js | 58 +++++++++++++++++++ src/scripts/utils.js | 42 -------------- test/{utils.test.js => taglist-order.test.js} | 23 +++++++- 3 files changed, 78 insertions(+), 45 deletions(-) create mode 100644 src/scripts/taglist-order.js rename test/{utils.test.js => taglist-order.test.js} (75%) diff --git a/src/scripts/taglist-order.js b/src/scripts/taglist-order.js new file mode 100644 index 0000000..42d274d --- /dev/null +++ b/src/scripts/taglist-order.js @@ -0,0 +1,58 @@ +import { DockerRegistryUIError } from './error.js'; +import { isDigit } from './utils.js'; + +const TAGLIST_ORDER_REGEX = /(alpha-(asc|desc);num-(asc|desc))|(num-(asc|desc);alpha-(asc|desc))/; + +export const taglistOrderVariants = (taglistOrder) => { + switch (taglistOrder) { + case 'desc': + return 'alpha-desc;num-desc'; + case 'asc': + return 'num-asc;alpha-asc'; + case 'alpha-desc': + case 'alpha-asc': + case 'num-desc': + case 'num-asc': + return `${taglistOrder};${taglistOrder.startsWith('num') ? 'alpha' : 'num'}-asc`; + default: + if (!taglistOrder) { + return 'num-asc;alpha-asc'; + } else if (TAGLIST_ORDER_REGEX.test(taglistOrder)) { + return taglistOrder; + } + throw new DockerRegistryUIError(`The order \`${taglistOrder}\` is not recognized.`); + } +}; + +export const taglistOrderParser = (taglistOrder) => { + const orders = taglistOrderVariants(taglistOrder) + .split(';') + .filter((e) => e) + .map((e) => e.split('-').filter((e) => e)) + .reduce((acc, e, idx) => { + if (e.length > 1) { + acc[e[0] + 'Asc'] = e[1] === 'asc'; + } + if (idx === 0) { + acc.numFirst = e[0] === 'num'; + } + return acc; + }, {}); + + return orders; +}; + +export const tagReduce = (acc, e) => { + if (acc.length > 0 && isDigit(acc[acc.length - 1].charAt(0)) == isDigit(e)) { + acc[acc.length - 1] += e; + } else { + acc.push(e); + } + return acc; +}; + +export const splitTagToArray = (tag) => + tag + .split('') + .reduce(tagReduce, []) + .map((e) => (isDigit(e.charAt(0)) ? parseInt(e) : e)); diff --git a/src/scripts/utils.js b/src/scripts/utils.js index 0ca3642..81e4328 100644 --- a/src/scripts/utils.js +++ b/src/scripts/utils.js @@ -1,4 +1,3 @@ -import { DockerRegistryUIError } from './error.js'; const LOCAL_STORAGE_KEY = 'registryServer'; export function bytesToSize(bytes) { @@ -221,44 +220,3 @@ export function truthy(value) { export function stringToArray(value) { return value && typeof value === 'string' ? value.split(',') : []; } - -const TAGLIST_ORDER_REGEX = /(alpha-(asc|desc);num-(asc|desc))|(num-(asc|desc);alpha-(asc|desc))/; - -export const taglistOrderVariants = (taglistOrder) => { - switch (taglistOrder) { - case 'desc': - return 'alpha-desc;num-desc'; - case 'asc': - return 'num-asc;alpha-asc'; - case 'alpha-desc': - case 'alpha-asc': - case 'num-desc': - case 'num-asc': - return `${taglistOrder};${taglistOrder.startsWith('num') ? 'alpha' : 'num'}-asc`; - default: - if (!taglistOrder) { - return 'num-asc;alpha-asc'; - } else if (TAGLIST_ORDER_REGEX.test(taglistOrder)) { - return taglistOrder; - } - throw new DockerRegistryUIError(`The order \`${taglistOrder}\` is not recognized.`); - } -}; - -export const taglistOrderParser = (taglistOrder) => { - const orders = taglistOrderVariants(taglistOrder) - .split(';') - .filter((e) => e) - .map((e) => e.split('-').filter((e) => e)) - .reduce((acc, e, idx) => { - if (e.length > 1) { - acc[e[0] + 'Asc'] = e[1] === 'asc'; - } - if (idx === 0) { - acc.numFirst = e[0] === 'num'; - } - return acc; - }, {}); - - return orders; -}; diff --git a/test/utils.test.js b/test/taglist-order.test.js similarity index 75% rename from test/utils.test.js rename to test/taglist-order.test.js index feb6d02..0736786 100644 --- a/test/utils.test.js +++ b/test/taglist-order.test.js @@ -1,4 +1,4 @@ -import { taglistOrderVariants, taglistOrderParser } from '../src/scripts/utils.js'; +import { taglistOrderVariants, taglistOrderParser, splitTagToArray } from '../src/scripts/taglist-order.js'; import { DockerRegistryUIError } from '../src/scripts/error.js'; import assert from 'assert'; @@ -59,12 +59,29 @@ describe('utils tests', () => { it('should parse correctly `alpha-asc;num-desc` and variants', () => { const expected = { numAsc: false, alphaAsc: true, numFirst: false }; - assert.deepEqual(taglistOrderParser('alpha-asc;num-desc'), expected) + assert.deepEqual(taglistOrderParser('alpha-asc;num-desc'), expected); }); it('should parse correctly `num-desc;alpha-desc` and variants', () => { const expected = { numAsc: false, alphaAsc: false, numFirst: true }; - assert.deepEqual(taglistOrderParser('num-desc;alpha-desc'), expected) + assert.deepEqual(taglistOrderParser('num-desc;alpha-desc'), expected); + }); + }); + + describe('splitTagToArray', () => { + it('should reduce tags with numbers', () => { + assert.deepEqual(splitTagToArray('0.2.4'), [0, '.', 2, '.', 4]); + assert.deepEqual(splitTagToArray('1.2.3-SNAPSHOT'), [1, '.', 2, '.', 3, '-SNAPSHOT']); + assert.deepEqual(splitTagToArray('alpine-3.2'), ['alpine-', 3, '.', 2]); + assert.deepEqual(splitTagToArray('10.30.00'), [10, '.', 30, '.', 0]); + assert.deepEqual(splitTagToArray('010.30.00'), [10, '.', 30, '.', 0]); + assert.deepEqual(splitTagToArray('z010.30.00'), ['z', 10, '.', 30, '.', 0]); + }); + + it('should reduce tags without numbers', () => { + assert.deepEqual(splitTagToArray('main'), ['main']); + assert.deepEqual(splitTagToArray('master'), ['master']); + assert.deepEqual(splitTagToArray('alpine-lts'), ['alpine-lts']); }); }); }); From 34d1ed90adb433c728d4752e2fc6f7a09dbd1082 Mon Sep 17 00:00:00 2001 From: Joxit Date: Wed, 10 May 2023 05:16:57 +0200 Subject: [PATCH 06/11] feat(utils): add `getTagComparator` that generate comparator, only numFirst supported --- src/scripts/taglist-order.js | 32 ++++++++++++++++++++++++++++++++ test/taglist-order.test.js | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) 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']); + }); + }); }); From fbab517a1747d5f1551e3254e6aaf44ee35e10c8 Mon Sep 17 00:00:00 2001 From: Joxit Date: Thu, 11 May 2023 22:15:06 +0200 Subject: [PATCH 07/11] feat(utils): add support to alpha first order --- src/scripts/taglist-order.js | 19 +++++++++---------- test/taglist-order.test.js | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 10 deletions(-) diff --git a/src/scripts/taglist-order.js b/src/scripts/taglist-order.js index 3e6bde7..2d83de9 100644 --- a/src/scripts/taglist-order.js +++ b/src/scripts/taglist-order.js @@ -61,16 +61,15 @@ 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 - } + const numFirst = order.numFirst ? 1 : -1; + if (typeof e1 === 'number') { + const factor = order.numAsc ? 1 : -1; + return typeof e2 === 'number' ? (e1 - e2) * factor : -1 * numFirst; + } else if (typeof e2 === 'number') { + return 1 * numFirst; + } else { + const factor = order.alphaAsc ? 1 : -1; + return e1.localeCompare(e2) * factor; } }; diff --git a/test/taglist-order.test.js b/test/taglist-order.test.js index 96dea87..3aaf8a4 100644 --- a/test/taglist-order.test.js +++ b/test/taglist-order.test.js @@ -118,5 +118,41 @@ describe('utils tests', () => { 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 `alpha-asc;num-asc`', () => { + const comparator = getTagComparator(taglistOrderParser('alpha-asc;num-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), ['latest', 'main', '0.2.4']); + assert.deepEqual(['latest', '1.0.0-SNAPSHOT', '1.0.0'].sort(comparator), ['latest', '1.0.0', '1.0.0-SNAPSHOT']); + assert.deepEqual(['latest', 'main', 'edge'].sort(comparator), ['edge', 'latest', 'main']); + }); + + it('should sort tags with `alpha-asc;num-desc`', () => { + const comparator = getTagComparator(taglistOrderParser('alpha-asc;num-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), ['latest', 'main', '0.2.4']); + assert.deepEqual(['latest', '1.0.0-SNAPSHOT', '1.0.0'].sort(comparator), ['latest', '1.0.0', '1.0.0-SNAPSHOT']); + assert.deepEqual(['latest', 'main', 'edge'].sort(comparator), ['edge', 'latest', 'main']); + }); + + it('should sort tags with `alpha-desc;num-asc`', () => { + const comparator = getTagComparator(taglistOrderParser('alpha-desc;num-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), ['main', 'latest', '0.2.4']); + assert.deepEqual(['latest', '1.0.0-SNAPSHOT', '1.0.0'].sort(comparator), ['latest', '1.0.0', '1.0.0-SNAPSHOT']); + assert.deepEqual(['latest', 'main', 'edge'].sort(comparator), ['main', 'latest', 'edge']); + }); + + it('should sort tags with `alpha-desc;num-desc`', () => { + const comparator = getTagComparator(taglistOrderParser('alpha-desc;num-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), ['main', 'latest', '0.2.4']); + assert.deepEqual(['latest', '1.0.0-SNAPSHOT', '1.0.0'].sort(comparator), ['latest', '1.0.0', '1.0.0-SNAPSHOT']); + assert.deepEqual(['latest', 'main', 'edge'].sort(comparator), ['main', 'latest', 'edge']); + }); }); }); From 8bbfc5c390c334e66741d5a639d4b17c8fe6fcea Mon Sep 17 00:00:00 2001 From: Joxit Date: Fri, 12 May 2023 07:23:59 +0200 Subject: [PATCH 08/11] feat(taglist-order): add new option `taglist-order` --- src/components/docker-registry-ui.riot | 3 +++ src/components/tag-list/tag-list.riot | 9 ++++++--- src/index.html | 2 ++ src/scripts/docker-image.js | 27 -------------------------- 4 files changed, 11 insertions(+), 30 deletions(-) diff --git a/src/components/docker-registry-ui.riot b/src/components/docker-registry-ui.riot index c9d1cc0..c140ece 100644 --- a/src/components/docker-registry-ui.riot +++ b/src/components/docker-registry-ui.riot @@ -55,6 +55,7 @@ along with this program. If not, see . filter-results="{ state.filter }" on-authentication="{ onAuthentication }" use-control-cache-header="{ truthy(props.useControlCacheHeader) }" + taglist-order="{ taglistOrderParser(props.taglistOrder) }" > @@ -129,6 +130,7 @@ along with this program. If not, see . import { stripHttps, getRegistryServers, setRegistryServers, truthy, stringToArray } from '../scripts/utils'; import router from '../scripts/router'; import { loadTheme } from '../scripts/theme'; + import { taglistOrderParser } from '../scripts/taglist-order'; export default { components: { @@ -241,6 +243,7 @@ along with this program. If not, see . version, truthy, stringToArray, + taglistOrderParser, };