-
Notifications
You must be signed in to change notification settings - Fork 687
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
[feature]: Debugging Reporter #2910
Changes from 6 commits
ba9e55a
c0a6e56
abd3484
eb1a6cf
3663c4b
ed501b7
0a4bfa4
4072227
750d7b4
7c73482
cc77b05
e9a314d
c858cf5
65d300e
a44a00c
045811b
6a97577
f8559fb
789c124
7c7ae86
abec157
ae7a30a
535cfd6
4ddb8f1
4ea451c
a061195
d527baa
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 |
---|---|---|
@@ -0,0 +1,212 @@ | ||
const { existsSync } = require('fs'); | ||
const os = require('os'); | ||
const path = require('path'); | ||
const { spawnSync } = require('child_process'); | ||
const https = require('https'); | ||
const fetch = require('node-fetch'); | ||
const agent = new https.Agent({ | ||
rejectUnauthorized: false | ||
}); | ||
|
||
const fetchWithAgent = async url => { | ||
return await fetch(url, { agent }); | ||
}; | ||
|
||
const prettyLogger = require('../util/pretty-logger'); | ||
const { loadEnvironment } = require('../Utilities'); | ||
|
||
const { uniqBy } = require('lodash'); | ||
const { sampleBackends: defaultSampleBackends } = require('./create-project'); | ||
|
||
const removeDuplicateBackends = backendEnvironments => | ||
uniqBy(backendEnvironments, 'url'); | ||
|
||
const fetchSampleBackendUrls = async () => { | ||
try { | ||
const res = await fetch( | ||
'https://fvp0esmt8f.execute-api.us-east-1.amazonaws.com/default/getSampleBackends' | ||
); | ||
const { sampleBackends } = await res.json(); | ||
|
||
return removeDuplicateBackends([ | ||
...sampleBackends.environments, | ||
...defaultSampleBackends.environments | ||
]).map(({ url }) => url); | ||
} catch { | ||
return defaultSampleBackends.environments.map(({ url }) => url); | ||
} | ||
}; | ||
|
||
const cwd = process.cwd(); | ||
|
||
function inspectDependencies(package) { | ||
prettyLogger.info('Inspecting Dependencies'); | ||
|
||
// Inspect all '@magento/...' dependencies. | ||
const magentoDependencies = [ | ||
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. @sirugh while writing tests for this file, it hit me, we should be capturing all 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. Depends on what you really want to glean from this information. I think we have at least one adobe dependency so might as well throw that in :) 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 actually use two: @adobe/adobe-client-data-layer |
||
...Object.keys(package.dependencies), | ||
...Object.keys(package.devDependencies) | ||
].filter(dependency => dependency.startsWith('@magento/')); | ||
|
||
let dependencies; | ||
if (existsSync(path.resolve(cwd, 'yarn.lock'))) { | ||
// using yarn | ||
dependencies = getYarnDependencies(magentoDependencies); | ||
prettyLogger.log( | ||
`Found ${dependencies.size} @magento dependencies in yarn.lock` | ||
); | ||
} else if (existsSync(path.resolve(cwd, 'package-lock.json'))) { | ||
// using npm | ||
dependencies = getNpmDependencies(magentoDependencies); | ||
prettyLogger.log( | ||
`Found ${ | ||
dependencies.size | ||
} @magento dependencies in package-lock.json` | ||
); | ||
} else { | ||
throw new Error( | ||
'Dependencies have not been installed, please run `yarn install` or npm install` then generate the build report again.' | ||
); | ||
} | ||
|
||
function logMapElements(value, key) { | ||
prettyLogger.log(`${key} @ ${value}`); | ||
} | ||
|
||
dependencies.forEach(logMapElements); | ||
} | ||
|
||
function getYarnDependencies(dependencies) { | ||
const dependencyMap = new Map(); | ||
|
||
dependencies.map(packageName => { | ||
const whyBuffer = spawnSync('yarn', ['why', packageName]); | ||
const grepBuffer = spawnSync('grep', ['Found'], { | ||
input: whyBuffer.stdout | ||
}); | ||
|
||
// [ 'info \r=> Found "@magento/pwa-buildpack@7.0.0"', '' ] | ||
const outputArray = grepBuffer.stdout.toString().split('\n'); | ||
|
||
// [ '7.0.0' ] | ||
const parsedOutputArray = outputArray | ||
.filter(output => output.length > 0) | ||
.map(output => output.split('@')[2].replace('"', '')); | ||
|
||
dependencyMap.set(packageName, parsedOutputArray.toString()); | ||
}); | ||
|
||
return dependencyMap; | ||
} | ||
|
||
function getNpmDependencies(dependencies) { | ||
const dependencyMap = new Map(); | ||
|
||
dependencies.map(packageName => { | ||
const listbuffer = spawnSync('npm', ['list', packageName]); | ||
const grepBuffer = spawnSync('grep', ['└──'], { | ||
input: listbuffer.stdout | ||
}); | ||
|
||
// TODO: handle multiple versions installed when not dupe. ie "npm ls core-js" | ||
const [, , version] = grepBuffer.stdout | ||
.toString() | ||
.split('\n') // ["│ └── @magento/upward-js@5.0.0 deduped", "└── @magento/upward-js@5.0.0"] | ||
.filter(text => !text.includes('deduped'))[0] // ["└── @magento/upward-js@5.0.0"] | ||
.split('@'); // [ '└── ', 'magento/upward-js', '5.0.0' ] | ||
|
||
dependencyMap.set(packageName, version); | ||
}); | ||
|
||
return dependencyMap; | ||
} | ||
|
||
async function inspectBackend() { | ||
prettyLogger.info('Inspecting Magento Backend'); | ||
const [projectConfig, sampleBackends] = await Promise.all([ | ||
loadEnvironment( | ||
// Load .env from root | ||
path.resolve(cwd) | ||
), | ||
fetchSampleBackendUrls() | ||
]); | ||
|
||
if (projectConfig.error) { | ||
throw projectConfig.error; | ||
} | ||
|
||
const { | ||
env: { MAGENTO_BACKEND_URL } | ||
} = projectConfig; | ||
|
||
if (sampleBackends.includes(MAGENTO_BACKEND_URL)) { | ||
prettyLogger.log('Using sample backend: ', MAGENTO_BACKEND_URL); | ||
} else { | ||
prettyLogger.log('Not using sample backend.'); | ||
} | ||
|
||
// Upcheck | ||
try { | ||
await fetchWithAgent(MAGENTO_BACKEND_URL); | ||
prettyLogger.log('Backend is UP!'); | ||
} catch (e) { | ||
prettyLogger.log('Backend is DOWN!'); | ||
prettyLogger.error('Reason:', e); | ||
} | ||
|
||
// Backend Version | ||
try { | ||
const res = await fetchWithAgent( | ||
`${MAGENTO_BACKEND_URL}/magento_version` | ||
); | ||
prettyLogger.log('Magento Version:', await res.text()); | ||
} catch (e) { | ||
prettyLogger.warn( | ||
'Unable to determine Magento version - ensure that the Magento_Version route is enabled when generating this report.' | ||
); | ||
prettyLogger.error('Reason:', e); | ||
} | ||
} | ||
|
||
function inspectBuildEnv() { | ||
const osVersion = os.version(); | ||
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. 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. Oops, you're right! Our monorepo package.json requires at least 10, but if this doesn't work in 10 we need a fall back (upgrading to minimum 12 is definitely out of scope). |
||
const nodeVersion = process.version(); | ||
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. Are you sure of this API? I checked the node docs and realized 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. Another good catch. I wonder how I got this to work. Maybe I had it written when I ran it for the screenshot and forgot to push? 🤷 Thanks for fixing :) |
||
const versionBuffer = spawnSync('npm', ['-v']); | ||
const npmVersion = versionBuffer.stdout.toString(); | ||
|
||
prettyLogger.info('Inspecting System'); | ||
prettyLogger.log('OS:', osVersion); | ||
prettyLogger.log('Node Version:', nodeVersion); | ||
prettyLogger.log('NPM Version:', npmVersion); | ||
} | ||
/** | ||
* main | ||
*/ | ||
async function buildpackCli() { | ||
const package = require(path.resolve(cwd, 'package.json')); | ||
prettyLogger.info( | ||
`Generating build report for ${package.name}@${ | ||
package.version | ||
}. This may take a moment.` | ||
); | ||
prettyLogger.log('\n'); | ||
|
||
inspectDependencies(package); | ||
|
||
prettyLogger.log('\n'); | ||
|
||
await inspectBackend(); | ||
|
||
prettyLogger.log('\n'); | ||
|
||
inspectBuildEnv(); | ||
|
||
prettyLogger.log('\n'); | ||
} | ||
|
||
module.exports.command = 'generate-build-report'; | ||
|
||
module.exports.describe = | ||
'Generates a report of general build information that can be used when debugging an issue.'; | ||
|
||
module.exports.handler = buildpackCli; |
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.
❤️