feat(taglist-order): add new option `TAGLIST_ORDER` (#307)
Create new option named `TAGLIST_ORDER` that will order tags using user defined configuration.
Available values are:
| value | description |
| --- | --- |
| `num-asc;alpha-asc` | Numbers come first in **ascending** order then alphabet in **ascending** order |
| `num-desc;alpha-asc` | Numbers come first in **descending** order then alphabet in **ascending** order |
| `num-asc;alpha-desc` | Numbers come first in **ascending** order then alphabet in **descending** order |
| `num-desc;alpha-desc` | Numbers come first in **descending** order then alphabet in **descending** order |
| `alpha-asc;num-asc` | Alphabet come first in **ascending** order then numbers in **ascending** order |
| `alpha-asc;num-desc` (default) | Alphabet come first in **ascending** order then numbers in **descending** order |
| `alpha-desc;num-asc` | Alphabet come first in **descending** order then numbers in **ascending** order |
| `alpha-desc;num-desc` | Alphabet come first in **descending** order then numbers in **descending** order |
Some examples in [test/taglist-order.test.js](8bbfc5c390/test/taglist-order.test.js
)
closes #294
This commit is contained in:
commit
d2222bef05
|
@ -96,6 +96,7 @@ Some env options are available for use this interface for **only one server** (w
|
|||
- `USE_CONTROL_CACHE_HEADER`: Use `Control-Cache` header and set to `no-store, no-cache`. This will avoid some issues on multi-arch images (see [#260](https://github.com/Joxit/docker-registry-ui/issues/260) and [#265](https://github.com/Joxit/docker-registry-ui/pull/265)). This option requires registry configuration: `Access-Control-Allow-Headers` with `Cache-Control`. (default: `false`). Since 2.3.0
|
||||
- `THEME`: Chose your default theme, could be `dark`, `light` or `auto` (see [#283](https://github.com/Joxit/docker-registry-ui/pull/283)). When auto is selected, you will have a switch to manually change from light to dark and vice-versa (see [#291](https://github.com/Joxit/docker-registry-ui/pull/291)). (default: `auto`). Since 2.4.0
|
||||
- `THEME_*`: See table in [Theme options](#theme-options) section (see [#283](https://github.com/Joxit/docker-registry-ui/pull/283)). Since 2.4.0
|
||||
- `TAGLIST_ORDER`: Set the default order for the taglist page, could be `num-asc;alpha-asc`, `num-desc;alpha-asc`, `num-asc;alpha-desc`, `num-desc;alpha-desc`, `alpha-asc;num-asc`, `alpha-asc;num-desc`, `alpha-desc;num-asc` or `alpha-desc;num-desc` (see [#307](https://github.com/Joxit/docker-registry-ui/pull/307)). (default: `alpha-asc;num-desc`) Since 2.5.0
|
||||
|
||||
There are some examples with [docker-compose](https://docs.docker.com/compose/) and docker-registry-ui as proxy [here](https://github.com/Joxit/docker-registry-ui/tree/main/examples/ui-as-proxy/) or docker-registry-ui as standalone [here](https://github.com/Joxit/docker-registry-ui/tree/main/examples/ui-as-standalone/).
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ sed -i "s~\${READ_ONLY_REGISTRIES}~${READ_ONLY_REGISTRIES}~" index.html
|
|||
sed -i "s~\${SHOW_CATALOG_NB_TAGS}~${SHOW_CATALOG_NB_TAGS}~" index.html
|
||||
sed -i "s~\${HISTORY_CUSTOM_LABELS}~${HISTORY_CUSTOM_LABELS}~" index.html
|
||||
sed -i "s~\${USE_CONTROL_CACHE_HEADER}~${USE_CONTROL_CACHE_HEADER}~" index.html
|
||||
sed -i "s~\${TAGLIST_ORDER}~${TAGLIST_ORDER}~" index.html
|
||||
|
||||
grep -o 'THEME[A-Z_]*' index.html | while read e; do
|
||||
sed -i "s~\${$e}~$(printenv $e)~" index.html
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -55,6 +55,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
filter-results="{ state.filter }"
|
||||
on-authentication="{ onAuthentication }"
|
||||
use-control-cache-header="{ truthy(props.useControlCacheHeader) }"
|
||||
taglist-order="{ props.taglistOrder }"
|
||||
></tag-list>
|
||||
</route>
|
||||
<route path="{baseRoute}taghistory/(.*)">
|
||||
|
|
|
@ -61,11 +61,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
<script>
|
||||
import { Http } from '../../scripts/http';
|
||||
import { DockerImage, compare } from '../../scripts/docker-image';
|
||||
import { DockerImage } from '../../scripts/docker-image';
|
||||
import { getNumPages, getPageLabels } from '../../scripts/utils';
|
||||
import Pagination from './pagination.riot';
|
||||
import TagTable from './tag-table.riot';
|
||||
import router from '../../scripts/router';
|
||||
import { getTagComparator, taglistOrderParser } from '../../scripts/taglist-order';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Pagination,
|
||||
|
@ -79,6 +81,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
asc: true,
|
||||
page: router.getPageQueryParam() || 1,
|
||||
};
|
||||
try {
|
||||
this.state.taglistOrder = taglistOrderParser(props.taglistOrder)
|
||||
} catch(e) {
|
||||
props.onNotify(e);
|
||||
}
|
||||
},
|
||||
onMounted(props, state) {
|
||||
this.display(props, state);
|
||||
|
@ -86,6 +93,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
// this may be run before the final document size is available, so schedule
|
||||
// a correction once everything is set up.
|
||||
window.requestAnimationFrame(this.onResize);
|
||||
this.tagComparator = getTagComparator(props.taglistOrder);
|
||||
},
|
||||
display(props, state) {
|
||||
state.tags = [];
|
||||
|
@ -106,7 +114,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
useControlCacheHeader: props.useControlCacheHeader,
|
||||
})
|
||||
)
|
||||
.sort(compare);
|
||||
.sort(self.tagComparator);
|
||||
window.requestAnimationFrame(self.onResize);
|
||||
self.update({
|
||||
page: Math.min(state.page, getNumPages(tags)),
|
||||
|
@ -168,7 +176,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
this.state.tags.reverse();
|
||||
this.state.asc = false;
|
||||
} else {
|
||||
this.state.tags.sort(compare);
|
||||
this.state.tags.sort(this.tagComparator);
|
||||
this.state.asc = true;
|
||||
}
|
||||
this.update();
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
show-catalog-nb-tags="${SHOW_CATALOG_NB_TAGS}"
|
||||
history-custom-labels="${HISTORY_CUSTOM_LABELS}"
|
||||
use-control-cache-header="${USE_CONTROL_CACHE_HEADER}"
|
||||
taglist-order="${TAGLIST_ORDER}"
|
||||
theme="${THEME}"
|
||||
theme-primary-text="${THEME_PRIMARY_TEXT}"
|
||||
theme-neutral-text="${THEME_NEUTRAL_TEXT}"
|
||||
|
@ -73,6 +74,7 @@
|
|||
show-catalog-nb-tags="true"
|
||||
history-custom-labels="first_custom_labels,second_custom_labels"
|
||||
use-control-cache-header="false"
|
||||
taglist-order=""
|
||||
theme="auto"
|
||||
theme-primary-text=""
|
||||
theme-neutral-text=""
|
||||
|
|
|
@ -18,33 +18,6 @@ import { Http } from './http';
|
|||
import { isDigit, eventTransfer, ERROR_CAN_NOT_READ_CONTENT_DIGEST } from './utils';
|
||||
import observable from '@riotjs/observable';
|
||||
|
||||
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 function compare(e1, e2) {
|
||||
const tag1 = e1.tag.match(/./g).reduce(tagReduce, []);
|
||||
const tag2 = e2.tag.match(/./g).reduce(tagReduce, []);
|
||||
|
||||
for (var i = 0; i < tag1.length && i < tag2.length; i++) {
|
||||
const compare = tag1[i].localeCompare(tag2[i]);
|
||||
if (isDigit(tag1[i].charAt(0)) && isDigit(tag2[i].charAt(0))) {
|
||||
const diff = tag1[i] - tag2[i];
|
||||
if (diff != 0) {
|
||||
return diff;
|
||||
}
|
||||
} else if (compare != 0) {
|
||||
return compare;
|
||||
}
|
||||
}
|
||||
return e1.tag.length - e2.tag.length;
|
||||
}
|
||||
|
||||
export class DockerImage {
|
||||
constructor(name, tag, { list, registryUrl, onNotify, onAuthentication, useControlCacheHeader }) {
|
||||
this.name = name;
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
export class DockerRegistryUIError extends Error {
|
||||
constructor(msg) {
|
||||
super(msg);
|
||||
this.isError = true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
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 'alpha-asc;num-desc';
|
||||
} else if (TAGLIST_ORDER_REGEX.test(taglistOrder)) {
|
||||
return taglistOrder;
|
||||
}
|
||||
throw new DockerRegistryUIError(`The taglist 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));
|
||||
|
||||
const applyOrder = (order, e1, e2) => {
|
||||
if (e1 === e2) {
|
||||
return 0;
|
||||
}
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
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;
|
||||
};
|
||||
};
|
|
@ -0,0 +1,163 @@
|
|||
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';
|
||||
|
||||
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 default order', () => {
|
||||
const expected = 'alpha-asc;num-desc';
|
||||
[undefined, ''].forEach((e) => assert.deepEqual(taglistOrderVariants(e), expected));
|
||||
});
|
||||
|
||||
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'].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}`)
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('taglistOrderParser', () => {
|
||||
it('should have default configuration when empty or undefined', () => {
|
||||
const expected = { numAsc: false, alphaAsc: true, numFirst: false };
|
||||
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(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(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(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);
|
||||
});
|
||||
});
|
||||
|
||||
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']);
|
||||
});
|
||||
});
|
||||
|
||||
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']);
|
||||
});
|
||||
|
||||
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']);
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue