From 5d80a5129d31eb7580b012d8d98a3c6eb9089caf Mon Sep 17 00:00:00 2001 From: techknowlogick Date: Wed, 4 May 2022 16:48:46 -0400 Subject: [PATCH] playwright: init at 1.27.1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Yannik Rödel Co-authored-by: Sandro --- .../python-modules/playwright/default.nix | 221 ++++++++++++++++++ .../playwright/driver-location.patch | 47 ++++ .../python-modules/playwright/update.sh | 31 +++ pkgs/top-level/all-packages.nix | 2 + pkgs/top-level/python-packages.nix | 4 + 5 files changed, 305 insertions(+) create mode 100644 pkgs/development/python-modules/playwright/default.nix create mode 100644 pkgs/development/python-modules/playwright/driver-location.patch create mode 100755 pkgs/development/python-modules/playwright/update.sh diff --git a/pkgs/development/python-modules/playwright/default.nix b/pkgs/development/python-modules/playwright/default.nix new file mode 100644 index 000000000000..cea762819573 --- /dev/null +++ b/pkgs/development/python-modules/playwright/default.nix @@ -0,0 +1,221 @@ +{ lib +, stdenv +, buildPythonPackage +, chromium +, ffmpeg +, firefox +, git +, greenlet +, jq +, nodejs +, fetchFromGitHub +, fetchurl +, makeFontsConf +, makeWrapper +, pyee +, python +, pythonOlder +, runCommand +, setuptools-scm +, unzip +}: + +let + inherit (stdenv.hostPlatform) system; + throwSystem = throw "Unsupported system: ${system}"; + + driverVersion = "1.27.1"; + + driver = let + suffix = { + x86_64-linux = "linux"; + aarch64-linux = "linux-arm64"; + x86_64-darwin = "mac"; + aarch64-darwin = "mac-arm64"; + }.${system} or throwSystem; + filename = "playwright-${driverVersion}-${suffix}.zip"; + in stdenv.mkDerivation { + pname = "playwright-driver"; + version = driverVersion; + + src = fetchurl { + url = "https://playwright.azureedge.net/builds/driver/${filename}"; + sha256 = { + x86_64-linux = "0x71b4kb8hlyacixipgfbgjgrbmhckxpbmrs2xk8iis7n5kg7539"; + aarch64-linux = "125lih7g2gj91k7j196wy5a5746wyfr8idj3ng369yh5wl7lfcfv"; + x86_64-darwin = "0z2kww4iby1izkwn6z2ai94y87bkjvwak8awdmjm8sgg00pa9l1a"; + aarch64-darwin = "0qajh4ac5lr1sznb2c471r5c5g2r0dk2pyqz8vhvnbk36r524h1h"; + }.${system} or throwSystem; + }; + + sourceRoot = "."; + + nativeBuildInputs = [ unzip ]; + + postPatch = '' + # Use Nix's NodeJS instead of the bundled one. + substituteInPlace playwright.sh --replace '"$SCRIPT_PATH/node"' '"${nodejs}/bin/node"' + rm node + + # Hard-code the script path to $out directory to avoid a dependency on coreutils + substituteInPlace playwright.sh \ + --replace 'SCRIPT_PATH="$(cd "$(dirname "$0")" ; pwd -P)"' "SCRIPT_PATH=$out" + + patchShebangs playwright.sh package/bin/*.sh + ''; + + installPhase = '' + runHook preInstall + + mkdir -p $out/bin + mv playwright.sh $out/bin/playwright + mv package $out/ + + runHook postInstall + ''; + + passthru = { + inherit filename; + }; + }; + + browsers-mac = stdenv.mkDerivation { + pname = "playwright-browsers"; + version = driverVersion; + + src = runCommand "playwright-browsers-base" { + outputHashMode = "recursive"; + outputHashAlgo = "sha256"; + outputHash = { + x86_64-darwin = "0z2kww4iby1izkwn6z2ai94y87bkjvwak8awdmjm8sgg00pa9l1a"; + }.${system} or throwSystem; + } '' + export PLAYWRIGHT_BROWSERS_PATH=$out + ${driver}/bin/playwright install + rm -r $out/.links + ''; + + installPhase = '' + mkdir $out + cp -r * $out/ + ''; + }; + + browsers-linux = { withFirefox ? true, withChromium ? true }: let + fontconfig = makeFontsConf { + fontDirectories = []; + }; + in runCommand ("playwright-browsers" + + lib.optionalString (withFirefox && !withChromium) "-firefox" + + lib.optionalString (!withFirefox && withChromium) "-chromium") + { + nativeBuildInputs = [ + makeWrapper + jq + ]; + } ('' + BROWSERS_JSON=${driver}/share/playwright-driver/package/browsers.json + '' + lib.optionalString withChromium '' + CHROMIUM_REVISION=$(jq -r '.browsers[] | select(.name == "chromium").revision' $BROWSERS_JSON) + mkdir -p $out/chromium-$CHROMIUM_REVISION/chrome-linux + + # See here for the Chrome options: + # https://github.com/NixOS/nixpkgs/issues/136207#issuecomment-908637738 + makeWrapper ${chromium}/bin/chromium $out/chromium-$CHROMIUM_REVISION/chrome-linux/chrome \ + --set SSL_CERT_FILE /etc/ssl/certs/ca-bundle.crt \ + --set FONTCONFIG_FILE ${fontconfig} + '' + lib.optionalString withFirefox '' + FIREFOX_REVISION=$(jq -r '.browsers[] | select(.name == "firefox").revision' $BROWSERS_JSON) + mkdir -p $out/firefox-$FIREFOX_REVISION + ln -s ${firefox}/bin/firefox $out/firefox-$FIREFOX_REVISION/firefox + '' + '' + FFMPEG_REVISION=$(jq -r '.browsers[] | select(.name == "ffmpeg").revision' $BROWSERS_JSON) + mkdir -p $out/ffmpeg-$FFMPEG_REVISION + ln -s ${ffmpeg}/bin/ffmpeg $out/ffmpeg-$FFMPEG_REVISION/ffmpeg-linux + ''); +in +buildPythonPackage rec { + pname = "playwright"; + version = "1.27.1"; + format = "setuptools"; + disabled = pythonOlder "3.7"; + + src = fetchFromGitHub { + owner = "microsoft"; + repo = "playwright-python"; + rev = "v${version}"; + sha256 = "sha256-cI/4GdkmTikoP9O0Skh/0jCxxRypRua0231iKcxtBcY="; + }; + + patches = [ + # This patches two things: + # - The driver location, which is now a static package in the Nix store. + # - The setup script, which would try to download the driver package from + # a CDN and patch wheels so that they include it. We don't want this + # we have our own driver build. + ./driver-location.patch + ]; + + postPatch = '' + # if setuptools_scm is not listing files via git almost all python files are excluded + export HOME=$(mktemp -d) + git init . + git add -A . + git config --global user.email "nixpkgs" + git config --global user.name "nixpkgs" + git commit -m "workaround setuptools-scm" + + substituteInPlace setup.py \ + --replace "greenlet==1.1.3" "greenlet>=1.1.3" \ + --replace "pyee==8.1.0" "pyee>=8.1.0" \ + --replace "setuptools-scm==7.0.5" "setuptools-scm>=7.0.5" \ + --replace "wheel==0.37.1" "wheel>=0.37.1" + + # Skip trying to download and extract the driver. + # This is done manually in postInstall instead. + substituteInPlace setup.py \ + --replace "self._download_and_extract_local_driver(base_wheel_bundles)" "" + + # Set the correct driver path with the help of a patch in patches + substituteInPlace playwright/_impl/_driver.py \ + --replace "@driver@" "${driver}/bin/playwright" + ''; + + + nativeBuildInputs = [ git setuptools-scm ]; + + propagatedBuildInputs = [ + greenlet + pyee + ]; + + postInstall = '' + ln -s ${driver} $out/${python.sitePackages}/playwright/driver + ''; + + # Skip tests because they require network access. + doCheck = false; + + pythonImportsCheck = [ + "playwright" + ]; + + passthru = { + inherit driver; + browsers = { + x86_64-linux = browsers-linux { }; + aarch64-linux = browsers-linux { }; + x86_64-darwin = browsers-mac; + aarch64-darwin = browsers-mac; + }.${system} or throwSystem; + browsers-chromium = browsers-linux { withFirefox = false; }; + browsers-firefox = browsers-linux { withChromium = false; }; + }; + + meta = with lib; { + description = "Python version of the Playwright testing and automation library"; + homepage = "https://github.com/microsoft/playwright-python"; + license = licenses.asl20; + maintainers = with maintainers; [ techknowlogick yrd SuperSandro2000 ]; + }; +} diff --git a/pkgs/development/python-modules/playwright/driver-location.patch b/pkgs/development/python-modules/playwright/driver-location.patch new file mode 100644 index 000000000000..a7f79840c65d --- /dev/null +++ b/pkgs/development/python-modules/playwright/driver-location.patch @@ -0,0 +1,47 @@ +diff --git a/playwright/_impl/_driver.py b/playwright/_impl/_driver.py +index f3b911f..d00e509 100644 +--- a/playwright/_impl/_driver.py ++++ b/playwright/_impl/_driver.py +@@ -23,11 +23,7 @@ from playwright._repo_version import version + + + def compute_driver_executable() -> Path: +- package_path = Path(inspect.getfile(playwright)).parent +- platform = sys.platform +- if platform == "win32": +- return package_path / "driver" / "playwright.cmd" +- return package_path / "driver" / "playwright.sh" ++ return Path("@driver@") + + + if sys.version_info.major == 3 and sys.version_info.minor == 7: +diff --git a/setup.py b/setup.py +index 3487a6a..05112c2 100644 +--- a/setup.py ++++ b/setup.py +@@ -141,25 +141,8 @@ class PlaywrightBDistWheelCommand(BDistWheelCommand): + base_wheel_location: str = glob.glob(os.path.join(self.dist_dir, "*.whl"))[0] + without_platform = base_wheel_location[:-7] + for wheel_bundle in wheels: +- download_driver(wheel_bundle["zip_name"]) +- zip_file = ( +- f"driver/playwright-{driver_version}-{wheel_bundle['zip_name']}.zip" +- ) +- with zipfile.ZipFile(zip_file, "r") as zip: +- extractall(zip, f"driver/{wheel_bundle['zip_name']}") + wheel_location = without_platform + wheel_bundle["wheel"] + shutil.copy(base_wheel_location, wheel_location) +- with zipfile.ZipFile(wheel_location, "a") as zip: +- driver_root = os.path.abspath(f"driver/{wheel_bundle['zip_name']}") +- for dir_path, _, files in os.walk(driver_root): +- for file in files: +- from_path = os.path.join(dir_path, file) +- to_path = os.path.relpath(from_path, driver_root) +- zip.write(from_path, f"playwright/driver/{to_path}") +- zip.writestr( +- "playwright/driver/README.md", +- f"{wheel_bundle['wheel']} driver package", +- ) + os.remove(base_wheel_location) + if InWheel: + for whlfile in glob.glob(os.path.join(self.dist_dir, "*.whl")): diff --git a/pkgs/development/python-modules/playwright/update.sh b/pkgs/development/python-modules/playwright/update.sh new file mode 100755 index 000000000000..51dd8723c851 --- /dev/null +++ b/pkgs/development/python-modules/playwright/update.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env nix-shell +#!nix-shell -i bash -p curl gnused nix-prefetch common-updater-scripts +set -euo pipefail + +root="$(dirname "$(readlink -f "$0")")" + +version=$(curl ${GITHUB_TOKEN:+" -u \":$GITHUB_TOKEN\""} -s https://api.github.com/repos/microsoft/playwright-python/releases/latest | jq -r '.tag_name | sub("^v"; "")') + +# Most of the time, this should be the latest stable release of the Node-based +# Playwright version, but that isn't a guarantee, so this needs to be specified +# as well: +setup_py_url="https://github.com/microsoft/playwright-python/raw/v${version}/setup.py" +driver_version=$(curl -Ls "$setup_py_url" | grep '^driver_version =' | grep -Eo '[0-9]+\.[0-9]+\.[0-9]+') + +fetch_driver_arch() { + nix-prefetch-url "https://playwright.azureedge.net/builds/driver/playwright-${version}-${1}.zip" +} + +replace_sha() { + sed -i "s|$1 = \".\{44,52\}\"|$1 = \"$2\"|" "$root/default.nix" +} + +# Replace SHAs for the driver downloads +replace_sha "x86_64-linux" "$(fetch_driver_arch "linux")" +replace_sha "x86_64-darwin" "$(fetch_driver_arch "mac")" +replace_sha "aarch64-linux" "$(fetch_driver_arch "linux-arm64")" +replace_sha "aarch64-darwin" "$(fetch_driver_arch "mac-arm64")" + +# Update the version stamps +sed -i "s/driverVersion = \"[^\$]*\"/driverVersion = \"$driver_version\"/" "$root/default.nix" +update-source-version playwright "$version" --rev="v$version" diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 4c4a47223a04..5710817b86d2 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -10254,6 +10254,8 @@ with pkgs; playbar2 = libsForQt5.callPackage ../applications/audio/playbar2 { }; + playwright = with python3Packages; toPythonApplication playwright; + please = callPackage ../tools/security/please { }; plecost = callPackage ../tools/security/plecost { }; diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index 7c8d74853fe9..58af505febdb 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -7036,6 +7036,10 @@ in { pkuseg = callPackage ../development/python-modules/pkuseg { }; + playwright = callPackage ../development/python-modules/playwright { + inherit (pkgs) jq; + }; + pmsensor = callPackage ../development/python-modules/pmsensor { }; ppdeep = callPackage ../development/python-modules/ppdeep { };