-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[MicroBadger] Add MicroBadger #1340
Conversation
I've seen the pull request with CircleCI and there "flaky tests" are mentioned. To be honest, locally my new tests fail sometimes due to to a long response from the MicroBadger API (more than 2 seconds). I don't know what the best solution in that case. I can stub every request but I saw in other PRs that you ask to add a few "live" tests, so, I need your suggestion here. |
Hi, thanks for this!
I should clarify that. We want tests that hit the real services. They're unreliable by necessity. I should think of a value-neutral way to say "unreliable." 😜 There's a long discussion of the test strategy in #927.
Since readme images are served through GitHub's proxy (camo) which has its own timeout, they may be unreliable there too. We will increase the test timeout, so tests that occasionally take longer than 2s do not cause failures. This is waiting on a release of IcedFrisby which includes IcedFrisby/IcedFrisby#71 which I should wrap up! |
Ok, that makes sense! So, let me know if you need something more from my side to merge it. Feel free to make notes about the code. |
@paulmelnikow : sure, I'll take care of it later in the evening. 😉 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks very much for working on this. I've left some comments for things you could improve but its shaping up nicely :) Some of my comments may benefit from clarification from another reviewer.
service-tests/microbadger.js
Outdated
.get('/image-size/_/httpd/alpine.json') | ||
.expectJSONTypes(Joi.object().keys({ | ||
name: 'image size', | ||
value: Joi.string().regex(/^[0-9]+[kMGTPEZY]B$/) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the convention for this project is that when writing a service test for a badge that uses metric()
, the test should make a call that should generate a non-zero value and check the result with a regex that ensures the badge value is non-zero: /^[1-9][0-9]*[kMGTPEZY]?$/
. See https://github.com/badges/shields/blob/master/service-tests/helpers/validators.js#L38-L43
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We also have isFileSize, though probably it should be modified to reject 0 as well!
server.js
Outdated
var image; | ||
|
||
if (tag) { | ||
if (!parsedData['Versions']) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this project have a convention for dot-notation vs square-bracket on object properties, or we not care?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see we waiting for the answer of another maintainer but personally, I use square-bracket only when the key has an uppercase first letter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For historical reasons server.js
has really lax rules, and we're about to rewrite the services which will slowly empty it out. Elsewhere our code uses dots on any possible key (c.f. eslint-config-standard).
server.js
Outdated
user = 'library'; | ||
} | ||
var path = user + '/' + repo; | ||
var url = 'https://api.microbadger.com/v1/images/' + path; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know a lot of the code in server.js
uses var
, but when adding new code maybe it would be better to make use of let
and const
where possible. For example url
, repo
, format
etc here are declared and never re-assigned so could be declared with const
. Similarly, i
, j
, versionJson
, tagJson
further down are unnecessarily defined with function scope and could be block-scoped by declaring them with let
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, I'll change it. Totally makes sense. I just see that the most part uses var
and the linter doesn't complain, so, I tried to be like majority :)
server.js
Outdated
return; | ||
} | ||
|
||
if (type == 'image-size') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we compare using ===
here
server.js
Outdated
if (type == 'image-size') { | ||
var size = metric(image['DownloadSize']) + "B"; | ||
badgeData.text[1] = size; | ||
} else if (type == 'layers') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...and here
} else { | ||
image = parsedData; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a chunk of logic in the middle here which parses the api response to find the latest tag. Could this be extracted to a helper?
To follow convention, you would create /lib/microbadger-helpers.js
and move this bit of logic to a function getLatestTag()
or getLatestVersionTag()
or something. That would reduce the amount of branching/logic in this function making it easier to read and by factoring it out it would be easier to test. You could add few unit tests for it in /lib/microbadger-spec.js
.
If you have a look through /lib
there are some examples following this pattern that you can crib from.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, I'll take a look! Thank you for the tip. I've just seen several other services with similar complexity code but I would like to break off that code too.
oh, also could you rename the pull request so it is prefixed with |
@chris48s did you not see my comment above? I had literally almost finished my review and, as one would expect, I had picked up mostly similar comments to yours (see below for some extra points). While consecutive reviews may be valuable, there is no point in several people reviewing the exact same code at the exact same time and stepping on each other's toes. I guess I have wasted my time and can discard most of my work. |
@PyvesB - oh no! Sorry. We must have been looking at it at the same time. Really sorry we've duplicated effort here. I'll make sure I communicate more clearly in future to avoid this :( |
service-tests/microbadger.js
Outdated
t.create('layers without a specified tag') | ||
.get('/layers/_/hello-world.json') | ||
.expectJSONTypes(Joi.object().keys({ name: 'layers', | ||
value: Joi.number().integer() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could probably make this slightly more restrictive by using Joi.number().integer().positive()
. Also, I believe the formatting is not entirely consistent with your other tests.
server.js
Outdated
} | ||
|
||
if (type == 'image-size') { | ||
var size = metric(image['DownloadSize']) + "B"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you use our prettyBytes
helper function here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I like it
server.js
Outdated
if (user === '_') { | ||
user = 'library'; | ||
} | ||
var path = user + '/' + repo; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would this be a good candidate for using template strings?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, why not
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lib/all-badge-examples.js
Outdated
previewUri: '/microbadger/image-size/_/httpd.svg', | ||
keywords: [ | ||
'docker', | ||
'microbadger' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'microbadger'
is not needed since it is in the title. Seems there are some others that should be cleaned up as well. I'd love to set up Danger to catch things like this!
}, | ||
{ | ||
title: 'MicroBadger Layers', | ||
previewUri: '/microbadger/layers/_/httpd.svg', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does layers support tag as well? Perhaps it would be worth including a fourth example.
Thank everyone for the review. I tried to fix all of your notes except extracting the parsing logic into a helper. I'll make an effort to do it tomorrow |
You can get CircleCI running again by merging master into this branch. |
b520f13
to
b05381e
Compare
@paulmelnikow I've updated the pull request with adding a helper. I didn't add a test for it because the helper is tested already by the general tests and to be honest I'm too lazy to add something more to test the same thing. I would have liked to add it if had thought about it at the beginning of the development because it could be useful in that case. |
b05381e
to
0368487
Compare
lib/microbadger-helpers.js
Outdated
} | ||
} | ||
} | ||
return result; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I'm understanding correctly, this would be equivalent:
return data.Versions.find(v => v.Tags.some(t => t.tag === tag))
Since you only call it once, you could move that code to the handler and eliminate the helper.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, you got it correctly. Thanks for the refs though!
@paulmelnikow I removed the helper a changed conditions a little |
Thanks for your work! |
Added support for MicroBadger image size and layers with ability to choose a tag (#944)