mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
103 lines
3.4 KiB
JavaScript
103 lines
3.4 KiB
JavaScript
![]() |
#!/usr/bin/env node
|
||
|
|
||
|
const fs = require('fs');
|
||
|
const util = require('util');
|
||
|
const path = require('path');
|
||
|
const {spawn} = require('child_process');
|
||
|
const browserPaths = require('playwright/lib/install/browserPaths.js');
|
||
|
|
||
|
(async () => {
|
||
|
const allBrowsersPath = browserPaths.browsersPath();
|
||
|
const {stdout} = await runCommand('find', [allBrowsersPath, '-executable', '-type', 'f']);
|
||
|
// lddPaths - files we want to run LDD against.
|
||
|
const lddPaths = stdout.trim().split('\n').map(f => f.trim()).filter(filePath => !filePath.toLowerCase().endsWith('.sh'));
|
||
|
// List of all shared libraries missing.
|
||
|
const missingDeps = new Set();
|
||
|
// Multimap: reverse-mapping from shared library to requiring file.
|
||
|
const depsToLddPaths = new Map();
|
||
|
await Promise.all(lddPaths.map(async lddPath => {
|
||
|
const deps = await missingFileDependencies(lddPath);
|
||
|
for (const dep of deps) {
|
||
|
missingDeps.add(dep);
|
||
|
let depsToLdd = depsToLddPaths.get(dep);
|
||
|
if (!depsToLdd) {
|
||
|
depsToLdd = new Set();
|
||
|
depsToLddPaths.set(dep, depsToLdd);
|
||
|
}
|
||
|
depsToLdd.add(lddPath);
|
||
|
}
|
||
|
}));
|
||
|
console.log(`==== MISSING DEPENDENCIES: ${missingDeps.size} ====`);
|
||
|
console.log([...missingDeps].sort().join('\n'));
|
||
|
|
||
|
console.log('{');
|
||
|
for (const dep of missingDeps) {
|
||
|
const packages = await findPackages(dep);
|
||
|
if (packages.length === 0) {
|
||
|
console.log(` // UNRESOLVED: ${dep} `);
|
||
|
const depsToLdd = depsToLddPaths.get(dep);
|
||
|
for (const filePath of depsToLdd)
|
||
|
console.log(` // - required by ${filePath}`);
|
||
|
} else if (packages.length === 1) {
|
||
|
console.log(` "${dep}": "${packages[0]}",`);
|
||
|
} else {
|
||
|
console.log(` "${dep}": ${JSON.stringify(packages)},`);
|
||
|
}
|
||
|
}
|
||
|
console.log('}');
|
||
|
})();
|
||
|
|
||
|
async function findPackages(libraryName) {
|
||
|
const {stdout} = await runCommand('apt-file', ['search', libraryName]);
|
||
|
if (!stdout.trim())
|
||
|
return [];
|
||
|
const libs = stdout.trim().split('\n').map(line => line.split(':')[0]);
|
||
|
return [...new Set(libs)];
|
||
|
}
|
||
|
|
||
|
async function fileDependencies(filePath) {
|
||
|
const {stdout} = await lddAsync(filePath);
|
||
|
const deps = stdout.split('\n').map(line => {
|
||
|
line = line.trim();
|
||
|
const missing = line.includes('not found');
|
||
|
const name = line.split('=>')[0].trim();
|
||
|
return {name, missing};
|
||
|
});
|
||
|
return deps;
|
||
|
}
|
||
|
|
||
|
async function missingFileDependencies(filePath) {
|
||
|
const deps = await fileDependencies(filePath);
|
||
|
return deps.filter(dep => dep.missing).map(dep => dep.name);
|
||
|
}
|
||
|
|
||
|
async function lddAsync(filePath) {
|
||
|
let LD_LIBRARY_PATH = [];
|
||
|
// Some shared objects inside browser sub-folders link against libraries that
|
||
|
// ship with the browser. We consider these to be included, so we want to account
|
||
|
// for them in the LD_LIBRARY_PATH.
|
||
|
for (let dirname = path.dirname(filePath); dirname !== '/'; dirname = path.dirname(dirname))
|
||
|
LD_LIBRARY_PATH.push(dirname);
|
||
|
return await runCommand('ldd', [filePath], {
|
||
|
cwd: path.dirname(filePath),
|
||
|
env: {
|
||
|
...process.env,
|
||
|
LD_LIBRARY_PATH: LD_LIBRARY_PATH.join(':'),
|
||
|
},
|
||
|
});
|
||
|
}
|
||
|
|
||
|
function runCommand(command, args, options = {}) {
|
||
|
const childProcess = spawn(command, args, options);
|
||
|
|
||
|
return new Promise((resolve) => {
|
||
|
let stdout = '';
|
||
|
let stderr = '';
|
||
|
childProcess.stdout.on('data', data => stdout += data);
|
||
|
childProcess.stderr.on('data', data => stderr += data);
|
||
|
childProcess.on('close', (code) => {
|
||
|
resolve({stdout, stderr, code});
|
||
|
});
|
||
|
});
|
||
|
}
|