-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add community CITGM checks (#64)
Output a warning for packages either not included in the list of community CITGM runs or are in the list but skipped for an in support version of Node.js.
- Loading branch information
1 parent
ada7116
commit 7ceeced
Showing
3 changed files
with
245 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
const { createWarning } = require('../lib/result'); | ||
const { stringBuilder, success, warning } = require('../lib/format'); | ||
const { fetchGithub } = require('../lib/network'); | ||
const nv = require('@pkgjs/nv'); | ||
const semver = require('semver'); | ||
|
||
const CITGM_REPO = 'nodejs/citgm'; | ||
const LOOKUP_PATH = 'lib/lookup.json'; | ||
const BRANCH = 'HEAD'; | ||
|
||
const getCITGMLookup = async (token) => { | ||
const metadata = await fetchGithub( | ||
`/repos/${CITGM_REPO}/contents/${LOOKUP_PATH}?ref=${BRANCH}`, | ||
token | ||
); | ||
const content = Buffer.from(metadata.content, metadata.encoding); | ||
return JSON.parse(content); | ||
} | ||
|
||
const citgmPlugin = async (pkg, _, options) => { | ||
// Support plugin output | ||
const output = stringBuilder( | ||
'\nChecking if module is tested by community CITGM runs' | ||
).withPadding(66); | ||
|
||
const lookup = await getCITGMLookup(options.token); | ||
if (!lookup[pkg.name]) { | ||
warning(output.get()); | ||
return createWarning( | ||
`The module "${pkg.name}" is not tested by community CITGM runs.` | ||
); | ||
} | ||
const skip = lookup[pkg.name].skip; | ||
if (skip !== undefined) { | ||
if (skip === true || (Array.isArray(skip) && skip.includes(true))) { | ||
warning(output.get()); | ||
return createWarning( | ||
`The module "${pkg.name}" is not tested (skipped) by community CITGM runs.` | ||
); | ||
} | ||
const lts = (await nv('supported')).map(v => v.version); | ||
for (version of lts) { | ||
if ((!Array.isArray(skip) && semver.satisfies(version, skip)) || Array.isArray(skip) && skip.some(v => semver.satisfies(version, v))) { | ||
warning(output.get()); | ||
return createWarning( | ||
`The module "${pkg.name}" is not tested (skipped on ${version}) by community CITGM runs.` | ||
); | ||
} | ||
} | ||
} | ||
success(output.get()); | ||
return null; | ||
}; | ||
|
||
module.exports = citgmPlugin; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,187 @@ | ||
/* eslint-env jest */ | ||
|
||
const nv = require('@pkgjs/nv'); | ||
|
||
const network = require('../../src/lib/network'); | ||
const format = require('../../src/lib/format'); | ||
const citgmPlugin = require('../../src/plugins/citgm'); | ||
|
||
jest.mock('@pkgjs/nv'); | ||
jest.mock('../../src/lib/network'); | ||
jest.mock('../../src/lib/format', () => ({ | ||
...jest.requireActual('../../src/lib/format'), | ||
failure: jest.fn(), | ||
success: jest.fn(), | ||
warning: jest.fn() | ||
})); | ||
|
||
const CITGM_LOOKUP_URL = '/repos/nodejs/citgm/contents/lib/lookup.json?ref=HEAD'; | ||
|
||
const mockCITGMLookup = (content, encoding = 'utf8') => { | ||
network.fetchGithub.mockImplementation(() => { | ||
return Promise.resolve({ content, encoding }); | ||
}); | ||
} | ||
|
||
beforeEach(() => { | ||
nv.mockImplementation(() => { | ||
return Promise.resolve([{ version: '12.22.5' }, { version: '14.17.5' }, { version: '16.7.0' }]); | ||
}); | ||
}); | ||
|
||
afterEach(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
it('should succeed if package is tested by community CITGM', async () => { | ||
mockCITGMLookup('{ "mymodule": {} }'); | ||
|
||
const pkg = { | ||
name: 'mymodule' | ||
}; | ||
|
||
const result = await citgmPlugin(pkg, null, {}); | ||
expect(network.fetchGithub).toHaveBeenCalled(); | ||
expect(network.fetchGithub).toBeCalledWith(CITGM_LOOKUP_URL, undefined); | ||
expect(format.success).toHaveBeenCalled(); | ||
expect(result).toBeNull(); | ||
}); | ||
|
||
it('should warn if package is not tested by community CITGM', async () => { | ||
mockCITGMLookup('{}'); | ||
|
||
const pkg = { | ||
name: 'mymodule' | ||
}; | ||
|
||
const result = await citgmPlugin(pkg, null, {}); | ||
expect(network.fetchGithub).toHaveBeenCalled(); | ||
expect(network.fetchGithub).toBeCalledWith(CITGM_LOOKUP_URL, undefined); | ||
expect(format.warning).toHaveBeenCalled(); | ||
expect(result.type).toBe('warning'); | ||
}); | ||
|
||
it('should warn if package is skipped everywhere', async () => { | ||
mockCITGMLookup('{ "mymodule": { "skip": true } }'); | ||
|
||
const pkg = { | ||
name: 'mymodule' | ||
}; | ||
|
||
const result = await citgmPlugin(pkg, null, {}); | ||
expect(network.fetchGithub).toHaveBeenCalled(); | ||
expect(network.fetchGithub).toBeCalledWith(CITGM_LOOKUP_URL, undefined); | ||
expect(format.warning).toHaveBeenCalled(); | ||
expect(result.type).toBe('warning'); | ||
}); | ||
|
||
it('should warn if package is skipped everywhere (array version)', async () => { | ||
mockCITGMLookup('{ "mymodule": { "skip": [ true ] } }'); | ||
|
||
const pkg = { | ||
name: 'mymodule' | ||
}; | ||
|
||
const result = await citgmPlugin(pkg, null, {}); | ||
expect(network.fetchGithub).toHaveBeenCalled(); | ||
expect(network.fetchGithub).toBeCalledWith(CITGM_LOOKUP_URL, undefined); | ||
expect(format.warning).toHaveBeenCalled(); | ||
expect(result.type).toBe('warning'); | ||
}); | ||
|
||
it('should warn if package is skipped for in support versions', async () => { | ||
mockCITGMLookup('{ "mymodule": { "skip": ">10" } }'); | ||
|
||
const pkg = { | ||
name: 'mymodule' | ||
}; | ||
|
||
const result = await citgmPlugin(pkg, null, {}); | ||
expect(network.fetchGithub).toHaveBeenCalled(); | ||
expect(network.fetchGithub).toBeCalledWith(CITGM_LOOKUP_URL, undefined); | ||
expect(format.warning).toHaveBeenCalled(); | ||
expect(result.type).toBe('warning'); | ||
}); | ||
|
||
it('should warn if package is skipped for in support versions (array version)', async () => { | ||
mockCITGMLookup('{ "mymodule": { "skip": [ ">10" ] } }'); | ||
|
||
const pkg = { | ||
name: 'mymodule' | ||
}; | ||
|
||
const result = await citgmPlugin(pkg, null, {}); | ||
expect(network.fetchGithub).toHaveBeenCalled(); | ||
expect(network.fetchGithub).toBeCalledWith(CITGM_LOOKUP_URL, undefined); | ||
expect(format.warning).toHaveBeenCalled(); | ||
expect(result.type).toBe('warning'); | ||
}); | ||
|
||
it('should succeed if package if skips do not affect in support versions', async () => { | ||
mockCITGMLookup('{ "mymodule": { "skip": "<10" } }'); | ||
|
||
const pkg = { | ||
name: 'mymodule' | ||
}; | ||
|
||
const result = await citgmPlugin(pkg, null, {}); | ||
expect(network.fetchGithub).toHaveBeenCalled(); | ||
expect(network.fetchGithub).toBeCalledWith(CITGM_LOOKUP_URL, undefined); | ||
expect(format.success).toHaveBeenCalled(); | ||
expect(result).toBeNull(); | ||
}); | ||
|
||
it('should succeed if package if skips do not affect in support versions (array version)', async () => { | ||
mockCITGMLookup('{ "mymodule": { "skip": ["<10"] } }'); | ||
|
||
const pkg = { | ||
name: 'mymodule' | ||
}; | ||
|
||
const result = await citgmPlugin(pkg, null, {}); | ||
expect(network.fetchGithub).toHaveBeenCalled(); | ||
expect(network.fetchGithub).toBeCalledWith(CITGM_LOOKUP_URL, undefined); | ||
expect(format.success).toHaveBeenCalled(); | ||
expect(result).toBeNull(); | ||
}); | ||
|
||
it('should succeed if package if skips are only platform specific', async () => { | ||
mockCITGMLookup('{ "mymodule": { "skip": "aix" } }'); | ||
|
||
const pkg = { | ||
name: 'mymodule' | ||
}; | ||
|
||
const result = await citgmPlugin(pkg, null, {}); | ||
expect(network.fetchGithub).toHaveBeenCalled(); | ||
expect(network.fetchGithub).toBeCalledWith(CITGM_LOOKUP_URL, undefined); | ||
expect(format.success).toHaveBeenCalled(); | ||
expect(result).toBeNull(); | ||
}); | ||
|
||
it('should succeed if package if skips are only platform specific (array version)', async () => { | ||
mockCITGMLookup('{ "mymodule": { "skip": ["aix", "s390", "ppc" ] } }'); | ||
|
||
const pkg = { | ||
name: 'mymodule' | ||
}; | ||
|
||
const result = await citgmPlugin(pkg, null, {}); | ||
expect(network.fetchGithub).toHaveBeenCalled(); | ||
expect(network.fetchGithub).toBeCalledWith(CITGM_LOOKUP_URL, undefined); | ||
expect(format.success).toHaveBeenCalled(); | ||
expect(result).toBeNull(); | ||
}); | ||
|
||
it('should not perform partial matches', async () => { | ||
mockCITGMLookup('{ "mymodule2": {} }'); | ||
|
||
const pkg = { | ||
name: 'mymodule' | ||
}; | ||
|
||
const result = await citgmPlugin(pkg, null, {}); | ||
expect(network.fetchGithub).toHaveBeenCalled(); | ||
expect(network.fetchGithub).toBeCalledWith(CITGM_LOOKUP_URL, undefined); | ||
expect(format.warning).toHaveBeenCalled(); | ||
}); |