Skip to content

Commit

Permalink
fix: node service has bad colors #4809
Browse files Browse the repository at this point in the history
  • Loading branch information
regevbr committed Mar 30, 2020
1 parent d35e941 commit 3f43e28
Show file tree
Hide file tree
Showing 9 changed files with 231 additions and 16 deletions.
19 changes: 10 additions & 9 deletions services/node/node.service.js → services/node/node-base.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
'use strict'

const NPMBase = require('../npm/npm-base')
const { versionColorForRange } = require('./node-version-color')

const keywords = ['npm']

module.exports = class NodeVersion extends NPMBase {
module.exports = class NodeVersionBase extends NPMBase {
static get category() {
return 'platform-support'
}

static get route() {
return this.buildRoute('node/v', { withTag: true })
return this.buildRoute(`node/${this.path}`, { withTag: true })
}

static get examples() {
const type = this.type
const prefix = `node-${type}`
return [
{
title: 'node',
title: `${prefix}`,
pattern: ':packageName',
namedParams: { packageName: 'passport' },
staticPreview: this.renderStaticPreview({
Expand All @@ -26,7 +27,7 @@ module.exports = class NodeVersion extends NPMBase {
keywords,
},
{
title: 'node (scoped)',
title: `${prefix} (scoped)`,
pattern: '@:scope/:packageName',
namedParams: { scope: 'stdlib', packageName: 'stdlib' },
staticPreview: this.renderStaticPreview({
Expand All @@ -35,7 +36,7 @@ module.exports = class NodeVersion extends NPMBase {
keywords,
},
{
title: 'node (tag)',
title: `${prefix} (tag)`,
pattern: ':packageName/:tag',
namedParams: { packageName: 'passport', tag: 'latest' },
staticPreview: this.renderStaticPreview({
Expand All @@ -45,7 +46,7 @@ module.exports = class NodeVersion extends NPMBase {
keywords,
},
{
title: 'node (scoped with tag)',
title: `${prefix} (scoped with tag)`,
pattern: '@:scope/:packageName/:tag',
namedParams: { scope: 'stdlib', packageName: 'stdlib', tag: 'latest' },
staticPreview: this.renderStaticPreview({
Expand All @@ -55,7 +56,7 @@ module.exports = class NodeVersion extends NPMBase {
keywords,
},
{
title: 'node (scoped with tag, custom registry)',
title: `${prefix} (scoped with tag, custom registry)`,
pattern: '@:scope/:packageName/:tag',
namedParams: { scope: 'stdlib', packageName: 'stdlib', tag: 'latest' },
queryParams: { registry_uri: 'https://registry.npmjs.com' },
Expand Down Expand Up @@ -98,7 +99,7 @@ module.exports = class NodeVersion extends NPMBase {
return {
label,
message: nodeVersionRange,
color: await versionColorForRange(nodeVersionRange),
color: await this.colorResolver(nodeVersionRange),
}
}
}
Expand Down
18 changes: 18 additions & 0 deletions services/node/node-current.service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
'use strict'

const NodeVersionBase = require('./node-base')
const { versionColorForRangeCurrent } = require('./node-version-color')

module.exports = class NodeCurrentVersion extends NodeVersionBase {
static get path() {
return 'v'
}

static get type() {
return 'current'
}

static get colorResolver() {
return versionColorForRangeCurrent
}
}
23 changes: 23 additions & 0 deletions services/node/node-current.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
'use strict'

const { test, given } = require('sazerac')
const NodeVersion = require('./node-current.service')

describe('renderStaticPreview', function() {
it('should have parity with render()', async function() {
const nodeVersionRange = '>= 6.0.0'

const expectedNoTag = await NodeVersion.renderStaticPreview({
nodeVersionRange,
})
const expectedLatestTag = await NodeVersion.renderStaticPreview({
nodeVersionRange,
tag: 'latest',
})

test(NodeVersion.renderStaticPreview, () => {
given({ nodeVersionRange }).expect(expectedNoTag)
given({ nodeVersionRange, tag: 'latest' }).expect(expectedLatestTag)
})
})
})
File renamed without changes.
18 changes: 18 additions & 0 deletions services/node/node-lts.service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
'use strict'

const NodeVersionBase = require('./node-base')
const { versionColorForRangeLts } = require('./node-version-color')

module.exports = class NodeLtsVersion extends NodeVersionBase {
static get path() {
return 'v-lts'
}

static get type() {
return 'lts'
}

static get colorResolver() {
return versionColorForRangeLts
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict'

const { test, given } = require('sazerac')
const NodeVersion = require('./node.service')
const NodeVersion = require('./node-lts.service')

describe('renderStaticPreview', function() {
it('should have parity with render()', async function() {
Expand Down
48 changes: 48 additions & 0 deletions services/node/node-lts.tester.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
'use strict'

const { expect } = require('chai')
const { Range } = require('semver')
const t = (module.exports = require('../tester').createServiceTester())

function expectSemverRange(message) {
expect(() => new Range(message)).not.to.throw()
}

t.create('gets the node version of passport')
.get('/passport.json')
.expectBadge({ label: 'node' })
.afterJSON(json => {
expectSemverRange(json.message)
})

t.create('gets the node version of @stdlib/stdlib')
.get('/@stdlib/stdlib.json')
.expectBadge({ label: 'node' })
.afterJSON(json => {
expectSemverRange(json.message)
})

t.create("gets the tagged release's node version version of ionic")
.get('/ionic/next.json')
.expectBadge({ label: 'node@next' })
.afterJSON(json => {
expectSemverRange(json.message)
})

t.create('gets the node version of passport from a custom registry')
.get('/passport.json?registry_uri=https://registry.npmjs.com')
.expectBadge({ label: 'node' })
.afterJSON(json => {
expectSemverRange(json.message)
})

t.create("gets the tagged release's node version of @cycle/core")
.get('/@cycle/core/canary.json')
.expectBadge({ label: 'node@canary' })
.afterJSON(json => {
expectSemverRange(json.message)
})

t.create('invalid package name')
.get('/frodo-is-not-a-package.json')
.expectBadge({ label: 'node', message: 'package not found' })
65 changes: 59 additions & 6 deletions services/node/node-version-color.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
'use strict'

const { promisify } = require('util')
const moment = require('moment')
const semver = require('semver')
const { regularUpdate } = require('../../core/legacy/regular-update')

function getLatestVersion() {
const dateFormat = 'YYYY-MM-DD'

function getVersion(version) {
let semver = ``
if (version) {
semver = `-${version}.x`
}
return promisify(regularUpdate)({
url: 'https://nodejs.org/dist/latest/SHASUMS256.txt',
url: `https://nodejs.org/dist/latest${semver}/SHASUMS256.txt`,
intervalMillis: 24 * 3600 * 1000,
json: false,
scraper: shasums => {
Expand All @@ -20,8 +27,52 @@ function getLatestVersion() {
})
}

async function versionColorForRange(range) {
const latestVersion = await getLatestVersion()
function ltsVersionsScraper(versions) {
const currentDate = moment().format(dateFormat)
return Object.keys(versions).filter(function(version) {
const data = versions[version]
return data.lts && data.lts < currentDate && data.end > currentDate
})
}

async function getCurrentVersion() {
return getVersion()
}

async function getLtsVersions() {
const versions = await promisify(regularUpdate)({
url:
'https://raw.githubusercontent.com/nodejs/Release/master/schedule.json',
intervalMillis: 24 * 3600 * 1000,
json: true,
scraper: ltsVersionsScraper,
})
return Promise.all(versions.map(getVersion))
}

async function versionColorForRangeLts(range) {
const ltsVersions = await getLtsVersions()
try {
const matchesAll = ltsVersions.reduce(function(satisfies, version) {
return satisfies && semver.satisfies(version, range)
}, true)
const greaterThanAll = ltsVersions.reduce(function(satisfies, version) {
return satisfies && semver.gtr(version, range)
}, true)
if (matchesAll) {
return 'brightgreen'
} else if (greaterThanAll) {
return 'yellow'
} else {
return 'orange'
}
} catch (e) {
return 'lightgray'
}
}

async function versionColorForRangeCurrent(range) {
const latestVersion = await getCurrentVersion()
try {
if (semver.satisfies(latestVersion, range)) {
return 'brightgreen'
Expand All @@ -36,6 +87,8 @@ async function versionColorForRange(range) {
}

module.exports = {
getLatestVersion,
versionColorForRange,
getCurrentVersion,
getStableVersions: getLtsVersions,
versionColorForRangeCurrent,
versionColorForRangeLts,
}
54 changes: 54 additions & 0 deletions services/node/node-version-color.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
'use strict'

const { expect } = require('chai')
const {
getStableVersions,
getCurrentVersion,
versionColorForRangeLts,
versionColorForRangeCurrent,
} = require('./node-version-color')

describe('node version color', function() {
describe(`stable`, function() {
it('should only return lts versions', async function() {
this.timeout(4000)
const versions = await getStableVersions()
versions.sort()
const major = parseInt(
versions[versions.length - 1].match(/(\d+)/)[0],
10
)
expect(major % 2).to.eql(0)
})
it('should print green on lts versions', async function() {
const versions = await getStableVersions()
const range = versions.reduce(
(range, version) => `${range} || ${version}`
)
const color = await versionColorForRangeLts(range)
expect(color).to.eql('brightgreen')
})
it('should print yellow on lts bigger than range', async function() {
const versions = await getStableVersions()
versions.sort()
const major = parseInt(versions[0].match(/(\d+)/)[0], 10) - 1
const range = `^${major}`
const color = await versionColorForRangeLts(range)
expect(color).to.eql('yellow')
})
})
describe(`latest`, function() {
it('should print green on latest version', async function() {
const version = await getCurrentVersion()
const color = await versionColorForRangeCurrent(version)
expect(color).to.eql('brightgreen')
})
it('should print yellow on latest bigger than range', async function() {
const version = await getCurrentVersion()
const major = parseInt(version.match(/(\d+)/)[0], 10) - 1
const range = `^${major}`
const color = await versionColorForRangeCurrent(range)
expect(color).to.eql('yellow')
})
})
})

0 comments on commit 3f43e28

Please sign in to comment.