{ lib , python3 , fetchFromGitHub , fetchYarnDeps , zlib , nixosTests , postgresqlTestHook , postgresql , yarn , fixup-yarn-lock , nodejs , stdenv , server-mode ? true }: let pname = "pgadmin"; version = "8.5"; yarnHash = "sha256-VLf8GRJ2IIcrfBqdgT2uZG3kOEt0pd7Cksm+tdrQogA="; src = fetchFromGitHub { owner = "pgadmin-org"; repo = "pgadmin4"; rev = "REL-${lib.versions.major version}_${lib.versions.minor version}"; hash = "sha256-D/8tiVL2DwxvDiSqHeOF1P/yRRniZY39TyUfibrfAOo="; }; # keep the scope, as it is used throughout the derivation and tests # this also makes potential future overrides easier pythonPackages = python3.pkgs.overrideScope (final: prev: rec { # Flask 5.4.3 introduces an CSRF error which makes it impossible to login # So either we downgrade flask here or use "WTF_CSRF_ENABLED = false" in the # module config to disable CSRF. flask-security-too = prev.flask-security-too.overridePythonAttrs (oldAttrs: rec { version = "5.4.1"; src = oldAttrs.src.override { inherit version; hash = "sha256-Ay7+gk+zuUlXtw0LDdsnvSa22z+yE6VR1guu9QmiFvw="; }; }); }); offlineCache = fetchYarnDeps { yarnLock = ./yarn.lock; hash = yarnHash; }; # don't bother to test kerberos authentication # skip tests on macOS which fail due to an error in keyring, see https://github.com/NixOS/nixpkgs/issues/281214 skippedTests = builtins.concatStringsSep "," ( [ "browser.tests.test_kerberos_with_mocking" ] ++ lib.optionals stdenv.isDarwin [ "browser.server_groups.servers.tests.test_all_server_get" "browser.server_groups.servers.tests.test_check_connect" "browser.server_groups.servers.tests.test_check_ssh_mock_connect" "browser.server_groups.servers.tests.test_is_password_saved" ] ); in pythonPackages.buildPythonApplication rec { inherit pname version src; # from Dockerfile CPPFLAGS = "-DPNG_ARM_NEON_OPT=0"; format = "setuptools"; patches = [ # Expose setup.py for later use ./expose-setup.py.patch # check for permission of /etc/pgadmin/config_system and don't fail ./check-system-config-dir.patch ]; postPatch = '' # patching Makefile, so it doesn't try to build sphinx documentation here # (will do so later) substituteInPlace Makefile \ --replace-fail 'LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 $(MAKE) -C docs/en_US -f Makefile.sphinx html' "true" # fix document which refers a non-existing document and fails substituteInPlace docs/en_US/contributions.rst \ --replace-fail "code_snippets" "" # relax dependencies sed 's|==|>=|g' -i requirements.txt # fix extra_require error with "*" in match sed 's|*|0|g' -i requirements.txt # remove packageManager from package.json so we can work without corepack substituteInPlace web/package.json \ --replace-fail "\"packageManager\": \"yarn@3.6.4\"" "\"\": \"\"" substituteInPlace pkg/pip/setup_pip.py \ --replace-fail "req = req.replace('psycopg[c]', 'psycopg[binary]')" "req = req" ${lib.optionalString (!server-mode) '' substituteInPlace web/config.py \ --replace-fail "SERVER_MODE = True" "SERVER_MODE = False" ''} ''; preBuild = '' # Adapted from pkg/pip/build.sh echo Creating required directories... mkdir -p pip-build/pgadmin4/docs echo Building the documentation cd docs/en_US sphinx-build -W -b html -d _build/doctrees . _build/html # Build the clean tree cd .. cp -r * ../pip-build/pgadmin4/docs for DIR in `ls -d ??_??/` do if [ -d ''${DIR}_build/html ]; then mkdir -p ../pip-build/pgadmin4/docs/''${DIR}_build cp -R ''${DIR}_build/html ../pip-build/pgadmin4/docs/''${DIR}_build fi done cd ../ # mkYarnModules and mkYarnPackage have problems running the webpacker echo Building the web frontend... cd web export HOME="$TMPDIR" yarn config --offline set yarn-offline-mirror "${offlineCache}" # replace with converted yarn.lock file rm yarn.lock cp ${./yarn.lock} yarn.lock chmod +w yarn.lock fixup-yarn-lock yarn.lock yarn install --offline --frozen-lockfile --ignore-platform --ignore-scripts --no-progress --non-interactive patchShebangs node_modules/ yarn webpacker cp -r * ../pip-build/pgadmin4 # save some disk space rm -rf ../pip-build/pgadmin4/node_modules cd .. echo Creating distro config... echo HELP_PATH = \'../../docs/en_US/_build/html/\' > pip-build/pgadmin4/config_distro.py echo MINIFY_HTML = False >> pip-build/pgadmin4/config_distro.py echo Creating manifest... echo recursive-include pgadmin4 \* > pip-build/MANIFEST.in echo Building wheel... cd pip-build # copy non-standard setup.py to local directory # so setuptools-build-hook can call it cp -v ../pkg/pip/setup_pip.py setup.py ''; nativeBuildInputs = with pythonPackages; [ cython pip sphinx yarn fixup-yarn-lock nodejs ]; buildInputs = [ zlib pythonPackages.wheel ]; propagatedBuildInputs = with pythonPackages; [ flask flask-gravatar flask-login flask-mail flask-migrate flask-sqlalchemy flask-wtf flask-compress passlib pytz simplejson sqlparse wtforms flask-paranoid psutil psycopg python-dateutil sqlalchemy itsdangerous flask-security-too bcrypt cryptography sshtunnel ldap3 flask-babel gssapi flask-socketio eventlet httpagentparser user-agents wheel authlib qrcode pillow pyotp botocore boto3 azure-mgmt-subscription azure-mgmt-rdbms azure-mgmt-resource azure-identity sphinxcontrib-youtube dnspython greenlet speaklater3 google-auth-oauthlib google-api-python-client keyring typer rich jsonformatter ]; passthru.tests = { inherit (nixosTests) pgadmin4; }; nativeCheckInputs = [ postgresqlTestHook postgresql pythonPackages.testscenarios pythonPackages.selenium ]; checkPhase = '' runHook preCheck ## Setup ## # pgadmin needs a home directory to save the configuration export HOME=$TMPDIR cd pgadmin4 # set configuration for postgresql test # also ensure Server Mode is set to false. If not, the tests will fail, since pgadmin expects read/write permissions # in /var/lib/pgadmin and /var/log/pgadmin # see https://github.com/pgadmin-org/pgadmin4/blob/fd1c26408bbf154fa455a49ee5c12895933833a3/web/regression/runtests.py#L217-L226 cp -v regression/test_config.json.in regression/test_config.json substituteInPlace regression/test_config.json --replace-fail "localhost" "$PGHOST" substituteInPlace regression/runtests.py --replace-fail "builtins.SERVER_MODE = None" "builtins.SERVER_MODE = False" ## Browser test ## python regression/runtests.py --pkg browser --exclude ${skippedTests} ## Reverse engineered SQL test ## python regression/runtests.py --pkg resql runHook postCheck ''; meta = with lib; { description = "Administration and development platform for PostgreSQL${optionalString (!server-mode) ". Desktop Mode"}"; longDescription = '' pgAdmin 4 is designed to meet the needs of both novice and experienced Postgres users alike, providing a powerful graphical interface that simplifies the creation, maintenance and use of database objects. ${if server-mode then '' This version is build with SERVER_MODE set to True (the default). It will require access to `/var/lib/pgadmin` and `/var/log/pgadmin`. This is the default version for the NixOS module `services.pgadmin`. This should NOT be used in combination with the `pgadmin4-desktopmode` package as they will interfere. '' else '' This version is build with SERVER_MODE set to False. It will require access to `~/.pgadmin/`. This version is suitable for single-user deployment or where access to `/var/lib/pgadmin` cannot be granted or the NixOS module cannot be used (e.g. on MacOS). This should NOT be used in combination with the NixOS module `pgadmin` as they will interfere. ''} ''; homepage = "https://www.pgadmin.org/"; license = licenses.mit; changelog = "https://www.pgadmin.org/docs/pgadmin4/latest/release_notes_${lib.versions.major version}_${lib.versions.minor version}.html"; maintainers = with maintainers; [ gador ]; mainProgram = "pgadmin4"; platforms = platforms.unix; }; }