Skip to content

Commit 3c41807

Browse files
sorting images (#323)
* add sorting images * add test
1 parent 706e869 commit 3c41807

File tree

5 files changed

+171
-61
lines changed

5 files changed

+171
-61
lines changed

.eslintrc.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module.exports = {
22
'plugins': [
3-
'mocha'
3+
'jest'
44
],
55
'extends': 'airbnb-base',
66
'rules': {
@@ -13,6 +13,6 @@ module.exports = {
1313
'no-console': 0
1414
},
1515
'env': {
16-
'mocha': true,
16+
'jest': true,
1717
}
1818
};
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
const _ = require('lodash');
2+
const helper = require('./image');
3+
const moment = require('moment');
4+
5+
const { extractImages } = helper;
6+
7+
jest.mock('../../../logic/entities/Image', () => class {
8+
constructor(props) {
9+
Object.assign(this, props);
10+
}
11+
});
12+
13+
describe('helpers unit tests', () => {
14+
describe('images', () => {
15+
describe('#extractImages', () => {
16+
beforeAll(() => {
17+
helper.extractFieldsForImageEntity = jest.fn((image, tag) => ({ tag: tag.tag || tag }));
18+
});
19+
20+
it('should wrap data into array if only one image passed', () => {
21+
const image = {
22+
tags: [{ tag: 'test', registry: 'r.cfcr.io' }],
23+
};
24+
expect(extractImages(image)).toEqual([{tag: 'test'}]);
25+
});
26+
27+
it('should extract image tags as separate images', () => {
28+
expect(extractImages([
29+
{
30+
tags: [{ tag: 'banana' }, { tag: 'beer', registry: 'r.cfcr.io' }],
31+
},
32+
{
33+
tags: [{ tag: 'banana' }, { tag: 'beer', registry: 'r.cfcr.io' }],
34+
},
35+
])).toEqual([
36+
{ tag: 'banana' },
37+
{ tag: 'beer' },
38+
{ tag: 'banana' },
39+
{ tag: 'beer' },
40+
]);
41+
});
42+
43+
it('should filter tags by registries', () => {
44+
expect(extractImages([
45+
{
46+
tags: [
47+
{ tag: 'banana', registry: 'filtered' },
48+
{ tag: 'beer', registry: 'r.cfcr.io' },
49+
],
50+
},
51+
{
52+
tags: [
53+
{ tag: 'banana', registry: 'r.cfcr.io' },
54+
{ tag: 'beer', registry: 'filtered' },
55+
],
56+
},
57+
], ['r.cfcr.io'])).toEqual([
58+
{ tag: 'beer' },
59+
{ tag: 'banana' },
60+
]);
61+
});
62+
63+
it('should filter images tagged as "volume"', () => {
64+
expect(extractImages([
65+
{
66+
tags: [
67+
{ tag: 'volume' },
68+
],
69+
},
70+
])).toEqual([]);
71+
});
72+
73+
it('should add <none> literal to image if it has no tags', () => {
74+
expect(extractImages([
75+
{
76+
tags: [],
77+
},
78+
])).toEqual([{ tag: '<none>' }]);
79+
});
80+
81+
it('should sort images by date created DESC', () => {
82+
helper.extractFieldsForImageEntity = jest.fn(({ created }) => ({ info: { created } }));
83+
const images = [
84+
{
85+
created: new Date('2019-04-22T14:30:18.742Z'),
86+
},
87+
{
88+
created: new Date('2019-04-22T14:40:18.741Z'),
89+
},
90+
{
91+
created: new Date('2019-04-22T14:45:18.742Z'),
92+
},
93+
];
94+
const extracted = extractImages(images);
95+
const extractedDates = _.map(extracted, i => i.info.created);
96+
const initialSortedDates = _.chain(images)
97+
.orderBy(['created'], ['desc'])
98+
.map(i => i.created)
99+
.value();
100+
expect(extractedDates).toEqual(initialSortedDates);
101+
});
102+
});
103+
});
104+
});

lib/interface/cli/helpers/image.js

Lines changed: 59 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -3,58 +3,69 @@ const filesize = require('filesize');
33
const Image = require('../../../logic/entities/Image');
44
const DEFAULTS = require('../../cli/defaults');
55

6+
const NONE_TAG = '<none>';
67

7-
const extractFieldsForImageEntity = (image, tag) => {
8-
const newImage = {
9-
name: image.imageDisplayName,
10-
size: filesize(image.size),
11-
_id: image._id,
12-
annotations: _.get(image, 'metadata', {}),
13-
tagId: tag._id,
14-
created: image.created ? new Date(image.created) : undefined,
15-
};
16-
newImage.id = image.internalImageId ? image.internalImageId.substring(0, 12) : '\b';
17-
if (_.isEqual(tag, '<none>')) {
18-
newImage.tag = tag;
19-
newImage.pull = '';
20-
} else {
21-
newImage.tag = tag.tag;
22-
newImage.pull = `${tag.registry}/${tag.repository}:${tag.tag}`;
8+
class ImagesHelper {
9+
constructor() {
10+
this.extractFieldsForImageEntity = this.extractFieldsForImageEntity.bind(this);
11+
this.extractImages = this.extractImages.bind(this);
2312
}
24-
return newImage;
25-
};
2613

2714

28-
const extractImages = (images, filterRegistries) => {
29-
if (!_.isArray(images)) {
30-
images = [images];
15+
extractFieldsForImageEntity(image, tag){
16+
const newImage = {
17+
name: image.imageDisplayName,
18+
size: filesize(image.size),
19+
_id: image._id,
20+
annotations: _.get(image, 'metadata', {}),
21+
tagId: tag._id,
22+
created: image.created ? new Date(image.created) : undefined,
23+
};
24+
newImage.id = image.internalImageId ? image.internalImageId.substring(0, 12) : '\b';
25+
if (_.isEqual(tag, NONE_TAG)) {
26+
newImage.tag = tag;
27+
newImage.pull = '';
28+
} else {
29+
newImage.tag = tag.tag;
30+
newImage.pull = `${tag.registry}/${tag.repository}:${tag.tag}`;
31+
}
32+
return newImage;
3133
}
32-
return _.flatten(images.map((image) => {
33-
const res = [];
34-
let addedCfCrTag = false;
35-
_.forEach(image.tags, (tag) => {
36-
if (_.isEqual(tag.tag, 'volume')) {
37-
addedCfCrTag = true;
38-
return;
39-
}
40-
// in case we are filtering by registries, ignore the image if it is not from the registires list
41-
if (filterRegistries && filterRegistries.indexOf(tag.registry) === -1) {
42-
return;
43-
}
44-
if (DEFAULTS.CODEFRESH_REGISTRIES.indexOf(tag.registry) !== -1) {
45-
addedCfCrTag = true;
46-
}
47-
const data = extractFieldsForImageEntity(image, tag);
48-
res.push(new Image(data));
49-
});
50-
if (_.isEmpty(image.tags) || !addedCfCrTag) {
51-
const data = extractFieldsForImageEntity(image, '<none>');
52-
res.push(new Image(data));
34+
35+
36+
extractImages(images, filterRegistries) {
37+
if (!_.isArray(images)) {
38+
images = [images]; // eslint-disable-line no-param-reassign
5339
}
54-
return res;
55-
}));
56-
};
40+
return _.chain(images)
41+
.map((image) => {
42+
const res = [];
43+
let addedCfCrTag = false;
44+
_.forEach(image.tags, (tag) => {
45+
if (_.isEqual(tag.tag, 'volume')) {
46+
addedCfCrTag = true;
47+
return;
48+
}
49+
// in case we are filtering by registries, ignore the image if it is not from the registires list
50+
if (filterRegistries && !_.includes(filterRegistries, tag.registry)) {
51+
return;
52+
}
53+
if (_.includes(DEFAULTS.CODEFRESH_REGISTRIES, tag.registry)) {
54+
addedCfCrTag = true;
55+
}
56+
const data = this.extractFieldsForImageEntity(image, tag);
57+
res.push(new Image(data));
58+
});
59+
if (_.isEmpty(image.tags) || !addedCfCrTag) {
60+
const data = this.extractFieldsForImageEntity(image, NONE_TAG);
61+
res.push(new Image(data));
62+
}
63+
return res;
64+
})
65+
.flatten()
66+
.orderBy(['info.created'], ['desc'])
67+
.value();
68+
}
69+
}
5770

58-
module.exports = {
59-
extractImages,
60-
};
71+
module.exports = new ImagesHelper();

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "codefresh",
3-
"version": "0.18.0",
3+
"version": "0.18.1",
44
"description": "Codefresh command line utility",
55
"main": "index.js",
66
"preferGlobal": true,
@@ -76,7 +76,7 @@
7676
"eslint": "^4.11.0",
7777
"eslint-config-airbnb-base": "^12.1.0",
7878
"eslint-plugin-import": "^2.8.0",
79-
"eslint-plugin-mocha": "^4.11.0",
79+
"eslint-plugin-jest": "^22.4.1",
8080
"hugo-cli": "^0.5.4",
8181
"jest": "^23.6.0",
8282
"pkg": "^4.3.5"

yarn.lock

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1547,11 +1547,10 @@ eslint-plugin-import@^2.8.0:
15471547
minimatch "^3.0.3"
15481548
read-pkg-up "^2.0.0"
15491549

1550-
eslint-plugin-mocha@^4.11.0:
1551-
version "4.12.1"
1552-
resolved "https://registry.yarnpkg.com/eslint-plugin-mocha/-/eslint-plugin-mocha-4.12.1.tgz#dbacc543b178b4536ec5b19d7f8e8864d85404bf"
1553-
dependencies:
1554-
ramda "^0.25.0"
1550+
eslint-plugin-jest@^22.4.1:
1551+
version "22.4.1"
1552+
resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-22.4.1.tgz#a5fd6f7a2a41388d16f527073b778013c5189a9c"
1553+
integrity sha512-gcLfn6P2PrFAVx3AobaOzlIEevpAEf9chTpFZz7bYfc7pz8XRv7vuKTIE4hxPKZSha6XWKKplDQ0x9Pq8xX2mg==
15551554

15561555
eslint-restricted-globals@^0.1.1:
15571556
version "0.1.1"
@@ -4371,10 +4370,6 @@ ramda@0.15.1:
43714370
version "0.15.1"
43724371
resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.15.1.tgz#b227f79e9ff0acee1955d582f18681eb02c4dc2a"
43734372

4374-
ramda@^0.25.0:
4375-
version "0.25.0"
4376-
resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.25.0.tgz#8fdf68231cffa90bc2f9460390a0cb74a29b29a9"
4377-
43784373
randomatic@^1.1.3:
43794374
version "1.1.7"
43804375
resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c"

0 commit comments

Comments
 (0)