-
Notifications
You must be signed in to change notification settings - Fork 4
Support url based evaluation #1
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
base: main
Are you sure you want to change the base?
Changes from all commits
56065a7
4243670
86e1ec4
abc947d
ef09f23
1ae8fe3
c4a0a9d
662f8f7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,14 +1,14 @@ | ||
| { | ||
| "3.16.*": { | ||
| "versionRange": "3.16.*", | ||
| "start_date": "2020-03-04T00:00:00.000Z", | ||
| "maintenance_start_date": "2020-11-11T00:00:00.000Z", | ||
| "end_date": "2021-03-17T00:00:00.000Z" | ||
| }, | ||
| "3.20.*": { | ||
| "versionRange": ">=3.20.*", | ||
| "start_date": "2020-08-24T00:00:00.000Z", | ||
| "maintenance_start_date": "2021-05-03T00:00:00.000Z", | ||
| "end_date": "2021-09-06T00:00:00.000Z" | ||
| }, | ||
| "3.24.*": { | ||
| "versionRange": ">=3.24.*", | ||
| "start_date": "2021-02-25T00:00:00.000Z", | ||
| "maintenance_start_date": "2021-11-04T00:00:00.000Z", | ||
| "end_date": "2022-03-10T00:00:00.000Z" | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,32 +3,65 @@ | |
| const semverCoerce = require('semver/functions/coerce'); | ||
| const YarnLockfile = require('@yarnpkg/lockfile'); | ||
| const npa = require('npm-package-arg'); | ||
| const ini = require('ini'); | ||
| const fs = require('fs'); | ||
| const path = require('path'); | ||
| const debug = require('debug')('supported:project'); | ||
| const { setupProjectPath } = require('../read-from-url'); | ||
|
|
||
| const npmConfig = require('../npm/config'); | ||
|
|
||
| module.exports = async function setupProject(projectRoot) { | ||
| const config = await npmConfig(projectRoot); // kinda slow, TODO: re-implement as standalone lib | ||
| // const { policies } = options; | ||
| const pkgPath = `${projectRoot}/package.json`; | ||
| if (!fs.existsSync(pkgPath)) { | ||
| throw new Error(`${pkgPath} does not exist, are you sure this is a valid package?`); | ||
| } | ||
| if (!fs.statSync(pkgPath).isFile()) { | ||
| throw new Error(`${pkgPath} is not a file, are you sure this is a valid package?`); | ||
| module.exports = async function setupProject(projectRoot, flags = {}) { | ||
| let projectInfo = {}; | ||
| if (!fs.existsSync(projectRoot)) { | ||
| projectInfo = await setupProjectPath(projectRoot, { | ||
| token: flags.token, | ||
| hostUrl: flags.hostUrl, | ||
| }); | ||
| // if project root is a URL then use homedir as root | ||
| projectRoot = require('os').homedir(); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is surprising, I understanding reading the Is there a more resilient alternative?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We are not using lock file or package.json from the homedir even if it exists. those are all read from in-memory files passed. The only npmrc we read is from homedir to avoid possible settings in the current project. The hope is not to have any custom npmrc in homedir. |
||
| } | ||
| const file = fs.readFileSync(pkgPath, 'utf-8'); | ||
| let pkg; | ||
| try { | ||
| pkg = JSON.parse(file); | ||
| } catch (e) { | ||
| throw new Error(`${pkgPath} is not a valid JSON file, are you sure this is a valid package?`); | ||
|
|
||
| let config = await npmConfig(projectRoot); // kinda slow, TODO: re-implement as standalone lib | ||
| let pkg = {}; | ||
| let lockfileContent = ''; | ||
| if (projectInfo.packageJSON) { | ||
| pkg = projectInfo.packageJSON; | ||
| lockfileContent = projectInfo['yarn.lock']; | ||
| if (projectInfo['.npmrc']) { | ||
| try { | ||
| let localConfig = ini.parse(projectInfo['.npmrc']); | ||
| config = { | ||
| config, | ||
| ...localConfig, | ||
| }; | ||
| } catch (e) { | ||
| throw new Error( | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm always nervous about catching all errors, is there a way to detect the expected exception if there was a parse failure and provide a nicer error? (assuming the existing error isn't itself already nice)
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can append the actual error this error so that we are not hiding actual error.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In the new change, I have appended the actual error. |
||
| `Couldn't parse the npmrc file, are you sure project URL has a valid npmrc?\n ${e}`, | ||
| ); | ||
| } | ||
| } | ||
| } else { | ||
| const pkgPath = `${projectRoot}/package.json`; | ||
| if (!fs.existsSync(pkgPath)) { | ||
| throw new Error(`${pkgPath} does not exist, are you sure this is a valid package?`); | ||
| } | ||
| if (!fs.statSync(pkgPath).isFile()) { | ||
| throw new Error(`${pkgPath} is not a file, are you sure this is a valid package?`); | ||
| } | ||
| const file = fs.readFileSync(pkgPath, 'utf-8'); | ||
| try { | ||
| pkg = JSON.parse(file); | ||
| } catch (e) { | ||
| throw new Error(`${pkgPath} is not a valid JSON file, are you sure this is a valid package?`); | ||
| } | ||
| const lockfilePath = path.join(projectRoot, 'yarn.lock'); | ||
| lockfileContent = fs.readFileSync(lockfilePath, 'utf-8'); | ||
| } | ||
| // const { policies } = options; | ||
| const lockfilePath = path.join(projectRoot, 'yarn.lock'); | ||
| // TODO: npm support | ||
| const { object: lockfile } = YarnLockfile.parse(fs.readFileSync(lockfilePath, 'utf-8')); | ||
| const { object: lockfile } = YarnLockfile.parse(lockfileContent); | ||
|
|
||
| const dependenciesToCheck = []; | ||
| if (pkg.dependencies) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,85 @@ | ||
| 'use strict'; | ||
| const fetch = require('minipass-fetch'); | ||
| const debug = require('debug')('supported:read-from-url'); | ||
| const { default: PQueue } = require('p-queue'); | ||
| const allSettled = require('promise.allsettled'); | ||
| const os = require('os'); | ||
| const { getFetchUrl } = require('./util'); | ||
| const chalk = require('chalk'); | ||
|
|
||
| async function setupProjectPath(_url, options = {}) { | ||
| let url = getFetchUrl(_url, options); | ||
|
|
||
| const work = []; | ||
| const queue = new PQueue({ | ||
| concurrency: os.cpus().length, | ||
| }); | ||
| let result = Object.create(null); | ||
| let packageJSON; | ||
| // check if the code moved to main or still using master | ||
| // https://github.com/SparshithNR/doc-tester/blob/master/package.json | ||
| // https://github.com/stefanpenner/supported/blob/main/package.json | ||
| try { | ||
| packageJSON = await runFetch(url + 'package.json', true); | ||
| } catch (e) { | ||
| if (e.code === 404) { | ||
| url = url.replace('main', 'master'); | ||
| packageJSON = await runFetch(url + 'package.json', true); | ||
| } else { | ||
| throw e; | ||
| } | ||
| } | ||
| for (const fileName of ['yarn.lock', '.npmrc']) { | ||
| work.push( | ||
| queue.add(async () => { | ||
| const requestURL = url + fileName; | ||
| result[fileName] = await runFetch(requestURL); | ||
| }), | ||
| ); | ||
| } | ||
| await queue.onIdle(); | ||
| for (const settled of await allSettled(work)) { | ||
| if (settled.status === 'rejected') { | ||
| throw settled.reason; | ||
| } | ||
| } | ||
|
|
||
| debug(`packageJSON url: ${url.toString()}`); | ||
|
|
||
| return { | ||
| packageJSON, | ||
| ...result, | ||
| }; | ||
| } | ||
|
|
||
| async function runFetch(requestURL, isJson) { | ||
| let response; | ||
| try { | ||
| response = await fetch(requestURL); | ||
| } catch (e) { | ||
| let error = new Error(chalk`{red Couldn't reach server, please check the URL provided.} | ||
| ${e.message}`); | ||
| throw error; | ||
| } | ||
| if (response.status === 200) { | ||
| if (isJson) { | ||
| return response.json(); | ||
| } | ||
| return response.text(); | ||
| } else if (response.status === 404) { | ||
| if (!requestURL.includes('.npmrc')) { | ||
| const text = await response.buffer(); | ||
| const e = new Error(`[http.status=${response.status}] url:${requestURL} : error: ${text}`); | ||
| e.code = response.status; | ||
| throw e; | ||
| } else { | ||
| debug(`Fetch failed for .npmrc , ${await response.buffer()}`); | ||
| } | ||
| } else { | ||
| throw new Error(`[http.status=${response.status}] url:${requestURL}`); | ||
| } | ||
| } | ||
|
|
||
| module.exports = { | ||
| setupProjectPath, | ||
| }; |
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.
The
GITHUB_TOKENenvironment variable is a convention which we can piggy back on more detailsI have fine having
-tas a way to override, but if a user has$GITHUB_TOKENalready set It would be great if we could seamlessly use that.What do you think?
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 may also want to provide a link to documentation which helps people generate said token.
Uh oh!
There was an error while loading. Please reload this page.
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 have documentation links to create TOKEN is in the error messages. https://github.com/stefanpenner/supported/pull/1/files/a4dd4064e13150cba88efa07a1c6eb35d0c7a01b#diff-b335630551682c19a781afebcf4d07bf978fb1f8ac04c6bf87428ed5106870f5R13
I will add it in the readme as well.
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.
Sorry for the delayed response on this.
I checked to see if I can find
GITHUB_TOKENin my local. I couldn't find this. Do you have it in your local environment?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.
Added documentation in the readme file