diff --git a/net-im/signal-desktop/Makefile b/net-im/signal-desktop/Makefile index 38cddad38339..e005542d3d85 100644 --- a/net-im/signal-desktop/Makefile +++ b/net-im/signal-desktop/Makefile @@ -1,235 +1,235 @@ PORTNAME= signal-desktop DISTVERSIONPREFIX= v DISTVERSION= 6.7.0 CATEGORIES= net-im MASTER_SITES= LOCAL/mikael/signal-desktop/:npm \ LOCAL/mikael/signal-desktop/:sqlite \ https://nodejs.org/download/release/v${NODE_VERSION}/:node \ https://electronjs.org/headers/v${ELECTRON_GYP_VERSION}/:electron_gyp \ https://build-artifacts.signal.org/desktop/:sqlcipher -DISTFILES= signal-desktop-${DISTVERSION}-yarn-cache.tar.gz:prefetch \ +DISTFILES= signal-desktop-${DISTVERSION}-yarn-cache.tar.gz \ signal-desktop-6.4.1-npm-cache.tar.gz:npm \ node-v${NODE_VERSION}-headers.tar.gz:node \ node-v${ELECTRON_GYP_VERSION}-headers.tar.gz:electron_gyp \ ${SQLCIPHER}.tar.gz:sqlcipher MAINTAINER= mikael@FreeBSD.org COMMENT= Cross-platform centralized encrypted messaging service WWW= https://signal.org/ LICENSE= AGPLv3 LICENSE_FILE= ${WRKSRC}/LICENSE ONLY_FOR_ARCHS= aarch64 amd64 FETCH_DEPENDS= yarn-node16>0:www/yarn-node16 EXTRACT_DEPENDS=yarn-node16>0:www/yarn-node16 BUILD_DEPENDS= ${LOCALBASE}/lib/libringrtc.so:multimedia/ringrtc \ ${LOCALBASE}/lib/libsignal_node.so:net-im/libsignal-node \ ${LOCALBASE}/lib/libsignal_tokenizer.a:devel/signal-fts5-extension \ app-builder>0:devel/app-builder \ electron${ELECTRON_VER_MAJOR}:devel/electron${ELECTRON_VER_MAJOR} \ npm:www/npm-node16 \ ${LOCALBASE}/lib/libcrypto.a:security/openssl-devel \ vips>0:graphics/vips \ yarn:www/yarn-node16 LIB_DEPENDS= libasound.so:audio/alsa-lib \ libatk-bridge-2.0.so:accessibility/at-spi2-atk \ libatspi.so:accessibility/at-spi2-core \ libcups.so:print/cups \ libdbus-1.so:devel/dbus \ libdrm.so:graphics/libdrm \ libexpat.so:textproc/expat2 \ libFLAC.so:audio/flac \ libfontconfig.so:x11-fonts/fontconfig \ libharfbuzz.so:print/harfbuzz \ libnspr4.so:devel/nspr \ libnss3.so:security/nss \ libopenh264.so:multimedia/openh264 \ libopus.so:audio/opus \ libpci.so:devel/libpci \ libpng16.so:graphics/png \ libsnappy.so:archivers/snappy \ libwebp.so:graphics/webp \ libxkbcommon.so:x11/libxkbcommon \ libxshmfence.so:x11/libxshmfence USES= desktop-file-utils gettext-runtime gl gnome jpeg xorg USE_GITHUB= yes GH_ACCOUNT= signalapp GH_PROJECT= Signal-Desktop USE_GL= gbm gl USE_GNOME= atk cairo gdkpixbuf2 glib20 gtk30 libxml2 libxslt pango USE_XORG= x11 xcb xcomposite xdamage xext xfixes xi xrandr xrender xtst PACKAGE_ENV= SIGNAL_ENV=production MAKE_ENV+= ELECTRON_OVERRIDE_DIST_PATH=${LOCALBASE}/share/electron${ELECTRON_VER_MAJOR} \ HOME=${WRKDIR} \ PLAYWRIGHT_BROWSERS_PATH=${WRKDIR}/.cache \ PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=true \ PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS=true \ USE_SYSTEM_APP_BUILDER=true \ SOURCE_DATE_EPOCH=${_BUILD_DATE} # Don't download electron binary distribution on electron node_modules installation MAKE_ENV+= ELECTRON_SKIP_BINARY_DOWNLOAD=1 # Don't create __pycache__ directory when executing node-gyp # This is a workaround to avoid filesystem violations during poudriere build MAKE_ENV+= PYTHONDONTWRITEBYTECODE=1 MAKE_ENV+= ESBUILD_BINARY_PATH=${WRKDIR}/esbuild-freebsd-64/package/bin/esbuild _BUILD_DATE= $$(date +'%s') ELECTRON_VER_MAJOR= 22 # keep NODE_VERSION in sync with www/node16 DISTVERSION NODE_VERSION= 16.19.1 # bump ELECTRON_GYP_VERSION when ELECTRON_VER_MAJOR is changed ELECTRON_GYP_VERSION= 22.2.0 # ll work/.cache/yarn/v6 | egrep "@signalapp|esbuild-freebsd" NPM_SIGNAL_DIR= npm-@signalapp-libsignal-client-0.22.0-d57441612df46f90df68fc5d9ad45b857b9d2c44-integrity NPM_RINGRTC_DIR= npm-@signalapp-ringrtc-2.24.0-634160d24b2e13967a634e0f3236b2b4b5854091-integrity NPM_SQLITE3_DIR= npm-@signalapp-better-sqlite3-8.4.3-7ffa8d03d2a12543247936bfb7b9f74cdbc6fe9b-integrity NPM_ESBUILD_VERS= 0.17.2 SQLCIPHER= sqlcipher-4.5.3-fts--3.0.7--0.2.1-b633825cf7e0fdd39a6cdf128f2bd76552a88d325f2b9cd07bb87a457cefb986 ESBUILD_ARCH= ${ARCH:S/aarch64/arm64/:S/amd64/x64/} NODE_ARCH= ${ARCH:S/aarch64/arm64/:S/amd64/x64/} APP_OUT_DIR= linux-${ARCH:S/aarch64/arm64-/:S/amd64//}unpacked PLIST_SUB= NODE_ARCH=${NODE_ARCH} \ SHARP_ARCH=${ARCH:S/aarch64/arm64v8/:S/amd64/x64/} YARN_TIMESTAMP= 1661146515 pre-fetch: if [ ! -f ${DISTDIR}/signal-desktop-${DISTVERSION}-yarn-cache.tar.gz ]; \ then ${MKDIR} ${WRKDIR}; \ ${ECHO_CMD} 'yarn-offline-mirror "./yarn-offline-cache"' >> \ ${WRKDIR}/.yarnrc; \ ${CP} ${FILESDIR}/package.json ${FILESDIR}/yarn.lock ${WRKDIR}; \ cd ${WRKDIR} && ${SETENV} HOME=${WRKDIR} XDG_CACHE_HOME=${WRKDIR}/.cache \ yarn --frozen-lockfile --ignore-scripts; \ ${MTREE_CMD} -cbnSp yarn-offline-cache | ${MTREE_CMD} -C | ${SED} \ -e 's:time=[0-9.]*:time=${YARN_TIMESTAMP}.000000000:' \ -e 's:\([gu]id\)=[0-9]*:\1=0:g' \ -e 's:flags=.*:flags=none:' \ -e 's:^\.:./yarn-offline-cache:' > yarn-offline-cache.mtree; \ ${TAR} cJf ${DISTDIR}/signal-desktop-${DISTVERSION}-yarn-cache.tar.gz \ @yarn-offline-cache.mtree; \ ${RM} -r ${WRKDIR}; \ fi post-patch: ${REINPLACE_CMD} "s#%%EPOCH%%#${_BUILD_DATE}#" \ ${WRKSRC}/ts/scripts/get-expire-time.ts post-extract: ${MKDIR} ${WRKDIR}/.cache/node-gyp/${NODE_VERSION} \ ${WRKDIR}/.electron-gyp/${ELECTRON_GYP_VERSION} ${MV} ${WRKDIR}/node-v${NODE_VERSION}/include ${WRKDIR}/.cache/node-gyp/${NODE_VERSION} ${MV} ${WRKDIR}/node_headers/include ${WRKDIR}/.electron-gyp/${ELECTRON_GYP_VERSION} ${ECHO_CMD} '9' > ${WRKDIR}/.cache/node-gyp/${NODE_VERSION}/installVersion ${ECHO_CMD} '9' > ${WRKDIR}/.electron-gyp/${ELECTRON_GYP_VERSION}/installVersion # install yarn modules and fail silently ${CP} ${FILESDIR}/package.json ${WRKSRC}/ ${ECHO_CMD} 'yarn-offline-mirror "../yarn-offline-cache"' > ${WRKSRC}/.yarnrc cd ${WRKSRC} && \ ${SETENV} ${MAKE_ENV} yarn install --frozen-lockfile --ignore-optional --offline || ${TRUE} do-build: ${ECHO_CMD} 'yarn-offline-mirror "../yarn-cache"' > ${WRKSRC}/.yarnrc # electron-builder is stupid and tries to open ${LOCALBASE}/share/electron22/electron with WRITE priv # copy ${LOCALBASE}/share/electron22 in WRKDIR # it's needed for the do-install phase, it's here because of this issue # https://github.com/MikaelUrankar/signal-desktop/issues/6 (I don't know why it fails though) @${RM} -r ${WRKDIR}/electron${ELECTRON_VER_MAJOR} @${CP} -pR ${LOCALBASE}/share/electron${ELECTRON_VER_MAJOR} ${WRKDIR}/electron${ELECTRON_VER_MAJOR} ${CHMOD} -R a+w ${WRKDIR}/electron${ELECTRON_VER_MAJOR} # Install libsignal_node.so and libringrtc.so binaries in the yarn cache ${MKDIR} ${WRKDIR}/.cache/yarn/v6/${NPM_SIGNAL_DIR}/node_modules/@signalapp/libsignal-client/prebuilds/freebsd-${NODE_ARCH} \ ${WRKDIR}/.cache/yarn/v6/${NPM_RINGRTC_DIR}/node_modules/@signalapp/ringrtc/build/freebsd ${CP} ${LOCALBASE}/lib/libsignal_node.so \ ${WRKDIR}/.cache/yarn/v6/${NPM_SIGNAL_DIR}/node_modules/@signalapp/libsignal-client/prebuilds/freebsd-${NODE_ARCH}/node.napi.node ${CP} ${LOCALBASE}/lib/libringrtc.so \ ${WRKDIR}/.cache/yarn/v6/${NPM_RINGRTC_DIR}/node_modules/@signalapp/ringrtc/build/freebsd/libringrtc-${NODE_ARCH}.node ${MKDIR} ${WRKDIR}/.cache/yarn/v6/${NPM_SQLITE3_DIR}/node_modules/@signalapp/better-sqlite3/deps ${CP} ${DISTDIR}/${SQLCIPHER}.tar.gz \ ${WRKDIR}/.cache/yarn/v6/${NPM_SQLITE3_DIR}/node_modules/@signalapp/better-sqlite3/deps/sqlcipher.tar.gz ${CP} ${FILESDIR}/fetch-prebuild.js \ ${WRKDIR}/.cache/yarn/v6/${NPM_RINGRTC_DIR}/node_modules/@signalapp/ringrtc/scripts/fetch-prebuild.js ${CP} ${FILESDIR}/download.js \ ${WRKDIR}/.cache/yarn/v6/${NPM_SQLITE3_DIR}/node_modules/@signalapp/better-sqlite3/deps/download.js # patch-package can't patch sqlite3 on aarch64, patch the yarn cache instead cd ${WRKDIR}/.cache/yarn/v6 && ${PATCH} -s -N -i ${FILESDIR}/sqlite3.gyp.diff ${MKDIR} ${WRKDIR}/esbuild-freebsd-64 ${TAR} -xf ${WRKDIR}/yarn-offline-cache/@esbuild-freebsd-${ESBUILD_ARCH}-${NPM_ESBUILD_VERS}.tgz -C ${WRKDIR}/esbuild-freebsd-64 # # For online build # ${RM} ${WRKDIR}/.npmrc # cd ${WRKSRC} && \ # ${SETENV} ${MAKE_ENV} yarn install --frozen-lockfile --ignore-optional # cd ${WRKSRC} && \ # ${SETENV} ${MAKE_ENV} yarn generate # cd ${WRKSRC} && \ # ${SETENV} ${MAKE_ENV} yarn build:webpack # For offline build ${ECHO_CMD} offline=true > ${WRKDIR}/.npmrc cd ${WRKSRC} && \ ${SETENV} ${MAKE_ENV} yarn install --frozen-lockfile --ignore-optional --offline cd ${WRKSRC} && \ ${SETENV} ${MAKE_ENV} yarn --offline generate cd ${WRKSRC} && \ ${SETENV} ${MAKE_ENV} yarn --offline build:webpack do-install: # taken from https://github.com/tagattie/FreeBSD-Electron/blob/master/Mk/Uses/electron.mk#L387 # and editors/vscode cd ${WRKSRC} && \ ${SETENV} ${MAKE_ENV} ${PACKAGE_ENV} yarn run electron-builder \ --linux --dir --config.npmRebuild=false \ --config.electronVersion=${ELECTRON_VER_MAJOR} \ --config.electronDist=${WRKDIR}/electron${ELECTRON_VER_MAJOR} ${MKDIR} ${STAGEDIR}${DATADIR} cd ${BUILD_WRKSRC}/dist/${APP_OUT_DIR} && \ ${COPYTREE_SHARE} . ${STAGEDIR}${DATADIR} ${MKDIR} ${STAGEDIR}${PREFIX}/share/pixmaps ${INSTALL_DATA} ${WRKSRC}/images/signal-logo-desktop-linux.png \ ${STAGEDIR}${PREFIX}/share/pixmaps/signal-desktop.png ${INSTALL_DATA} ${FILESDIR}/${PORTNAME}.desktop \ ${STAGEDIR}${PREFIX}/share/applications .for f in chromedriver mksnapshot v8_context_snapshot_generator ${RM} ${STAGEDIR}${DATADIR}/${f} .endfor ${RM} -r ${STAGEDIR}${DATADIR}/gen ${RM} -r ${STAGEDIR}${DATADIR}/node_headers ${RM} -r ${STAGEDIR}${DATADIR}/resources/completions ${RLN} ${STAGEDIR}${DATADIR}/signal-desktop ${STAGEDIR}${PREFIX}/bin create-caches-tarball: # do some cleanup first ${RM} -r ${WRKDIR}/.npm/_logs ${WRKDIR}/.npm/_update-notifier-last-checked ${WRKDIR}/.cache/yarn/v6/.tmp ${FIND} ${WRKDIR}/.cache -type f -perm 755 -exec file {} \; | ${EGREP} "ELF|PE32+|Mach-O" | ${AWK} -F ':' '{print $$1}' | ${XARGS} ${RM} cd ${WRKDIR} && \ ${TAR} czf signal-desktop-${DISTVERSION}-yarn-cache.tar.gz .cache yarn-cache cd ${WRKDIR} && \ ${TAR} czf signal-desktop-${DISTVERSION}-electron-gyp-cache.tar.gz .electron-gyp cd ${WRKDIR} && \ ${TAR} czf signal-desktop-${DISTVERSION}-npm-cache.tar.gz .npm .include diff --git a/net-im/signal-desktop/files/playwrigth-registry.js b/net-im/signal-desktop/files/playwrigth-registry.js deleted file mode 100644 index 6ad12151f76b..000000000000 --- a/net-im/signal-desktop/files/playwrigth-registry.js +++ /dev/null @@ -1,753 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.buildPlaywrightCLICommand = buildPlaywrightCLICommand; -exports.installDefaultBrowsersForNpmInstall = installDefaultBrowsersForNpmInstall; -exports.installBrowsersForNpmInstall = installBrowsersForNpmInstall; -exports.findChromiumChannel = findChromiumChannel; -exports.registry = exports.Registry = exports.registryDirectory = void 0; - -var os = _interopRequireWildcard(require("os")); - -var _path = _interopRequireDefault(require("path")); - -var util = _interopRequireWildcard(require("util")); - -var fs = _interopRequireWildcard(require("fs")); - -var _properLockfile = _interopRequireDefault(require("proper-lockfile")); - -var _ubuntuVersion = require("./ubuntuVersion"); - -var _utils = require("./utils"); - -var _dependencies = require("./dependencies"); - -var _browserFetcher = require("./browserFetcher"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } - -function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -/** - * Copyright 2017 Google Inc. All rights reserved. - * Modifications copyright (c) Microsoft Corporation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -const PACKAGE_PATH = _path.default.join(__dirname, '..', '..'); - -const BIN_PATH = _path.default.join(__dirname, '..', '..', 'bin'); - -const EXECUTABLE_PATHS = { - 'chromium': { - 'freebsd': ['chrome', 'chrome'], - 'ubuntu18.04': ['chrome-linux', 'chrome'], - 'ubuntu20.04': ['chrome-linux', 'chrome'], - 'ubuntu18.04-arm64': ['chrome-linux', 'chrome'], - 'ubuntu20.04-arm64': ['chrome-linux', 'chrome'], - 'mac10.13': ['chrome-mac', 'Chromium.app', 'Contents', 'MacOS', 'Chromium'], - 'mac10.14': ['chrome-mac', 'Chromium.app', 'Contents', 'MacOS', 'Chromium'], - 'mac10.15': ['chrome-mac', 'Chromium.app', 'Contents', 'MacOS', 'Chromium'], - 'mac11': ['chrome-mac', 'Chromium.app', 'Contents', 'MacOS', 'Chromium'], - 'mac11-arm64': ['chrome-mac', 'Chromium.app', 'Contents', 'MacOS', 'Chromium'], - 'win64': ['chrome-win', 'chrome.exe'] - }, - 'firefox': { - 'freebsd': ['firefox', 'firefox'], - 'ubuntu18.04': ['firefox', 'firefox'], - 'ubuntu20.04': ['firefox', 'firefox'], - 'ubuntu18.04-arm64': undefined, - 'ubuntu20.04-arm64': ['firefox', 'firefox'], - 'mac10.13': ['firefox', 'Nightly.app', 'Contents', 'MacOS', 'firefox'], - 'mac10.14': ['firefox', 'Nightly.app', 'Contents', 'MacOS', 'firefox'], - 'mac10.15': ['firefox', 'Nightly.app', 'Contents', 'MacOS', 'firefox'], - 'mac11': ['firefox', 'Nightly.app', 'Contents', 'MacOS', 'firefox'], - 'mac11-arm64': ['firefox', 'Nightly.app', 'Contents', 'MacOS', 'firefox'], - 'win64': ['firefox', 'firefox.exe'] - }, - 'webkit': { - 'ubuntu18.04': ['pw_run.sh'], - 'ubuntu20.04': ['pw_run.sh'], - 'ubuntu18.04-arm64': undefined, - 'ubuntu20.04-arm64': ['pw_run.sh'], - 'mac10.13': undefined, - 'mac10.14': ['pw_run.sh'], - 'mac10.15': ['pw_run.sh'], - 'mac11': ['pw_run.sh'], - 'mac11-arm64': ['pw_run.sh'], - 'win64': ['Playwright.exe'] - }, - 'ffmpeg': { - 'ubuntu18.04': ['ffmpeg-linux'], - 'ubuntu20.04': ['ffmpeg-linux'], - 'ubuntu18.04-arm64': ['ffmpeg-linux-arm64'], - 'ubuntu20.04-arm64': ['ffmpeg-linux-arm64'], - 'mac10.13': ['ffmpeg-mac'], - 'mac10.14': ['ffmpeg-mac'], - 'mac10.15': ['ffmpeg-mac'], - 'mac11': ['ffmpeg-mac'], - 'mac11-arm64': ['ffmpeg-mac'], - 'win64': ['ffmpeg-win64.exe'] - } -}; -const DOWNLOAD_URLS = { - 'chromium': { - 'freebsd': '%s/builds/chromium/%s/chromium-linux.zip', - 'ubuntu18.04': '%s/builds/chromium/%s/chromium-linux.zip', - 'ubuntu20.04': '%s/builds/chromium/%s/chromium-linux.zip', - 'ubuntu18.04-arm64': '%s/builds/chromium/%s/chromium-linux-arm64.zip', - 'ubuntu20.04-arm64': '%s/builds/chromium/%s/chromium-linux-arm64.zip', - 'mac10.13': '%s/builds/chromium/%s/chromium-mac.zip', - 'mac10.14': '%s/builds/chromium/%s/chromium-mac.zip', - 'mac10.15': '%s/builds/chromium/%s/chromium-mac.zip', - 'mac11': '%s/builds/chromium/%s/chromium-mac.zip', - 'mac11-arm64': '%s/builds/chromium/%s/chromium-mac-arm64.zip', - 'win64': '%s/builds/chromium/%s/chromium-win64.zip' - }, - 'chromium-with-symbols': { - 'ubuntu18.04': '%s/builds/chromium/%s/chromium-with-symbols-linux.zip', - 'ubuntu20.04': '%s/builds/chromium/%s/chromium-with-symbols-linux.zip', - 'ubuntu18.04-arm64': '%s/builds/chromium/%s/chromium-with-symbols-linux-arm64.zip', - 'ubuntu20.04-arm64': '%s/builds/chromium/%s/chromium-with-symbols-linux-arm64.zip', - 'mac10.13': '%s/builds/chromium/%s/chromium-with-symbols-mac.zip', - 'mac10.14': '%s/builds/chromium/%s/chromium-with-symbols-mac.zip', - 'mac10.15': '%s/builds/chromium/%s/chromium-with-symbols-mac.zip', - 'mac11': '%s/builds/chromium/%s/chromium-with-symbols-mac.zip', - 'mac11-arm64': '%s/builds/chromium/%s/chromium-with-symbols-mac-arm64.zip', - 'win64': '%s/builds/chromium/%s/chromium-with-symbols-win64.zip' - }, - 'firefox': { - 'freebsd': '%s/builds/firefox/%s/firefox-ubuntu-18.04.zip', - 'ubuntu18.04': '%s/builds/firefox/%s/firefox-ubuntu-18.04.zip', - 'ubuntu20.04': '%s/builds/firefox/%s/firefox-ubuntu-20.04.zip', - 'ubuntu18.04-arm64': undefined, - 'ubuntu20.04-arm64': '%s/builds/firefox/%s/firefox-ubuntu-20.04-arm64.zip', - 'mac10.13': '%s/builds/firefox/%s/firefox-mac-11.zip', - 'mac10.14': '%s/builds/firefox/%s/firefox-mac-11.zip', - 'mac10.15': '%s/builds/firefox/%s/firefox-mac-11.zip', - 'mac11': '%s/builds/firefox/%s/firefox-mac-11.zip', - 'mac11-arm64': '%s/builds/firefox/%s/firefox-mac-11-arm64.zip', - 'win64': '%s/builds/firefox/%s/firefox-win64.zip' - }, - 'firefox-beta': { - 'ubuntu18.04': '%s/builds/firefox-beta/%s/firefox-beta-ubuntu-18.04.zip', - 'ubuntu20.04': '%s/builds/firefox-beta/%s/firefox-beta-ubuntu-20.04.zip', - 'ubuntu18.04-arm64': undefined, - 'ubuntu20.04-arm64': undefined, - 'mac10.13': '%s/builds/firefox-beta/%s/firefox-beta-mac-11.zip', - 'mac10.14': '%s/builds/firefox-beta/%s/firefox-beta-mac-11.zip', - 'mac10.15': '%s/builds/firefox-beta/%s/firefox-beta-mac-11.zip', - 'mac11': '%s/builds/firefox-beta/%s/firefox-beta-mac-11.zip', - 'mac11-arm64': '%s/builds/firefox-beta/%s/firefox-beta-mac-11-arm64.zip', - 'win64': '%s/builds/firefox-beta/%s/firefox-beta-win64.zip' - }, - 'webkit': { - 'ubuntu18.04': '%s/builds/webkit/%s/webkit-ubuntu-18.04.zip', - 'ubuntu20.04': '%s/builds/webkit/%s/webkit-ubuntu-20.04.zip', - 'ubuntu18.04-arm64': undefined, - 'ubuntu20.04-arm64': '%s/builds/webkit/%s/webkit-ubuntu-20.04-arm64.zip', - 'mac10.13': undefined, - 'mac10.14': '%s/builds/deprecated-webkit-mac-10.14/%s/deprecated-webkit-mac-10.14.zip', - 'mac10.15': '%s/builds/webkit/%s/webkit-mac-10.15.zip', - 'mac11': '%s/builds/webkit/%s/webkit-mac-10.15.zip', - 'mac11-arm64': '%s/builds/webkit/%s/webkit-mac-11-arm64.zip', - 'win64': '%s/builds/webkit/%s/webkit-win64.zip' - }, - 'ffmpeg': { - 'ubuntu18.04': '%s/builds/ffmpeg/%s/ffmpeg-linux.zip', - 'ubuntu20.04': '%s/builds/ffmpeg/%s/ffmpeg-linux.zip', - 'ubuntu18.04-arm64': '%s/builds/ffmpeg/%s/ffmpeg-linux-arm64.zip', - 'ubuntu20.04-arm64': '%s/builds/ffmpeg/%s/ffmpeg-linux-arm64.zip', - 'mac10.13': '%s/builds/ffmpeg/%s/ffmpeg-mac.zip', - 'mac10.14': '%s/builds/ffmpeg/%s/ffmpeg-mac.zip', - 'mac10.15': '%s/builds/ffmpeg/%s/ffmpeg-mac.zip', - 'mac11': '%s/builds/ffmpeg/%s/ffmpeg-mac.zip', - 'mac11-arm64': '%s/builds/ffmpeg/%s/ffmpeg-mac.zip', - 'win64': '%s/builds/ffmpeg/%s/ffmpeg-win64.zip' - } -}; - -const registryDirectory = (() => { - let result; - const envDefined = (0, _utils.getFromENV)('PLAYWRIGHT_BROWSERS_PATH'); - - if (envDefined === '0') { - result = _path.default.join(__dirname, '..', '..', '.local-browsers'); - } else if (envDefined) { - result = envDefined; - } else { - let cacheDirectory; - if (process.platform === 'linux') cacheDirectory = process.env.XDG_CACHE_HOME || _path.default.join(os.homedir(), '.cache');else if (process.platform === 'darwin') cacheDirectory = _path.default.join(os.homedir(), 'Library', 'Caches');else if (process.platform === 'win32') cacheDirectory = process.env.LOCALAPPDATA || _path.default.join(os.homedir(), 'AppData', 'Local');else throw new Error('Unsupported platform: ' + process.platform); - result = _path.default.join(cacheDirectory, 'ms-playwright'); - } - - if (!_path.default.isAbsolute(result)) { - // It is important to resolve to the absolute path: - // - for unzipping to work correctly; - // - so that registry directory matches between installation and execution. - // INIT_CWD points to the root of `npm/yarn install` and is probably what - // the user meant when typing the relative path. - result = _path.default.resolve((0, _utils.getFromENV)('INIT_CWD') || process.cwd(), result); - } - - return result; -})(); - -exports.registryDirectory = registryDirectory; - -function isBrowserDirectory(browserDirectory) { - const baseName = _path.default.basename(browserDirectory); - - for (const browserName of allDownloadable) { - if (baseName.startsWith(browserName + '-')) return true; - } - - return false; -} - -function readDescriptors(browsersJSON) { - return browsersJSON['browsers'].map(obj => { - const name = obj.name; - const revisionOverride = (obj.revisionOverrides || {})[_utils.hostPlatform]; - const revision = revisionOverride || obj.revision; - const browserDirectoryPrefix = revisionOverride ? `${name}_${_utils.hostPlatform}_special` : `${name}`; - const descriptor = { - name, - revision, - installByDefault: !!obj.installByDefault, - // Method `isBrowserDirectory` determines directory to be browser iff - // it starts with some browser name followed by '-'. Some browser names - // are prefixes of others, e.g. 'webkit' is a prefix of `webkit-technology-preview`. - // To avoid older registries erroneously removing 'webkit-technology-preview', we have to - // ensure that browser folders to never include dashes inside. - dir: _path.default.join(registryDirectory, browserDirectoryPrefix.replace(/-/g, '_') + '-' + revision) - }; - return descriptor; - }); -} - -const allDownloadable = ['chromium', 'firefox', 'webkit', 'ffmpeg', 'firefox-beta', 'chromium-with-symbols']; - -class Registry { - constructor(browsersJSON) { - this._executables = void 0; - const descriptors = readDescriptors(browsersJSON); - - const findExecutablePath = (dir, name) => { - const tokens = EXECUTABLE_PATHS[name][_utils.hostPlatform]; - return tokens ? _path.default.join(dir, ...tokens) : undefined; - }; - - const executablePathOrDie = (name, e, installByDefault, sdkLanguage) => { - if (!e) throw new Error(`${name} is not supported on ${_utils.hostPlatform}`); - const installCommand = buildPlaywrightCLICommand(sdkLanguage, `install${installByDefault ? '' : ' ' + name}`); - - if (!(0, _utils.canAccessFile)(e)) { - const prettyMessage = [`Looks like Playwright Test or Playwright was just installed or updated.`, `Please run the following command to download new browser${installByDefault ? 's' : ''}:`, ``, ` ${installCommand}`, ``, `<3 Playwright Team`].join('\n'); - throw new Error(`Executable doesn't exist at ${e}\n${(0, _utils.wrapInASCIIBox)(prettyMessage, 1)}`); - } - - return e; - }; - - this._executables = []; - const chromium = descriptors.find(d => d.name === 'chromium'); - const chromiumExecutable = findExecutablePath(chromium.dir, 'chromium'); - - this._executables.push({ - type: 'browser', - name: 'chromium', - browserName: 'chromium', - directory: chromium.dir, - executablePath: () => chromiumExecutable, - executablePathOrDie: sdkLanguage => executablePathOrDie('chromium', chromiumExecutable, chromium.installByDefault, sdkLanguage), - installType: chromium.installByDefault ? 'download-by-default' : 'download-on-demand', - validateHostRequirements: sdkLanguage => this._validateHostRequirements(sdkLanguage, 'chromium', chromium.dir, ['chrome-linux'], [], ['chrome-win']), - _install: () => this._downloadExecutable(chromium, chromiumExecutable, DOWNLOAD_URLS['chromium'][_utils.hostPlatform], 'PLAYWRIGHT_CHROMIUM_DOWNLOAD_HOST'), - _dependencyGroup: 'chromium' - }); - - const chromiumWithSymbols = descriptors.find(d => d.name === 'chromium-with-symbols'); - const chromiumWithSymbolsExecutable = findExecutablePath(chromiumWithSymbols.dir, 'chromium'); - - this._executables.push({ - type: 'tool', - name: 'chromium-with-symbols', - browserName: 'chromium', - directory: chromiumWithSymbols.dir, - executablePath: () => chromiumWithSymbolsExecutable, - executablePathOrDie: sdkLanguage => executablePathOrDie('chromium-with-symbols', chromiumWithSymbolsExecutable, chromiumWithSymbols.installByDefault, sdkLanguage), - installType: chromiumWithSymbols.installByDefault ? 'download-by-default' : 'download-on-demand', - validateHostRequirements: sdkLanguage => this._validateHostRequirements(sdkLanguage, 'chromium', chromiumWithSymbols.dir, ['chrome-linux'], [], ['chrome-win']), - _install: () => this._downloadExecutable(chromiumWithSymbols, chromiumWithSymbolsExecutable, DOWNLOAD_URLS['chromium-with-symbols'][_utils.hostPlatform], 'PLAYWRIGHT_CHROMIUM_DOWNLOAD_HOST'), - _dependencyGroup: 'chromium' - }); - - this._executables.push(this._createChromiumChannel('chrome', { - 'linux': '/opt/google/chrome/chrome', - 'darwin': '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome', - 'win32': `\\Google\\Chrome\\Application\\chrome.exe` - }, () => this._installChromiumChannel('chrome', { - 'linux': 'reinstall_chrome_stable_linux.sh', - 'darwin': 'reinstall_chrome_stable_mac.sh', - 'win32': 'reinstall_chrome_stable_win.ps1' - }))); - - this._executables.push(this._createChromiumChannel('chrome-beta', { - 'linux': '/opt/google/chrome-beta/chrome', - 'darwin': '/Applications/Google Chrome Beta.app/Contents/MacOS/Google Chrome Beta', - 'win32': `\\Google\\Chrome Beta\\Application\\chrome.exe` - }, () => this._installChromiumChannel('chrome-beta', { - 'linux': 'reinstall_chrome_beta_linux.sh', - 'darwin': 'reinstall_chrome_beta_mac.sh', - 'win32': 'reinstall_chrome_beta_win.ps1' - }))); - - this._executables.push(this._createChromiumChannel('chrome-dev', { - 'linux': '/opt/google/chrome-unstable/chrome', - 'darwin': '/Applications/Google Chrome Dev.app/Contents/MacOS/Google Chrome Dev', - 'win32': `\\Google\\Chrome Dev\\Application\\chrome.exe` - })); - - this._executables.push(this._createChromiumChannel('chrome-canary', { - 'linux': '', - 'darwin': '/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary', - 'win32': `\\Google\\Chrome SxS\\Application\\chrome.exe` - })); - - this._executables.push(this._createChromiumChannel('msedge', { - 'linux': '/opt/microsoft/msedge/msedge', - 'darwin': '/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge', - 'win32': `\\Microsoft\\Edge\\Application\\msedge.exe` - }, () => this._installMSEdgeChannel('msedge', { - 'linux': 'reinstall_msedge_stable_linux.sh', - 'darwin': 'reinstall_msedge_stable_mac.sh', - 'win32': 'reinstall_msedge_stable_win.ps1' - }))); - - this._executables.push(this._createChromiumChannel('msedge-beta', { - 'linux': '/opt/microsoft/msedge-beta/msedge', - 'darwin': '/Applications/Microsoft Edge Beta.app/Contents/MacOS/Microsoft Edge Beta', - 'win32': `\\Microsoft\\Edge Beta\\Application\\msedge.exe` - }, () => this._installMSEdgeChannel('msedge-beta', { - 'darwin': 'reinstall_msedge_beta_mac.sh', - 'linux': 'reinstall_msedge_beta_linux.sh', - 'win32': 'reinstall_msedge_beta_win.ps1' - }))); - - this._executables.push(this._createChromiumChannel('msedge-dev', { - 'linux': '/opt/microsoft/msedge-dev/msedge', - 'darwin': '/Applications/Microsoft Edge Dev.app/Contents/MacOS/Microsoft Edge Dev', - 'win32': `\\Microsoft\\Edge Dev\\Application\\msedge.exe` - }, () => this._installMSEdgeChannel('msedge-dev', { - 'darwin': 'reinstall_msedge_dev_mac.sh', - 'linux': 'reinstall_msedge_dev_linux.sh', - 'win32': 'reinstall_msedge_dev_win.ps1' - }))); - - this._executables.push(this._createChromiumChannel('msedge-canary', { - 'linux': '', - 'darwin': '/Applications/Microsoft Edge Canary.app/Contents/MacOS/Microsoft Edge Canary', - 'win32': `\\Microsoft\\Edge SxS\\Application\\msedge.exe` - })); - - const firefox = descriptors.find(d => d.name === 'firefox'); - const firefoxExecutable = findExecutablePath(firefox.dir, 'firefox'); - - this._executables.push({ - type: 'browser', - name: 'firefox', - browserName: 'firefox', - directory: firefox.dir, - executablePath: () => firefoxExecutable, - executablePathOrDie: sdkLanguage => executablePathOrDie('firefox', firefoxExecutable, firefox.installByDefault, sdkLanguage), - installType: firefox.installByDefault ? 'download-by-default' : 'download-on-demand', - validateHostRequirements: sdkLanguage => this._validateHostRequirements(sdkLanguage, 'firefox', firefox.dir, ['firefox'], [], ['firefox']), - _install: () => this._downloadExecutable(firefox, firefoxExecutable, DOWNLOAD_URLS['firefox'][_utils.hostPlatform], 'PLAYWRIGHT_FIREFOX_DOWNLOAD_HOST'), - _dependencyGroup: 'firefox' - }); - - const firefoxBeta = descriptors.find(d => d.name === 'firefox-beta'); - const firefoxBetaExecutable = findExecutablePath(firefoxBeta.dir, 'firefox'); - - this._executables.push({ - type: 'tool', - name: 'firefox-beta', - browserName: 'firefox', - directory: firefoxBeta.dir, - executablePath: () => firefoxBetaExecutable, - executablePathOrDie: sdkLanguage => executablePathOrDie('firefox-beta', firefoxBetaExecutable, firefoxBeta.installByDefault, sdkLanguage), - installType: firefoxBeta.installByDefault ? 'download-by-default' : 'download-on-demand', - validateHostRequirements: sdkLanguage => this._validateHostRequirements(sdkLanguage, 'firefox', firefoxBeta.dir, ['firefox'], [], ['firefox']), - _install: () => this._downloadExecutable(firefoxBeta, firefoxBetaExecutable, DOWNLOAD_URLS['firefox-beta'][_utils.hostPlatform], 'PLAYWRIGHT_FIREFOX_DOWNLOAD_HOST'), - _dependencyGroup: 'firefox' - }); - - const webkit = descriptors.find(d => d.name === 'webkit'); - const webkitExecutable = findExecutablePath(webkit.dir, 'webkit'); - const webkitLinuxLddDirectories = [_path.default.join('minibrowser-gtk'), _path.default.join('minibrowser-gtk', 'bin'), _path.default.join('minibrowser-gtk', 'lib'), _path.default.join('minibrowser-wpe'), _path.default.join('minibrowser-wpe', 'bin'), _path.default.join('minibrowser-wpe', 'lib')]; - - this._executables.push({ - type: 'browser', - name: 'webkit', - browserName: 'webkit', - directory: webkit.dir, - executablePath: () => webkitExecutable, - executablePathOrDie: sdkLanguage => executablePathOrDie('webkit', webkitExecutable, webkit.installByDefault, sdkLanguage), - installType: webkit.installByDefault ? 'download-by-default' : 'download-on-demand', - validateHostRequirements: sdkLanguage => this._validateHostRequirements(sdkLanguage, 'webkit', webkit.dir, webkitLinuxLddDirectories, ['libGLESv2.so.2', 'libx264.so'], ['']), - _install: () => this._downloadExecutable(webkit, webkitExecutable, DOWNLOAD_URLS['webkit'][_utils.hostPlatform], 'PLAYWRIGHT_WEBKIT_DOWNLOAD_HOST'), - _dependencyGroup: 'webkit' - }); - - const ffmpeg = descriptors.find(d => d.name === 'ffmpeg'); - const ffmpegExecutable = findExecutablePath(ffmpeg.dir, 'ffmpeg'); - - this._executables.push({ - type: 'tool', - name: 'ffmpeg', - browserName: undefined, - directory: ffmpeg.dir, - executablePath: () => ffmpegExecutable, - executablePathOrDie: sdkLanguage => executablePathOrDie('ffmpeg', ffmpegExecutable, ffmpeg.installByDefault, sdkLanguage), - installType: ffmpeg.installByDefault ? 'download-by-default' : 'download-on-demand', - validateHostRequirements: () => Promise.resolve(), - _install: () => this._downloadExecutable(ffmpeg, ffmpegExecutable, DOWNLOAD_URLS['ffmpeg'][_utils.hostPlatform], 'PLAYWRIGHT_FFMPEG_DOWNLOAD_HOST'), - _dependencyGroup: 'tools' - }); - } - - _createChromiumChannel(name, lookAt, install) { - const executablePath = (sdkLanguage, shouldThrow) => { - const suffix = lookAt[process.platform]; - - if (!suffix) { - if (shouldThrow) throw new Error(`Chromium distribution '${name}' is not supported on ${process.platform}`); - return undefined; - } - - const prefixes = process.platform === 'win32' ? [process.env.LOCALAPPDATA, process.env.PROGRAMFILES, process.env['PROGRAMFILES(X86)']].filter(Boolean) : ['']; - - for (const prefix of prefixes) { - const executablePath = _path.default.join(prefix, suffix); - - if ((0, _utils.canAccessFile)(executablePath)) return executablePath; - } - - if (!shouldThrow) return undefined; - const location = prefixes.length ? ` at ${_path.default.join(prefixes[0], suffix)}` : ``; // TODO: language-specific error message - - const installation = install ? `\nRun "${buildPlaywrightCLICommand(sdkLanguage, 'install ' + name)}"` : ''; - throw new Error(`Chromium distribution '${name}' is not found${location}${installation}`); - }; - - return { - type: 'channel', - name, - browserName: 'chromium', - directory: undefined, - executablePath: sdkLanguage => executablePath(sdkLanguage, false), - executablePathOrDie: sdkLanguage => executablePath(sdkLanguage, true), - installType: install ? 'install-script' : 'none', - validateHostRequirements: () => Promise.resolve(), - _install: install - }; - } - - executables() { - return this._executables; - } - - findExecutable(name) { - return this._executables.find(b => b.name === name); - } - - defaultExecutables() { - return this._executables.filter(e => e.installType === 'download-by-default'); - } - - _addRequirementsAndDedupe(executables) { - const set = new Set(); - - for (const executable of executables) { - set.add(executable); - if (executable.browserName === 'chromium') set.add(this.findExecutable('ffmpeg')); - } - - return Array.from(set); - } - - async _validateHostRequirements(sdkLanguage, browserName, browserDirectory, linuxLddDirectories, dlOpenLibraries, windowsExeAndDllDirectories) { - if ((0, _utils.getAsBooleanFromENV)('PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS')) { - process.stdout.write('Skipping host requirements validation logic because `PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS` env variable is set.\n'); - return; - } - - const ubuntuVersion = await (0, _ubuntuVersion.getUbuntuVersion)(); - if (browserName === 'firefox' && ubuntuVersion === '16.04') throw new Error(`Cannot launch Firefox on Ubuntu 16.04! Minimum required Ubuntu version for Firefox browser is 18.04`); - if (os.platform() === 'linux') return await (0, _dependencies.validateDependenciesLinux)(sdkLanguage, linuxLddDirectories.map(d => _path.default.join(browserDirectory, d)), dlOpenLibraries); - if (os.platform() === 'win32' && os.arch() === 'x64') return await (0, _dependencies.validateDependenciesWindows)(windowsExeAndDllDirectories.map(d => _path.default.join(browserDirectory, d))); - } - - async installDeps(executablesToInstallDeps) { - const executables = this._addRequirementsAndDedupe(executablesToInstallDeps); - - const targets = new Set(); - - for (const executable of executables) { - if (executable._dependencyGroup) targets.add(executable._dependencyGroup); - } - - targets.add('tools'); - if (os.platform() === 'win32') return await (0, _dependencies.installDependenciesWindows)(targets); - if (os.platform() === 'linux') return await (0, _dependencies.installDependenciesLinux)(targets); - } - - async install(executablesToInstall) { - const executables = this._addRequirementsAndDedupe(executablesToInstall); - - await fs.promises.mkdir(registryDirectory, { - recursive: true - }); - - const lockfilePath = _path.default.join(registryDirectory, '__dirlock'); - - const linksDir = _path.default.join(registryDirectory, '.links'); - - let releaseLock; - - try { - releaseLock = await _properLockfile.default.lock(registryDirectory, { - retries: { - // Retry 20 times during 10 minutes with - // exponential back-off. - // See documentation at: https://www.npmjs.com/package/retry#retrytimeoutsoptions - retries: 20, - factor: 1.27579 - }, - onCompromised: err => { - throw new Error(`${err.message} Path: ${lockfilePath}`); - }, - lockfilePath - }); // Create a link first, so that cache validation does not remove our own browsers. - - await fs.promises.mkdir(linksDir, { - recursive: true - }); - await fs.promises.writeFile(_path.default.join(linksDir, (0, _utils.calculateSha1)(PACKAGE_PATH)), PACKAGE_PATH); // Remove stale browsers. - - await this._validateInstallationCache(linksDir); // Install browsers for this package. - - for (const executable of executables) { - if (executable._install) await executable._install();else throw new Error(`ERROR: Playwright does not support installing ${executable.name}`); - } - } catch (e) { - if (e.code === 'ELOCKED') { - const rmCommand = process.platform === 'win32' ? 'rm -R' : 'rm -rf'; - throw new Error('\n' + (0, _utils.wrapInASCIIBox)([`An active lockfile is found at:`, ``, ` ${lockfilePath}`, ``, `Either:`, `- wait a few minutes if other Playwright is installing browsers in parallel`, `- remove lock manually with:`, ``, ` ${rmCommand} ${lockfilePath}`, ``, `<3 Playwright Team`].join('\n'), 1)); - } else { - throw e; - } - } finally { - if (releaseLock) await releaseLock(); - } - } - - async _downloadExecutable(descriptor, executablePath, downloadURLTemplate, downloadHostEnv) { - if (!downloadURLTemplate || !executablePath) throw new Error(`ERROR: Playwright does not support ${descriptor.name} on ${_utils.hostPlatform}`); - const downloadHost = downloadHostEnv && (0, _utils.getFromENV)(downloadHostEnv) || (0, _utils.getFromENV)('PLAYWRIGHT_DOWNLOAD_HOST') || 'https://playwright.azureedge.net'; - const downloadURL = util.format(downloadURLTemplate, downloadHost, descriptor.revision); - const title = `${descriptor.name} v${descriptor.revision}`; - const downloadFileName = `playwright-download-${descriptor.name}-${_utils.hostPlatform}-${descriptor.revision}.zip`; - await (0, _browserFetcher.downloadBrowserWithProgressBar)(title, descriptor.dir, executablePath, downloadURL, downloadFileName).catch(e => { - throw new Error(`Failed to download ${title}, caused by\n${e.stack}`); - }); - await fs.promises.writeFile(markerFilePath(descriptor.dir), ''); - } - - async _installMSEdgeChannel(channel, scripts) { - const scriptArgs = []; - - if (process.platform !== 'linux') { - const products = JSON.parse(await (0, _utils.fetchData)({ - url: 'https://edgeupdates.microsoft.com/api/products' - })); - const productName = { - 'msedge': 'Stable', - 'msedge-beta': 'Beta', - 'msedge-dev': 'Dev' - }[channel]; - const product = products.find(product => product.Product === productName); - const searchConfig = { - darwin: { - platform: 'MacOS', - arch: 'universal', - artifact: 'pkg' - }, - win32: { - platform: 'Windows', - arch: 'x64', - artifact: 'msi' - } - }[process.platform]; - const release = searchConfig ? product.Releases.find(release => release.Platform === searchConfig.platform && release.Architecture === searchConfig.arch) : null; - const artifact = release ? release.Artifacts.find(artifact => artifact.ArtifactName === searchConfig.artifact) : null; - if (artifact) scriptArgs.push(artifact.Location - /* url */ - );else throw new Error(`Cannot install ${channel} on ${process.platform}`); - } - - await this._installChromiumChannel(channel, scripts, scriptArgs); - } - - async _installChromiumChannel(channel, scripts, scriptArgs = []) { - const scriptName = scripts[process.platform]; - if (!scriptName) throw new Error(`Cannot install ${channel} on ${process.platform}`); - const isPowerShell = scriptName.endsWith('.ps1'); - const shell = isPowerShell ? 'powershell.exe' : 'bash'; - const args = [...(isPowerShell ? ['-ExecutionPolicy', 'Bypass', '-File'] : []), _path.default.join(BIN_PATH, scriptName), ...scriptArgs]; - const { - code - } = await (0, _utils.spawnAsync)(shell, args, { - cwd: BIN_PATH, - stdio: 'inherit' - }); - if (code !== 0) throw new Error(`Failed to install ${channel}`); - } - - async _validateInstallationCache(linksDir) { - // 1. Collect used downloads and package descriptors. - const usedBrowserPaths = new Set(); - - for (const fileName of await fs.promises.readdir(linksDir)) { - const linkPath = _path.default.join(linksDir, fileName); - - let linkTarget = ''; - - try { - linkTarget = (await fs.promises.readFile(linkPath)).toString(); - - const browsersJSON = require(_path.default.join(linkTarget, 'browsers.json')); - - const descriptors = readDescriptors(browsersJSON); - - for (const browserName of allDownloadable) { - // We retain browsers if they are found in the descriptor. - // Note, however, that there are older versions out in the wild that rely on - // the "download" field in the browser descriptor and use its value - // to retain and download browsers. - // As of v1.10, we decided to abandon "download" field. - const descriptor = descriptors.find(d => d.name === browserName); - if (!descriptor) continue; - const usedBrowserPath = descriptor.dir; - const browserRevision = parseInt(descriptor.revision, 10); // Old browser installations don't have marker file. - - const shouldHaveMarkerFile = browserName === 'chromium' && browserRevision >= 786218 || browserName === 'firefox' && browserRevision >= 1128 || browserName === 'webkit' && browserRevision >= 1307 || browserName !== 'firefox' && browserName !== 'chromium' && browserName !== 'webkit'; - if (!shouldHaveMarkerFile || (await (0, _utils.existsAsync)(markerFilePath(usedBrowserPath)))) usedBrowserPaths.add(usedBrowserPath); - } - } catch (e) { - await fs.promises.unlink(linkPath).catch(e => {}); - } - } // 2. Delete all unused browsers. - - - if (!(0, _utils.getAsBooleanFromENV)('PLAYWRIGHT_SKIP_BROWSER_GC')) { - let downloadedBrowsers = (await fs.promises.readdir(registryDirectory)).map(file => _path.default.join(registryDirectory, file)); - downloadedBrowsers = downloadedBrowsers.filter(file => isBrowserDirectory(file)); - const directories = new Set(downloadedBrowsers); - - for (const browserDirectory of usedBrowserPaths) directories.delete(browserDirectory); - - for (const directory of directories) (0, _browserFetcher.logPolitely)('Removing unused browser at ' + directory); - - await (0, _utils.removeFolders)([...directories]); - } - } - -} - -exports.Registry = Registry; - -function markerFilePath(browserDirectory) { - return _path.default.join(browserDirectory, 'INSTALLATION_COMPLETE'); -} - -function buildPlaywrightCLICommand(sdkLanguage, parameters) { - switch (sdkLanguage) { - case 'python': - return `playwright ${parameters}`; - - case 'java': - return `mvn exec:java -e -Dexec.mainClass=com.microsoft.playwright.CLI -Dexec.args="${parameters}"`; - - case 'csharp': - return `playwright ${parameters}`; - - default: - return `npx playwright ${parameters}`; - } -} - -async function installDefaultBrowsersForNpmInstall() { - const defaultBrowserNames = registry.defaultExecutables().map(e => e.name); - return installBrowsersForNpmInstall(defaultBrowserNames); -} - -async function installBrowsersForNpmInstall(browsers) { - // PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD should have a value of 0 or 1 - if ((0, _utils.getAsBooleanFromENV)('PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD')) { - (0, _browserFetcher.logPolitely)('Skipping browsers download because `PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD` env variable is set'); - return false; - } - - const executables = []; - - for (const browserName of browsers) { - const executable = registry.findExecutable(browserName); - if (!executable || executable.installType === 'none') throw new Error(`Cannot install ${browserName}`); - executables.push(executable); - } - - await registry.install(executables); -} - -function findChromiumChannel(sdkLanguage) { - // Fall back to the stable channels of popular vendors to work out of the box. - // Null means no installation and no channels found. - let channel = null; - - for (const name of ['chromium', 'chrome', 'msedge']) { - try { - registry.findExecutable(name).executablePathOrDie(sdkLanguage); - channel = name === 'chromium' ? undefined : name; - break; - } catch (e) {} - } - - if (channel === null) { - const installCommand = buildPlaywrightCLICommand(sdkLanguage, `install chromium`); - const prettyMessage = [`No chromium-based browser found on the system.`, `Please run the following command to download one:`, ``, ` ${installCommand}`, ``, `<3 Playwright Team`].join('\n'); - throw new Error('\n' + (0, _utils.wrapInASCIIBox)(prettyMessage, 1)); - } - - return channel; -} - -const registry = new Registry(require('../../browsers.json')); -exports.registry = registry; -//# sourceMappingURL=registry.js.map