Skip to content
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

Give the NPM package some love #2200

Merged
merged 14 commits into from
Oct 30, 2018
Merged

Give the NPM package some love #2200

merged 14 commits into from
Oct 30, 2018

Conversation

chris48s
Copy link
Member

Following on from the discussion in #1388 I've done a bit of work to whip the NPM package into shape so we can do a 2.0.0-beta1 release. There is one additional issue I think we should consider before publishing a 2.0.0 release:

Is it useful to force the user to make a choice of text measurer in order to generate a badge? Would it be better to be opinionated on this and provide a simpler public interface using either PDFKitTextMeasurer or QuickTextMeasurer (at least as a default)? As a point of reference, the CLI uses PDFKitTextMeasurer only.

@chris48s chris48s added the core Server, BaseService, GitHub auth label Oct 20, 2018
@shields-ci
Copy link

shields-ci commented Oct 20, 2018

Warnings
⚠️

This PR added helper modules in lib/ but not accompanying tests.
Generally helper modules should have their own tests.

Messages
📖

✨ Thanks for your contribution to Shields, @chris48s!

📖

Thanks for contributing to our documentation. We ❤️ our documentarians!

Generated by 🚫 dangerJS

PyvesB
PyvesB previously approved these changes Oct 22, 2018
Copy link
Member

@PyvesB PyvesB left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. I agree that we should hide PDFKitTextMeasurer and QuickTextMeasurer from the public interface. 👍

@chris48s
Copy link
Member Author

I agree that we should hide PDFKitTextMeasurer and QuickTextMeasurer from the public interface.

OK - cheers. Given this is the only outstanding thing and will change the public interface and docs, lets tack that on to this PR.

Do you have a feel for whether it is sensible for the default (or possibly only) measurer to be QuickTextMeasurer or PDFKitTextMeasurer? We use QuickTextMeasurer on shields.io and PDFKitTextMeasurer in the CLI but I'm unclear on whether they are different for a good reason or because we changed it in one place and forgot to change it in the other.

Any thoughts?

@PyvesB
Copy link
Member

PyvesB commented Oct 23, 2018

After looking into this some more, as far as I can tell, these are both custom classes that we've written in text-measurer.js. QuickTextMeasurer uses PDFKitTextMeasurer but adds an additional layer of kerning/caching. Therefore I don't think that saying one is fast and the other accurate is correct.

The CLI targets one-off generations, therefore it doesn't make sense to add the caching capabilities, it would only slow things down.

If users use this as part of a Node module, they may or may not benefit from having caching depending on their use-case. However I think that they are most likely to write something that will call makeBadge several times and even if they don't, the performance impact of having to initialise and populate the cache will probably be negligible. Therefore I would go for QuickTextMeasurer as a default in the NPM module. We could also provide an alternative method or an optional withoutCache flag if users really want to override the default. 😉

@chris48s
Copy link
Member Author

chris48s commented Oct 23, 2018

After looking into this some more, as far as I can tell, these are both custom classes that we've written in text-measurer.js. QuickTextMeasurer uses PDFKitTextMeasurer but adds an additional layer of kerning/caching. Therefore I don't think that saying one is fast and the other accurate is correct.

Aah yes I see you've used the classic "work out what's going on by actually reading the code" technique - cunning :)

My initial thought on this was that we should probably decouple the LRU cache from the badge generation (which would imply just using PDFKitTextMeasurer) but maybe that instinct is wrong.

We could also provide an alternative method or an optional withoutCache flag

Where possible I prefer the boolean condition to be positive. i.e: true should enable the thing and false should disable it rather than using a disableThing=true param) so I'd tend to think of it the other way round: call the param cache and default it to true.. but yeah, agreed.

I'll update this tomorrow. Cheers.

@chris48s
Copy link
Member Author

How does this feel as a new public surface for the package?

PyvesB
PyvesB previously approved these changes Oct 24, 2018
Copy link
Member

@PyvesB PyvesB left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The public interface is clean and simple, I like it. 👍

badge(format, (svg, err) => {
// svg is a string containing your badge
})})
const svg = bf.create(format)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this is sync now?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep. As noted in #1388 (comment) its now synchronous

lib/gh-badges.js Show resolved Hide resolved
PyvesB
PyvesB previously approved these changes Oct 27, 2018
@paulmelnikow
Copy link
Member

Using PDFKitTextMeasurer will be faster for one-shot badge generation, since it only measures the two strings that are being used. On the other hand, QuickTextMeasurer builds the entire kerning table on startup, so it's slower. It would only be faster if you're generating hundreds of badges inside a single Node process, which I expect most people are not. (We should get rid of both of these things and just publish the lookup table, but that's a project for another day.)

lib/gh-badges.js Outdated
const { PDFKitTextMeasurer, QuickTextMeasurer } = require('./text-measurer')

class BadgeFactory {
constructor({ fontPath, fallbackFontPath, cache = true }) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

QuickTextMeasurer doesn't cache as much as it memoizes the most common inputs. Something like precomputeWidths would be more accurate.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed. Do you think this should default to true or false?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

false, since I’d wager the most common use will be generating a single badge.

* @param {string} format.colorB
* @param {string} format.format
* @param {string} format.template
* @return {string} Badge in SVG or JSON format
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd love to switch this over to the schema we're using for new-style services, though that could definitely happen another day.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The DocBlock is helpful, because it allows editors/IDEs to show inline help, but we could definitely improve the validation. Lets save that for a minor release though

@chris48s chris48s merged commit 6fc8744 into badges:master Oct 30, 2018
@shields-deployment
Copy link

This pull request was merged to master branch. This change is now waiting for deployment, which will usually happen within a few days. Stay tuned by joining our #ops channel on Discord!

After deployment, changes are copied to gh-pages branch:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core Server, BaseService, GitHub auth
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants