Skip to content

Commit

Permalink
sorting images (#323)
Browse files Browse the repository at this point in the history
* add sorting images

* add test
  • Loading branch information
yaroslav-codefresh authored Apr 22, 2019
1 parent 706e869 commit 3c41807
Show file tree
Hide file tree
Showing 5 changed files with 171 additions and 61 deletions.
4 changes: 2 additions & 2 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module.exports = {
'plugins': [
'mocha'
'jest'
],
'extends': 'airbnb-base',
'rules': {
Expand All @@ -13,6 +13,6 @@ module.exports = {
'no-console': 0
},
'env': {
'mocha': true,
'jest': true,
}
};
104 changes: 104 additions & 0 deletions lib/interface/cli/helpers/helpers.unit.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
const _ = require('lodash');
const helper = require('./image');
const moment = require('moment');

const { extractImages } = helper;

jest.mock('../../../logic/entities/Image', () => class {
constructor(props) {
Object.assign(this, props);
}
});

describe('helpers unit tests', () => {
describe('images', () => {
describe('#extractImages', () => {
beforeAll(() => {
helper.extractFieldsForImageEntity = jest.fn((image, tag) => ({ tag: tag.tag || tag }));
});

it('should wrap data into array if only one image passed', () => {
const image = {
tags: [{ tag: 'test', registry: 'r.cfcr.io' }],
};
expect(extractImages(image)).toEqual([{tag: 'test'}]);
});

it('should extract image tags as separate images', () => {
expect(extractImages([
{
tags: [{ tag: 'banana' }, { tag: 'beer', registry: 'r.cfcr.io' }],
},
{
tags: [{ tag: 'banana' }, { tag: 'beer', registry: 'r.cfcr.io' }],
},
])).toEqual([
{ tag: 'banana' },
{ tag: 'beer' },
{ tag: 'banana' },
{ tag: 'beer' },
]);
});

it('should filter tags by registries', () => {
expect(extractImages([
{
tags: [
{ tag: 'banana', registry: 'filtered' },
{ tag: 'beer', registry: 'r.cfcr.io' },
],
},
{
tags: [
{ tag: 'banana', registry: 'r.cfcr.io' },
{ tag: 'beer', registry: 'filtered' },
],
},
], ['r.cfcr.io'])).toEqual([
{ tag: 'beer' },
{ tag: 'banana' },
]);
});

it('should filter images tagged as "volume"', () => {
expect(extractImages([
{
tags: [
{ tag: 'volume' },
],
},
])).toEqual([]);
});

it('should add <none> literal to image if it has no tags', () => {
expect(extractImages([
{
tags: [],
},
])).toEqual([{ tag: '<none>' }]);
});

it('should sort images by date created DESC', () => {
helper.extractFieldsForImageEntity = jest.fn(({ created }) => ({ info: { created } }));
const images = [
{
created: new Date('2019-04-22T14:30:18.742Z'),
},
{
created: new Date('2019-04-22T14:40:18.741Z'),
},
{
created: new Date('2019-04-22T14:45:18.742Z'),
},
];
const extracted = extractImages(images);
const extractedDates = _.map(extracted, i => i.info.created);
const initialSortedDates = _.chain(images)
.orderBy(['created'], ['desc'])
.map(i => i.created)
.value();
expect(extractedDates).toEqual(initialSortedDates);
});
});
});
});
107 changes: 59 additions & 48 deletions lib/interface/cli/helpers/image.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,58 +3,69 @@ const filesize = require('filesize');
const Image = require('../../../logic/entities/Image');
const DEFAULTS = require('../../cli/defaults');

const NONE_TAG = '<none>';

const extractFieldsForImageEntity = (image, tag) => {
const newImage = {
name: image.imageDisplayName,
size: filesize(image.size),
_id: image._id,
annotations: _.get(image, 'metadata', {}),
tagId: tag._id,
created: image.created ? new Date(image.created) : undefined,
};
newImage.id = image.internalImageId ? image.internalImageId.substring(0, 12) : '\b';
if (_.isEqual(tag, '<none>')) {
newImage.tag = tag;
newImage.pull = '';
} else {
newImage.tag = tag.tag;
newImage.pull = `${tag.registry}/${tag.repository}:${tag.tag}`;
class ImagesHelper {
constructor() {
this.extractFieldsForImageEntity = this.extractFieldsForImageEntity.bind(this);
this.extractImages = this.extractImages.bind(this);
}
return newImage;
};


const extractImages = (images, filterRegistries) => {
if (!_.isArray(images)) {
images = [images];
extractFieldsForImageEntity(image, tag){
const newImage = {
name: image.imageDisplayName,
size: filesize(image.size),
_id: image._id,
annotations: _.get(image, 'metadata', {}),
tagId: tag._id,
created: image.created ? new Date(image.created) : undefined,
};
newImage.id = image.internalImageId ? image.internalImageId.substring(0, 12) : '\b';
if (_.isEqual(tag, NONE_TAG)) {
newImage.tag = tag;
newImage.pull = '';
} else {
newImage.tag = tag.tag;
newImage.pull = `${tag.registry}/${tag.repository}:${tag.tag}`;
}
return newImage;
}
return _.flatten(images.map((image) => {
const res = [];
let addedCfCrTag = false;
_.forEach(image.tags, (tag) => {
if (_.isEqual(tag.tag, 'volume')) {
addedCfCrTag = true;
return;
}
// in case we are filtering by registries, ignore the image if it is not from the registires list
if (filterRegistries && filterRegistries.indexOf(tag.registry) === -1) {
return;
}
if (DEFAULTS.CODEFRESH_REGISTRIES.indexOf(tag.registry) !== -1) {
addedCfCrTag = true;
}
const data = extractFieldsForImageEntity(image, tag);
res.push(new Image(data));
});
if (_.isEmpty(image.tags) || !addedCfCrTag) {
const data = extractFieldsForImageEntity(image, '<none>');
res.push(new Image(data));


extractImages(images, filterRegistries) {
if (!_.isArray(images)) {
images = [images]; // eslint-disable-line no-param-reassign
}
return res;
}));
};
return _.chain(images)
.map((image) => {
const res = [];
let addedCfCrTag = false;
_.forEach(image.tags, (tag) => {
if (_.isEqual(tag.tag, 'volume')) {
addedCfCrTag = true;
return;
}
// in case we are filtering by registries, ignore the image if it is not from the registires list
if (filterRegistries && !_.includes(filterRegistries, tag.registry)) {
return;
}
if (_.includes(DEFAULTS.CODEFRESH_REGISTRIES, tag.registry)) {
addedCfCrTag = true;
}
const data = this.extractFieldsForImageEntity(image, tag);
res.push(new Image(data));
});
if (_.isEmpty(image.tags) || !addedCfCrTag) {
const data = this.extractFieldsForImageEntity(image, NONE_TAG);
res.push(new Image(data));
}
return res;
})
.flatten()
.orderBy(['info.created'], ['desc'])
.value();
}
}

module.exports = {
extractImages,
};
module.exports = new ImagesHelper();
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "codefresh",
"version": "0.18.0",
"version": "0.18.1",
"description": "Codefresh command line utility",
"main": "index.js",
"preferGlobal": true,
Expand Down Expand Up @@ -76,7 +76,7 @@
"eslint": "^4.11.0",
"eslint-config-airbnb-base": "^12.1.0",
"eslint-plugin-import": "^2.8.0",
"eslint-plugin-mocha": "^4.11.0",
"eslint-plugin-jest": "^22.4.1",
"hugo-cli": "^0.5.4",
"jest": "^23.6.0",
"pkg": "^4.3.5"
Expand Down
13 changes: 4 additions & 9 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1547,11 +1547,10 @@ eslint-plugin-import@^2.8.0:
minimatch "^3.0.3"
read-pkg-up "^2.0.0"

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

eslint-restricted-globals@^0.1.1:
version "0.1.1"
Expand Down Expand Up @@ -4371,10 +4370,6 @@ [email protected]:
version "0.15.1"
resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.15.1.tgz#b227f79e9ff0acee1955d582f18681eb02c4dc2a"

ramda@^0.25.0:
version "0.25.0"
resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.25.0.tgz#8fdf68231cffa90bc2f9460390a0cb74a29b29a9"

randomatic@^1.1.3:
version "1.1.7"
resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c"
Expand Down

0 comments on commit 3c41807

Please sign in to comment.