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

generate static examples without api call [apm appveyor cdnjs clojars gem npm uptimerobot] #1740

Merged
merged 28 commits into from
Aug 23, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
e2c930c
allow service classes to define a staticExample
chris48s Aug 12, 2018
ca4c1a0
define static example for cdnjs
chris48s Aug 12, 2018
1c9305f
rename method
chris48s Aug 13, 2018
48ab922
Merge branch 'master' into issue1700-a
chris48s Aug 13, 2018
af19ff0
encode special chars in URL
chris48s Aug 13, 2018
35b6999
add tests
chris48s Aug 13, 2018
687dda5
use a placeholder instead of a real name
chris48s Aug 14, 2018
0e59399
update other new-style services to use static examples
chris48s Aug 15, 2018
5b26ba1
update all-badge-examples test to expect static example
chris48s Aug 15, 2018
6fae315
coding standards
chris48s Aug 15, 2018
6bee4c4
use :param instead of PARAM
chris48s Aug 18, 2018
960d600
clarify query params test
chris48s Aug 19, 2018
23327ee
rename exampleUrl/Uri to placeholderUrl/Uri
chris48s Aug 19, 2018
f12351a
provide an example API call for badges using static example
chris48s Aug 19, 2018
15edf9a
comment rot
chris48s Aug 19, 2018
6de6da0
update legacy example to use :param instead of PARAM
chris48s Aug 19, 2018
2688e18
coding standards
chris48s Aug 19, 2018
56a9e0e
placeholderUri --> urlPattern
chris48s Aug 22, 2018
f5a0d06
placeholderUrl --> urlPattern
chris48s Aug 22, 2018
ded9cf2
add real-looking fake tokens
chris48s Aug 22, 2018
a663b1b
move render logic in gem rank badge
chris48s Aug 22, 2018
29ae4b0
Merge branch 'master' into issue1700-a
chris48s Aug 22, 2018
b965a0f
fix conflict resolution error
chris48s Aug 22, 2018
3b2446e
make example more clickable
chris48s Aug 22, 2018
c33e494
pass tag:undefined implicitly instead of explicitly
chris48s Aug 23, 2018
bee965b
pass counts as int instead of str
chris48s Aug 23, 2018
1a5d94a
use existing function to build a label instead of hard-coding it
chris48s Aug 23, 2018
ad78f58
Merge branch 'master' into issue1700-a
chris48s Aug 23, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 15 additions & 5 deletions frontend/components/badge-examples.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,24 @@ import resolveBadgeUrl from '../lib/badge-url'

