fix: print all missing libraries when used on unsupported linux distro (#12966)
This patch:
- Adds 3 new host platform types:
* `generic-linux` and `generic-linux-arm64` for the unsupported
linux distributions
* `<unknown>` for non-supported OS versions
- Prints a warning when downloading Ubuntu browser builds on
unsupported Linux distribution
- Makes sure launch doctor prints all missing shared libraries
on unknown Linux distributions
- Also prints an `apt` command as an alternative to Playwright CLI
dependency installation.
This commit is contained in:
parent
4d41e51ee5
commit
bbc1a4fea0
|
|
@ -155,9 +155,9 @@ export async function validateDependenciesLinux(sdkLanguage: string, linuxLddDir
|
|||
const lddPaths: string[] = [];
|
||||
for (const directoryPath of directoryPaths)
|
||||
lddPaths.push(...(await executablesOrSharedLibraries(directoryPath)));
|
||||
const allMissingDeps = await Promise.all(lddPaths.map(lddPath => missingFileDependencies(lddPath, directoryPaths)));
|
||||
const missingDepsPerFile = await Promise.all(lddPaths.map(lddPath => missingFileDependencies(lddPath, directoryPaths)));
|
||||
const missingDeps: Set<string> = new Set();
|
||||
for (const deps of allMissingDeps) {
|
||||
for (const deps of missingDepsPerFile) {
|
||||
for (const dep of deps)
|
||||
missingDeps.add(dep);
|
||||
}
|
||||
|
|
@ -165,6 +165,7 @@ export async function validateDependenciesLinux(sdkLanguage: string, linuxLddDir
|
|||
missingDeps.add(dep);
|
||||
if (!missingDeps.size)
|
||||
return;
|
||||
const allMissingDeps = new Set(missingDeps);
|
||||
// Check Ubuntu version.
|
||||
const missingPackages = new Set();
|
||||
|
||||
|
|
@ -182,41 +183,33 @@ export async function validateDependenciesLinux(sdkLanguage: string, linuxLddDir
|
|||
}
|
||||
|
||||
const maybeSudo = (process.getuid() !== 0) && os.platform() !== 'win32' ? 'sudo ' : '';
|
||||
// Happy path: known dependencies are missing for browsers.
|
||||
// Suggest installation with a Playwright CLI.
|
||||
const errorLines = [
|
||||
`Host system is missing dependencies to run browsers.`,
|
||||
];
|
||||
if (missingPackages.size && !missingDeps.size) {
|
||||
throw new Error('\n' + utils.wrapInASCIIBox([
|
||||
`Host system is missing a few dependencies to run browsers.`,
|
||||
// Happy path: known dependencies are missing for browsers.
|
||||
// Suggest installation with a Playwright CLI.
|
||||
errorLines.push(...[
|
||||
`Please install them with the following command:`,
|
||||
``,
|
||||
` ${maybeSudo}${buildPlaywrightCLICommand(sdkLanguage, 'install-deps')}`,
|
||||
``,
|
||||
`Alternatively, use Aptitude:`,
|
||||
` ${maybeSudo}apt-get install ${[...missingPackages].join('\\\n ')}`,
|
||||
``,
|
||||
`<3 Playwright Team`,
|
||||
].join('\n'), 1));
|
||||
]);
|
||||
} else {
|
||||
// Unhappy path: we either run on unknown distribution, or we failed to resolve all missing
|
||||
// libraries to package names.
|
||||
// Print missing libraries only:
|
||||
errorLines.push(...[
|
||||
`Missing libraries:`,
|
||||
...[...allMissingDeps].map(dep => ' ' + dep),
|
||||
]);
|
||||
}
|
||||
|
||||
// Unhappy path - unusual distribution configuration.
|
||||
let missingPackagesMessage = '';
|
||||
if (missingPackages.size) {
|
||||
missingPackagesMessage = [
|
||||
` Install missing packages with:`,
|
||||
` ${maybeSudo}apt-get install ${[...missingPackages].join('\\\n ')}`,
|
||||
``,
|
||||
``,
|
||||
].join('\n');
|
||||
}
|
||||
|
||||
let missingDependenciesMessage = '';
|
||||
if (missingDeps.size) {
|
||||
const header = missingPackages.size ? `Missing libraries we didn't find packages for:` : `Missing libraries are:`;
|
||||
missingDependenciesMessage = [
|
||||
` ${header}`,
|
||||
` ${[...missingDeps].join('\n ')}`,
|
||||
``,
|
||||
].join('\n');
|
||||
}
|
||||
|
||||
throw new Error('Host system is missing dependencies!\n\n' + missingPackagesMessage + missingDependenciesMessage);
|
||||
throw new Error('\n' + utils.wrapInASCIIBox(errorLines.join('\n'), 1));
|
||||
}
|
||||
|
||||
function isSharedLib(basename: string) {
|
||||
|
|
|
|||
|
|
@ -53,6 +53,9 @@ const EXECUTABLE_PATHS = {
|
|||
|
||||
const DOWNLOAD_PATHS = {
|
||||
'chromium': {
|
||||
'<unknown>': undefined,
|
||||
'generic-linux': 'builds/chromium/%s/chromium-linux.zip',
|
||||
'generic-linux-arm64': 'builds/chromium/%s/chromium-linux-arm64.zip',
|
||||
'ubuntu18.04': 'builds/chromium/%s/chromium-linux.zip',
|
||||
'ubuntu20.04': 'builds/chromium/%s/chromium-linux.zip',
|
||||
'ubuntu18.04-arm64': 'builds/chromium/%s/chromium-linux-arm64.zip',
|
||||
|
|
@ -67,6 +70,9 @@ const DOWNLOAD_PATHS = {
|
|||
'win64': 'builds/chromium/%s/chromium-win64.zip',
|
||||
},
|
||||
'chromium-with-symbols': {
|
||||
'<unknown>': undefined,
|
||||
'generic-linux': 'builds/chromium/%s/chromium-with-symbols-linux.zip',
|
||||
'generic-linux-arm64': 'builds/chromium/%s/chromium-with-symbols-linux-arm64.zip',
|
||||
'ubuntu18.04': 'builds/chromium/%s/chromium-with-symbols-linux.zip',
|
||||
'ubuntu20.04': 'builds/chromium/%s/chromium-with-symbols-linux.zip',
|
||||
'ubuntu18.04-arm64': 'builds/chromium/%s/chromium-with-symbols-linux-arm64.zip',
|
||||
|
|
@ -81,6 +87,9 @@ const DOWNLOAD_PATHS = {
|
|||
'win64': 'builds/chromium/%s/chromium-with-symbols-win64.zip',
|
||||
},
|
||||
'firefox': {
|
||||
'<unknown>': undefined,
|
||||
'generic-linux': 'builds/firefox/%s/firefox-ubuntu-20.04.zip',
|
||||
'generic-linux-arm64': 'builds/firefox/%s/firefox-ubuntu-20.04-arm64.zip',
|
||||
'ubuntu18.04': 'builds/firefox/%s/firefox-ubuntu-18.04.zip',
|
||||
'ubuntu20.04': 'builds/firefox/%s/firefox-ubuntu-20.04.zip',
|
||||
'ubuntu18.04-arm64': undefined,
|
||||
|
|
@ -95,6 +104,9 @@ const DOWNLOAD_PATHS = {
|
|||
'win64': 'builds/firefox/%s/firefox-win64.zip',
|
||||
},
|
||||
'firefox-beta': {
|
||||
'<unknown>': undefined,
|
||||
'generic-linux': 'builds/firefox-beta/%s/firefox-beta-ubuntu-20.04.zip',
|
||||
'generic-linux-arm64': undefined,
|
||||
'ubuntu18.04': 'builds/firefox-beta/%s/firefox-beta-ubuntu-18.04.zip',
|
||||
'ubuntu20.04': 'builds/firefox-beta/%s/firefox-beta-ubuntu-20.04.zip',
|
||||
'ubuntu18.04-arm64': undefined,
|
||||
|
|
@ -109,6 +121,9 @@ const DOWNLOAD_PATHS = {
|
|||
'win64': 'builds/firefox-beta/%s/firefox-beta-win64.zip',
|
||||
},
|
||||
'webkit': {
|
||||
'<unknown>': undefined,
|
||||
'generic-linux': 'builds/webkit/%s/webkit-ubuntu-20.04.zip',
|
||||
'generic-linux-arm64': 'builds/webkit/%s/webkit-ubuntu-20.04-arm64.zip',
|
||||
'ubuntu18.04': 'builds/webkit/%s/webkit-ubuntu-18.04.zip',
|
||||
'ubuntu20.04': 'builds/webkit/%s/webkit-ubuntu-20.04.zip',
|
||||
'ubuntu18.04-arm64': undefined,
|
||||
|
|
@ -123,6 +138,9 @@ const DOWNLOAD_PATHS = {
|
|||
'win64': 'builds/webkit/%s/webkit-win64.zip',
|
||||
},
|
||||
'ffmpeg': {
|
||||
'<unknown>': undefined,
|
||||
'generic-linux': 'builds/ffmpeg/%s/ffmpeg-linux.zip',
|
||||
'generic-linux-arm64': 'builds/ffmpeg/%s/ffmpeg-linux-arm64.zip',
|
||||
'ubuntu18.04': 'builds/ffmpeg/%s/ffmpeg-linux.zip',
|
||||
'ubuntu20.04': 'builds/ffmpeg/%s/ffmpeg-linux.zip',
|
||||
'ubuntu18.04-arm64': 'builds/ffmpeg/%s/ffmpeg-linux-arm64.zip',
|
||||
|
|
@ -593,6 +611,8 @@ export class Registry {
|
|||
private async _downloadExecutable(descriptor: BrowsersJSONDescriptor, executablePath: string | undefined, downloadPathTemplate: string | undefined, downloadHostEnv: string) {
|
||||
if (!downloadPathTemplate || !executablePath)
|
||||
throw new Error(`ERROR: Playwright does not support ${descriptor.name} on ${hostPlatform}`);
|
||||
if (hostPlatform === 'generic-linux' || hostPlatform === 'generic-linux-arm64')
|
||||
logPolitely('BEWARE: your OS is not officially supported by Playwright; downloading Ubuntu build as a fallback.');
|
||||
const downloadHost =
|
||||
(downloadHostEnv && getFromENV(downloadHostEnv)) ||
|
||||
getFromENV('PLAYWRIGHT_DOWNLOAD_HOST') ||
|
||||
|
|
|
|||
|
|
@ -508,7 +508,9 @@ export type HostPlatform = 'win64' |
|
|||
'mac11' | 'mac11-arm64' |
|
||||
'mac12' | 'mac12-arm64' |
|
||||
'ubuntu18.04' | 'ubuntu18.04-arm64' |
|
||||
'ubuntu20.04' | 'ubuntu20.04-arm64';
|
||||
'ubuntu20.04' | 'ubuntu20.04-arm64' |
|
||||
'generic-linux' | 'generic-linux-arm64' |
|
||||
'<unknown>';
|
||||
|
||||
export const hostPlatform = ((): HostPlatform => {
|
||||
const platform = os.platform();
|
||||
|
|
@ -534,15 +536,17 @@ export const hostPlatform = ((): HostPlatform => {
|
|||
return macVersion as HostPlatform;
|
||||
}
|
||||
if (platform === 'linux') {
|
||||
const ubuntuVersion = getUbuntuVersionSync();
|
||||
const archSuffix = os.arch() === 'arm64' ? '-arm64' : '';
|
||||
const ubuntuVersion = getUbuntuVersionSync();
|
||||
if (!ubuntuVersion)
|
||||
return ('generic-linux' + archSuffix) as HostPlatform;
|
||||
if (parseInt(ubuntuVersion, 10) <= 19)
|
||||
return ('ubuntu18.04' + archSuffix) as HostPlatform;
|
||||
return ('ubuntu20.04' + archSuffix) as HostPlatform;
|
||||
}
|
||||
if (platform === 'win32')
|
||||
return 'win64';
|
||||
return platform as HostPlatform;
|
||||
return '<unknown>';
|
||||
})();
|
||||
|
||||
export function wrapInASCIIBox(text: string, padding = 0): string {
|
||||
|
|
|
|||
Loading…
Reference in a new issue