diff --git a/.gitignore b/.gitignore index 779dd19..ac2b586 100644 --- a/.gitignore +++ b/.gitignore @@ -3,47 +3,6 @@ /.coverage /build /deploy_rsa -/examples/*.txt -/examples/aiohttp -/examples/aiohttp.nix -/examples/aiohttp_override.nix -/examples/awscli_and_requests -/examples/awscli_and_requests.nix -/examples/connexion -/examples/connexion.nix -/examples/empy -/examples/empy.nix -/examples/empy_override.nix -/examples/flake8 -/examples/flake8-includes -/examples/flake8-includes.nix -/examples/flake8-includes_override.nix -/examples/flake8.nix -/examples/flake8_override.nix -/examples/ldap -/examples/ldap.nix -/examples/lektor -/examples/lektor -/examples/lektor.nix -/examples/lektor.nix -/examples/mercurial -/examples/mercurial.nix -/examples/mercurial_override.nix -/examples/pillow -/examples/pillow -/examples/pillow.nix -/examples/pillow.nix -/examples/pillow_override.nix -/examples/pillow_override.nix -/examples/pypi2nix -/examples/rss2email -/examples/rss2email.nix -/examples/rss2email_override.nix -/examples/scipy -/examples/scipy.nix -/examples/tornado -/examples/tornado.nix -/examples/tornado_override.nix /out/ /result* /src/pypi2nix.egg-info/ @@ -62,4 +21,4 @@ /dist/ *.egg-info **/.eggs/** -.mypy_cache \ No newline at end of file +.mypy_cache diff --git a/.travis.yml b/.travis.yml index e442dc9..8edd2d4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -53,3 +53,11 @@ jobs: - nix build - result/bin/pypi2nix --version - nix-shell --command 'pytest unittests/' + - stage: package tests + name: package installation + os: linux + env: + - NIX_PATH=nixpkgs=https://github.com/NixOS/nixpkgs-channels/archive/nixos-unstable.tar.gz + + script: + - nix-shell --command 'install_test.py' diff --git a/default.nix b/default.nix index 6de6fca..f427c83 100644 --- a/default.nix +++ b/default.nix @@ -45,9 +45,9 @@ in python.mkDerivation { dontUseSetuptoolsShellHook = true; checkPhase = if doCheck then '' echo "Running black ..." - black --check --diff -v setup.py src/ unittests/ mypy/ ${maybeIntegrationTestsDir} + black --check --diff -v setup.py src/ unittests/ mypy/ ${maybeIntegrationTestsDir} scripts/ echo "Running flake8 ..." - flake8 -v setup.py src/ ${maybeIntegrationTestsDir} unittests/ + flake8 -v setup.py src/ ${maybeIntegrationTestsDir} unittests/ scripts/ mypy --config-file setup.cfg src/ mypy \ --config-file setup.cfg \ diff --git a/requirements-dev.txt b/requirements-dev.txt index cbf4e12..5de6922 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -14,6 +14,9 @@ attrs # develop pdbpp +# packaging +twine + # setup requires pytest-runner setuptools-scm diff --git a/requirements.nix b/requirements.nix index 69c2b63..caecd9b 100644 --- a/requirements.nix +++ b/requirements.nix @@ -148,6 +148,25 @@ let }; }; + "bleach" = python.mkDerivation { + name = "bleach-3.1.0"; + src = pkgs.fetchurl { + url = "https://files.pythonhosted.org/packages/78/5a/0df03e8735cd9c75167528299c738702437589b9c71a849489d00ffa82e8/bleach-3.1.0.tar.gz"; + sha256 = "3fdf7f77adcf649c9911387df51254b813185e32b2c6619f690b593a617e19fa"; +}; + doCheck = commonDoCheck; + buildInputs = commonBuildInputs ++ [ ]; + propagatedBuildInputs = [ + self."six" + self."webencodings" + ]; + meta = with pkgs.stdenv.lib; { + homepage = "https://github.com/mozilla/bleach"; + license = licenses.asl20; + description = "An easy safelist-based HTML-sanitizing tool."; + }; + }; + "certifi" = python.mkDerivation { name = "certifi-2019.9.11"; src = pkgs.fetchurl { @@ -614,6 +633,22 @@ let }; }; + "pkginfo" = python.mkDerivation { + name = "pkginfo-1.5.0.1"; + src = pkgs.fetchurl { + url = "https://files.pythonhosted.org/packages/6c/04/fd6683d24581894be8b25bc8c68ac7a0a73bf0c4d74b888ac5fe9a28e77f/pkginfo-1.5.0.1.tar.gz"; + sha256 = "7424f2c8511c186cd5424bbf31045b77435b37a8d604990b79d4e70d741148bb"; +}; + doCheck = commonDoCheck; + buildInputs = commonBuildInputs ++ [ ]; + propagatedBuildInputs = [ ]; + meta = with pkgs.stdenv.lib; { + homepage = "https://code.launchpad.net/~tseaver/pkginfo/trunk"; + license = licenses.mit; + description = "Query metadatdata from sdists / bdists / installed packages."; + }; + }; + "pluggy" = python.mkDerivation { name = "pluggy-0.13.0"; src = pkgs.fetchurl { @@ -800,6 +835,27 @@ let }; }; + "readme-renderer" = python.mkDerivation { + name = "readme-renderer-24.0"; + src = pkgs.fetchurl { + url = "https://files.pythonhosted.org/packages/44/de/a567140b13a0fc8d3b04d85a510b5a7d9869b44b2939fa8ac07c5e421485/readme_renderer-24.0.tar.gz"; + sha256 = "bb16f55b259f27f75f640acf5e00cf897845a8b3e4731b5c1a436e4b8529202f"; +}; + doCheck = commonDoCheck; + buildInputs = commonBuildInputs ++ [ ]; + propagatedBuildInputs = [ + self."bleach" + self."docutils" + self."pygments" + self."six" + ]; + meta = with pkgs.stdenv.lib; { + homepage = "https://github.com/pypa/readme_renderer"; + license = licenses.asl20; + description = "readme_renderer is a library for rendering \"readme\" descriptions for Warehouse"; + }; + }; + "requests" = python.mkDerivation { name = "requests-2.22.0"; src = pkgs.fetchurl { @@ -821,6 +877,24 @@ let }; }; + "requests-toolbelt" = python.mkDerivation { + name = "requests-toolbelt-0.9.1"; + src = pkgs.fetchurl { + url = "https://files.pythonhosted.org/packages/28/30/7bf7e5071081f761766d46820e52f4b16c8a08fef02d2eb4682ca7534310/requests-toolbelt-0.9.1.tar.gz"; + sha256 = "968089d4584ad4ad7c171454f0a5c6dac23971e9472521ea3b6d49d610aa6fc0"; +}; + doCheck = commonDoCheck; + buildInputs = commonBuildInputs ++ [ ]; + propagatedBuildInputs = [ + self."requests" + ]; + meta = with pkgs.stdenv.lib; { + homepage = "https://toolbelt.readthedocs.org"; + license = licenses.asl20; + description = "A utility belt for advanced users of python-requests"; + }; + }; + "setuptools" = python.mkDerivation { name = "setuptools-41.4.0"; src = pkgs.fetchurl { @@ -885,6 +959,45 @@ let }; }; + "tqdm" = python.mkDerivation { + name = "tqdm-4.36.1"; + src = pkgs.fetchurl { + url = "https://files.pythonhosted.org/packages/80/b3/6ca4806441b730782fc4613c6aa2070412295c5521f33ae151988e448929/tqdm-4.36.1.tar.gz"; + sha256 = "abc25d0ce2397d070ef07d8c7e706aede7920da163c64997585d42d3537ece3d"; +}; + doCheck = commonDoCheck; + buildInputs = commonBuildInputs ++ [ ]; + propagatedBuildInputs = [ ]; + meta = with pkgs.stdenv.lib; { + homepage = "https://github.com/tqdm/tqdm"; + license = licenses.mit; + description = "Fast, Extensible Progress Meter"; + }; + }; + + "twine" = python.mkDerivation { + name = "twine-2.0.0"; + src = pkgs.fetchurl { + url = "https://files.pythonhosted.org/packages/91/82/32c68749d10ae30dd126699ee471b8885d9a9ae326a0f25dac42bb6a3f28/twine-2.0.0.tar.gz"; + sha256 = "9fe7091715c7576df166df8ef6654e61bada39571783f2fd415bdcba867c6993"; +}; + doCheck = commonDoCheck; + buildInputs = commonBuildInputs ++ [ ]; + propagatedBuildInputs = [ + self."pkginfo" + self."readme-renderer" + self."requests" + self."requests-toolbelt" + self."setuptools" + self."tqdm" + ]; + meta = with pkgs.stdenv.lib; { + homepage = "https://twine.readthedocs.io/"; + license = licenses.asl20; + description = "Collection of utilities for publishing packages on PyPI"; + }; + }; + "typed-ast" = python.mkDerivation { name = "typed-ast-1.4.0"; src = pkgs.fetchurl { @@ -949,6 +1062,22 @@ let }; }; + "webencodings" = python.mkDerivation { + name = "webencodings-0.5.1"; + src = pkgs.fetchurl { + url = "https://files.pythonhosted.org/packages/0b/02/ae6ceac1baeda530866a85075641cec12989bd8d31af6d5ab4a3e8c92f47/webencodings-0.5.1.tar.gz"; + sha256 = "b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"; +}; + doCheck = commonDoCheck; + buildInputs = commonBuildInputs ++ [ ]; + propagatedBuildInputs = [ ]; + meta = with pkgs.stdenv.lib; { + homepage = "https://github.com/SimonSapin/python-webencodings"; + license = licenses.bsdOriginal; + description = "Character encoding aliases for legacy web content"; + }; + }; + "wheel" = python.mkDerivation { name = "wheel-0.33.6"; src = pkgs.fetchurl { diff --git a/requirements_frozen.txt b/requirements_frozen.txt index e4b72dc..aef7a4d 100644 --- a/requirements_frozen.txt +++ b/requirements_frozen.txt @@ -2,6 +2,7 @@ appdirs==1.4.3 atomicwrites==1.3.0 attrs==19.3.0 black==19.3b0 +bleach==3.1.0 certifi==2019.9.11 chardet==3.0.4 Click==7.0 @@ -28,6 +29,7 @@ nix-prefetch-github==2.3.1 packaging==19.2 Parsley==1.3 pdbpp==0.10.2 +pkginfo==1.5.0.1 pluggy==0.13.0 py==1.8.0 pycodestyle==2.5.0 @@ -38,13 +40,18 @@ pytest==5.2.2 pytest-cov==2.8.1 pytest-runner==5.1 pytoml==0.1.21 +readme-renderer==24.0 requests==2.22.0 +requests-toolbelt==0.9.1 setuptools-scm==3.3.3 six==1.12.0 toml==0.10.0 +tqdm==4.36.1 +twine==2.0.0 typed-ast==1.4.0 typing-extensions==3.7.4 urllib3==1.25.6 wcwidth==0.1.7 +webencodings==0.5.1 wmctrl==0.3 zipp==0.6.0 diff --git a/scripts/deploy_to_pypi.py b/scripts/deploy_to_pypi.py new file mode 100755 index 0000000..e324452 --- /dev/null +++ b/scripts/deploy_to_pypi.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python +import argparse +import os +import shutil +import subprocess + +from pypi2nix.version import pypi2nix_version + + +def main(): + set_up_environment() + args = parse_args() + pypi_name = get_pypi_name_from_args(args) + remove_old_build_artifacts() + deploy_to(pypi_name) + + +def set_up_environment(): + os.putenv("SOURCE_DATE_EPOCH", "315532800") + + +def parse_args(): + parser = argparse.ArgumentParser(description="Deploy pypi2nix to pypi") + parser.add_argument("--production", action="store_true", default=False) + return parser.parse_args() + + +def get_pypi_name_from_args(args): + return "pypi" if args.production else "test-pypi" + + +def remove_old_build_artifacts(): + shutil.rmtree("src/pypi2nix.egg-info", ignore_errors=True) + + +def deploy_to(pypi_name): + subprocess.run(["python", "setup.py", "sdist", "bdist_wheel"], check=True) + distribution_paths = [ + f"dist/pypi2nix-{pypi2nix_version}.tar.gz", + f"dist/pypi2nix-{pypi2nix_version}-py3-none-any.whl", + ] + subprocess.run( + ["twine", "upload", "-r", pypi_name] + distribution_paths, check=True + ) + + +if __name__ == "__main__": + main() diff --git a/scripts/install_test.py b/scripts/install_test.py new file mode 100755 index 0000000..8a2ceb7 --- /dev/null +++ b/scripts/install_test.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python +import os +import os.path +import shutil +import subprocess + +from pypi2nix.version import pypi2nix_version + + +def set_up_environment(): + os.putenv("SOURCE_DATE_EPOCH", "315532800") + os.unsetenv("PYTHONPATH") + + +def create_sdist(): + shutil.rmtree(os.path.join("src", "pypi2nix.egg-info"), ignore_errors=True) + subprocess.run(["build/venv/bin/python", "setup.py", "sdist"], check=True) + + +def create_virtual_env(): + os.makedirs("build", exist_ok=True) + try: + shutil.rmtree("build/venv") + except FileNotFoundError: + pass + subprocess.run(["python", "-m", "venv", "build/venv"], check=True) + + +def create_wheel(): + shutil.rmtree(os.path.join("src", "pypi2nix.egg-info"), ignore_errors=True) + subprocess.run(["build/venv/bin/pip", "install", "wheel"], check=True) + subprocess.run(["build/venv/bin/python", "setup.py", "bdist_wheel"], check=True) + + +def install_sdist(): + subprocess.run( + ["build/venv/bin/pip", "install", f"dist/pypi2nix-{pypi2nix_version}.tar.gz"], + check=True, + ) + + +def install_wheel(): + subprocess.run( + [ + "build/venv/bin/pip", + "install", + f"dist/pypi2nix-{pypi2nix_version}-py3-none-any.whl", + ], + check=True, + ) + + +def run_help_command(): + subprocess.run(["build/venv/bin/pypi2nix", "--help"], check=True) + + +def main(): + set_up_environment() + create_virtual_env() + create_sdist() + install_sdist() + run_help_command() + create_virtual_env() + create_wheel() + install_wheel() + run_help_command() + + +if __name__ == "__main__": + main() diff --git a/scripts/update_dependencies.py b/scripts/update_dependencies.py index 10e89c4..99d1b50 100755 --- a/scripts/update_dependencies.py +++ b/scripts/update_dependencies.py @@ -6,10 +6,9 @@ def main(): - subprocess.run(["nix", "build"], cwd=ROOT, check=True) subprocess.run( [ - "result/bin/pypi2nix", + "pypi2nix", "-r", "requirements.txt", "-r",