const Badge = ({
title,
previewUri,
exampleUri,
previewUri,
urlPattern,
documentation,
baseUri,
longCache,
shouldDisplay = () => true,
onClick,
}) => {
const handleClick = onClick
? () => onClick({ title, previewUri, exampleUri, documentation })
? () =>
onClick({
title,
exampleUri,
previewUri,
urlPattern,
documentation,
})
: undefined

const previewImage = previewUri ? (
Expand All @@ -29,7 +37,7 @@ const Badge = ({
'\u00a0'
) // non-breaking space
const resolvedExampleUri = resolveBadgeUrl(
exampleUri || previewUri,
urlPattern || previewUri,
baseUri,
{ longCache: false }
)
Expand Down Expand Up @@ -59,8 +67,9 @@ const Badge = ({
}
Badge.propTypes = {
title: PropTypes.string.isRequired,
previewUri: PropTypes.string,
exampleUri: PropTypes.string,
previewUri: PropTypes.string,
urlPattern: PropTypes.string,
documentation: PropTypes.string,
baseUri: PropTypes.string,
longCache: PropTypes.bool.isRequired,
Expand Down Expand Up @@ -101,8 +110,9 @@ Category.propTypes = {
examples: PropTypes.arrayOf(
PropTypes.shape({
title: PropTypes.string.isRequired,
previewUri: PropTypes.string,
exampleUri: PropTypes.string,
previewUri: PropTypes.string,
urlPattern: PropTypes.string,
documentation: PropTypes.string,
})
).isRequired,
Expand Down
23 changes: 20 additions & 3 deletions frontend/components/markup-modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ export default class MarkupModal extends React.Component {
static propTypes = {
example: PropTypes.shape({
title: PropTypes.string.isRequired,
previewUri: PropTypes.string,
exampleUri: PropTypes.string,
previewUri: PropTypes.string,
urlPattern: PropTypes.string,
documentation: PropTypes.string,
link: PropTypes.string,
}),
Expand All @@ -20,6 +21,7 @@ export default class MarkupModal extends React.Component {
}

state = {
exampleUri: null,
badgeUri: null,
link: null,
style: 'flat',
Expand All @@ -38,10 +40,13 @@ export default class MarkupModal extends React.Component {

// Transfer `badgeUri` and `link` into state so they can be edited by the
// user.
const { exampleUri, previewUri, link } = example
const { exampleUri, urlPattern, previewUri, link } = example
this.setState({
exampleUri: exampleUri
? resolveBadgeUrl(exampleUri, baseUri || window.location.href)
: null,
badgeUri: resolveBadgeUrl(
exampleUri || previewUri,
urlPattern || previewUri,
baseUri || window.location.href
),
link,
Expand Down Expand Up @@ -126,6 +131,18 @@ export default class MarkupModal extends React.Component {
/>
</label>
</p>
{this.state.exampleUri && (
<p>
Example&nbsp;
<ClickToSelect>
<input
className="code clickable"
readOnly
value={this.state.exampleUri}
/>
</ClickToSelect>
</p>
)}
<p>
<label>
Style&nbsp;
Expand Down
32 changes: 22 additions & 10 deletions lib/all-badge-examples.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,22 +120,26 @@ const allBadgeExamples = [
{
title: 'Travis (.org)',
previewUri: '/travis/rust-lang/rust.svg',
exampleUri: '/travis/USER/REPO.svg',
urlPattern: '/travis/:user/:repo.svg',
exampleUri: '/travis/rust-lang/rust.svg',
},
{
title: 'Travis (.org) branch',
previewUri: '/travis/rust-lang/rust/master.svg',
exampleUri: '/travis/USER/REPO/BRANCH.svg',
urlPattern: '/travis/:user/:repo/:branch.svg',
exampleUri: '/travis/rust-lang/rust/master.svg',
},
{
title: 'Travis (.com)',
previewUri: '/travis/com/ivandelabeldad/rackian-gateway.svg',
exampleUri: '/travis/com/USER/REPO.svg',
urlPattern: '/travis/com/:user/:repo.svg',
exampleUri: '/travis/com/ivandelabeldad/rackian-gateway.svg',
},
{
title: 'Travis (.com) branch',
previewUri: '/travis/com/ivandelabeldad/rackian-gateway/master.svg',
exampleUri: '/travis/com/USER/REPO/BRANCH.svg',
urlPattern: '/travis/com/:user/:repo/:branch.svg',
exampleUri: '/travis/com/ivandelabeldad/rackian-gateway/master.svg',
},
{
title: 'TeamCity CodeBetter',
Expand All @@ -148,7 +152,7 @@ const allBadgeExamples = [
{
title: 'TeamCity (full build status)',
keywords: ['teamcity'],
exampleUri: '/teamcity/http/teamcity.jetbrains.com/e/bt345.svg',
previewUri: '/teamcity/http/teamcity.jetbrains.com/e/bt345.svg',
},
{
title: 'Buildkite',
Expand Down Expand Up @@ -176,8 +180,10 @@ const allBadgeExamples = [
title: 'CircleCI token',
previewUri:
'/circleci/project/github/RedSparr0w/node-csgo-parser/master.svg',
urlPattern:
'/circleci/token/:token/project/github/RedSparr0w/node-csgo-parser/master.svg',
exampleUri:
'/circleci/token/YOURTOKEN/project/github/RedSparr0w/node-csgo-parser/master.svg',
'/circleci/token/b90b5c49e59a4c67ba3a92f7992587ac7a0408c2/project/github/RedSparr0w/node-csgo-parser/master.svg',
},
{
title: 'Visual Studio Team services',
Expand Down Expand Up @@ -281,8 +287,9 @@ const allBadgeExamples = [
{
title: 'Codecov private',
previewUri: '/codecov/c/github/codecov/example-python.svg',
urlPattern: '/codecov/c/token/:token/github/codecov/example-python.svg',
exampleUri:
'/codecov/c/token/YOURTOKEN/github/codecov/example-python.svg',
'/codecov/c/token/My0A8VL917/github/codecov/example-python.svg',
},
{
title: 'Coverity Scan',
Expand Down Expand Up @@ -312,8 +319,9 @@ const allBadgeExamples = [
title: 'Dockbit',
previewUri:
'/dockbit/DockbitStatus/health.svg?token=TvavttxFHJ4qhnKstDxrvBXM',
urlPattern: '/dockbit/:organisation/:pipeline.svg?token=:token',
exampleUri:
'/dockbit/ORGANIZATION_NAME/PIPELINE_NAME.svg?token=PIPELINE_TOKEN',
'/dockbit/DockbitStatus/health.svg?token=TvavttxFHJ4qhnKstDxrvBXM',
},
{
title: 'continuousphp',
Expand All @@ -333,7 +341,10 @@ const allBadgeExamples = [
title: 'Bitrise',
previewUri:
'/bitrise/cde737473028420d/master.svg?token=GCIdEzacE4GW32jLVrZb7A',
exampleUri: '/bitrise/APP-ID/BRANCH.svg?token=APP-STATUS-BADGE-TOKEN',
urlPattern:
'/bitrise/:app-id/:branch.svg?token=:app-status-badge-token',
exampleUri:
'/bitrise/cde737473028420d/master.svg?token=GCIdEzacE4GW32jLVrZb7A',
},
{
title: 'Code Climate',
Expand Down Expand Up @@ -1440,7 +1451,8 @@ const allBadgeExamples = [
{
title: 'iTunes App Store',
previewUri: '/itunes/v/803453959.svg',
exampleUri: '/itunes/v/BUNDLE_ID.svg',
urlPattern: '/itunes/v/:bundle-id.svg',
exampleUri: '/itunes/v/803453959.svg',
},
{
title: 'JitPack',
Expand Down
10 changes: 6 additions & 4 deletions lib/all-badge-examples.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,16 @@ describe('The badge examples', function() {
expect(appVeyorBuildExamples).to.deep.equal([
{
title: 'AppVeyor',
previewUri: '/appveyor/ci/gruntjs/grunt.svg',
exampleUri: undefined,
exampleUri: '/appveyor/ci/gruntjs/grunt.svg',
previewUri: '/badge/build-passing-brightgreen.svg',
urlPattern: '/appveyor/ci/:user/:repo.svg',
documentation: undefined,
},
{
title: 'AppVeyor branch',
previewUri: '/appveyor/ci/gruntjs/grunt/master.svg',
exampleUri: undefined,
exampleUri: '/appveyor/ci/gruntjs/grunt/master.svg',
previewUri: '/badge/build-passing-brightgreen.svg',
urlPattern: '/appveyor/ci/:user/:repo/:branch.svg',
documentation: undefined,
},
])
Expand Down
42 changes: 33 additions & 9 deletions services/apm/apm.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,6 @@ class BaseAPMService extends BaseJsonService {
static get defaultBadgeData() {
return { label: 'apm' }
}

static get examples() {
return [
{
previewUrl: 'vim-mode',
keywords: ['atom'],
},
]
}
}

class APMDownloads extends BaseAPMService {
Expand Down Expand Up @@ -65,6 +56,17 @@ class APMDownloads extends BaseAPMService {
capture: ['repo'],
}
}

static get examples() {
return [
{
exampleUrl: 'vim-mode',
urlPattern: ':package',
staticExample: this.render({ downloads: '60043' }),
keywords: ['atom'],
},
]
}
}

class APMVersion extends BaseAPMService {
Expand Down Expand Up @@ -94,6 +96,17 @@ class APMVersion extends BaseAPMService {
capture: ['repo'],
}
}

static get examples() {
return [
{
exampleUrl: 'vim-mode',
urlPattern: ':package',
staticExample: this.render({ version: '0.6.0' }),
keywords: ['atom'],
},
]
}
}

class APMLicense extends BaseAPMService {
Expand Down Expand Up @@ -127,6 +140,17 @@ class APMLicense extends BaseAPMService {
capture: ['repo'],
}
}

static get examples() {
return [
{
exampleUrl: 'vim-mode',
urlPattern: ':package',
staticExample: this.render({ license: 'MIT' }),
keywords: ['atom'],
},
]
}
}

module.exports = {
Expand Down
8 changes: 6 additions & 2 deletions services/appveyor/appveyor-ci.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,15 @@ module.exports = class AppVeyorCi extends AppVeyorBase {
return [
{
title: 'AppVeyor',
previewUrl: 'gruntjs/grunt',
exampleUrl: 'gruntjs/grunt',
urlPattern: ':user/:repo',
staticExample: this.render({ status: 'success' }),
},
{
title: 'AppVeyor branch',
previewUrl: 'gruntjs/grunt/master',
exampleUrl: 'gruntjs/grunt/master',
urlPattern: ':user/:repo/:branch',
staticExample: this.render({ status: 'success' }),
},
]
}
Expand Down
39 changes: 30 additions & 9 deletions services/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,30 +86,51 @@ class BaseService {
return '/' + [this.url.base, partialUrl].filter(Boolean).join('/')
}

static _makeStaticExampleUrl(serviceData) {
const badgeData = this._makeBadgeData({}, serviceData)
const color = badgeData.colorscheme || badgeData.colorB
return `/badge/${encodeURIComponent(
badgeData.text[0]
)}-${encodeURIComponent(badgeData.text[1])}-${color}`
}

/**
* Return an array of examples. Each example is prepared according to the
* schema in `lib/all-badge-examples.js`. Four keys are supported:
* - title
* - previewUrl
* - exampleUrl
* - documentation
* schema in `lib/all-badge-examples.js`.
*/
static prepareExamples() {
return this.examples.map(
({ title, previewUrl, query, exampleUrl, documentation }) => {
if (!previewUrl) {
throw Error(`Example for ${this.name} is missing required previewUrl`)
({
title,
query,
exampleUrl,
previewUrl,
urlPattern,
staticExample,
documentation,
}) => {
if (!previewUrl && !staticExample) {
throw Error(
`Example for ${
this.name
} is missing required previewUrl or staticExample`
Copy link
Member

Choose a reason for hiding this comment

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

Total aside: It would be helpful if instead of printing the classname, we printed the file where the class is defined. I wonder if we can do this by introspecting in the BaseService constructor.

Copy link
Member

Choose a reason for hiding this comment

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

I did something similar, to a different end, in #1934.

Copy link
Member Author

Choose a reason for hiding this comment

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

That's true, but I'm not sure we can use the same approach here. caller() returns null in this context

Copy link
Member

Choose a reason for hiding this comment

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

Yea, that makes sense.

I was thinking there would be a way to snag it when the class was defined, though there’s no code from the superclass that runs at that time. The filename could be identified and associated with the service class at the time the service module is loaded. It’d be kind of dirty but might still be worth doing. I’ll give it some thought.

)
}

const stringified = queryString.stringify(query)
const suffix = stringified ? `?${stringified}` : ''

return {
title: title ? `${title}` : this.name,
previewUri: `${this._makeFullUrl(previewUrl, query)}.svg${suffix}`,
exampleUri: exampleUrl
? `${this._makeFullUrl(exampleUrl, query)}.svg${suffix}`
: undefined,
previewUri: staticExample
? `${this._makeStaticExampleUrl(staticExample)}.svg`
: `${this._makeFullUrl(previewUrl, query)}.svg${suffix}`,
urlPattern: urlPattern
? `${this._makeFullUrl(urlPattern, query)}.svg${suffix}`
: undefined,
documentation,
}
}
Expand Down
Loading