Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pynixify/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class PackageMetadata:
description: Optional[str]
license: Optional[str]
url: Optional[str]
_fmt: Optional[str] = "pyproject"

@dataclass
class Package:
Expand Down
40 changes: 40 additions & 0 deletions pynixify/data/flitcore_patch.diff
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
diff --git a/flit_core/flit_core/buildapi.py b/flit_core/flit_core/buildapi.py
index 963bf61..5190b7e 100644
--- a/flit_core/flit_core/buildapi.py
+++ b/flit_core/flit_core/buildapi.py
@@ -3,6 +3,7 @@ import logging
import io
import os
import os.path as osp
+import sys
from pathlib import Path

from .common import (
@@ -13,6 +14,19 @@ from .config import read_flit_config
from .wheel import make_wheel_in, _write_wheel_file
from .sdist import SdistBuilder

+def _write_pynixify_files(config_settings, deps):
+ if config_settings is not None and "PYNIXIFY_OUT" in config_settings:
+ from pathlib import Path
+ import json
+ pynix_out = Path(config_settings['PYNIXIFY_OUT'])
+ for target in ("tests", "setup", "install"):
+ fp = (pynix_out / ("%s_requires.txt" % target)).open("w")
+ fp.write('\n'.join([str(req) for req in deps]))
+ fp.write('\nflit_core')
+ fp.close()
+ with (pynix_out / 'meta.json').open('w') as fp:
+ json.dump({"version": None, "url": None, "license": None, "description": None}, fp)
+
log = logging.getLogger(__name__)

# PEP 517 specifies that the CWD will always be the source tree
@@ -70,6 +84,7 @@ prepare_metadata_for_build_editable = prepare_metadata_for_build_wheel
def build_wheel(wheel_directory, config_settings=None, metadata_directory=None):
"""Builds a wheel, places it in wheel_directory"""
info = make_wheel_in(pyproj_toml, Path(wheel_directory))
+ _write_pynixify_files(config_settings, [])
return info.file.name

def build_editable(wheel_directory, config_settings=None, metadata_directory=None):
88 changes: 88 additions & 0 deletions pynixify/data/hatchling_patch.diff
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
diff --git a/src/hatchling/build.py b/src/hatchling/build.py
index d79c1e2e..c85a837e 100644
--- a/src/hatchling/build.py
+++ b/src/hatchling/build.py
@@ -1,6 +1,20 @@
import os


+def _write_pynixify_files(config_settings, deps):
+ if config_settings is not None and "PYNIXIFY_OUT" in config_settings:
+ from pathlib import Path
+ import json
+ pynix_out = Path(config_settings['PYNIXIFY_OUT'])
+ for target in ("tests", "setup", "install"):
+ fp = (pynix_out / ("%s_requires.txt" % target)).open("w")
+ fp.write('\n'.join([str(req) for req in deps]))
+ fp.write('\nhatchling\nhatch-vcs')
+ fp.close()
+ with (pynix_out / 'meta.json').open('w') as fp:
+ json.dump({"version": None, "url": None, "license": None, "description": None}, fp)
+
+
def get_requires_for_build_sdist(config_settings=None):
"""
https://peps.python.org/pep-0517/#get-requires-for-build-sdist
@@ -8,6 +22,7 @@ def get_requires_for_build_sdist(config_settings=None):
from hatchling.builders.sdist import SdistBuilder

builder = SdistBuilder(os.getcwd())
+ _write_pynixify_files(config_settings, builder.config.dependencies)
return builder.config.dependencies


@@ -18,6 +33,7 @@ def build_sdist(sdist_directory, config_settings=None):
from hatchling.builders.sdist import SdistBuilder

builder = SdistBuilder(os.getcwd())
+ _write_pynixify_files(config_settings, builder.config.dependencies)
return os.path.basename(next(builder.build(sdist_directory, ['standard'])))


@@ -28,6 +44,7 @@ def get_requires_for_build_wheel(config_settings=None):
from hatchling.builders.wheel import WheelBuilder

builder = WheelBuilder(os.getcwd())
+ _write_pynixify_files(config_settings, builder.config.dependencies)
return builder.config.dependencies


@@ -38,6 +55,7 @@ def build_wheel(wheel_directory, config_settings=None, metadata_directory=None):
from hatchling.builders.wheel import WheelBuilder

builder = WheelBuilder(os.getcwd())
+ _write_pynixify_files(config_settings, builder.config.dependencies)
return os.path.basename(next(builder.build(wheel_directory, ['standard'])))


@@ -48,6 +66,7 @@ def get_requires_for_build_editable(config_settings=None):
from hatchling.builders.wheel import WheelBuilder

builder = WheelBuilder(os.getcwd())
+ _write_pynixify_files(config_settings, builder.config.dependencies)
return builder.config.dependencies


@@ -58,6 +77,7 @@ def build_editable(wheel_directory, config_settings=None, metadata_directory=Non
from hatchling.builders.wheel import WheelBuilder

builder = WheelBuilder(os.getcwd())
+ _write_pynixify_files(config_settings, builder.config.dependencies)
return os.path.basename(next(builder.build(wheel_directory, ['editable'])))


@@ -89,6 +109,7 @@ if 'PIP_BUILD_TRACKER' not in os.environ:

with open(os.path.join(directory, 'METADATA'), 'w', encoding='utf-8') as f:
f.write(builder.config.core_metadata_constructor(builder.metadata))
+ _write_pynixify_files(config_settings, builder.config.dependencies)

return os.path.basename(directory)

@@ -110,5 +131,6 @@ if 'PIP_BUILD_TRACKER' not in os.environ:

with open(os.path.join(directory, 'METADATA'), 'w', encoding='utf-8') as f:
f.write(builder.config.core_metadata_constructor(builder.metadata, extra_dependencies=extra_dependencies))
+ _write_pynixify_files(config_settings, builder.config.dependencies)

return os.path.basename(directory)
9 changes: 5 additions & 4 deletions pynixify/data/old_setuptools_patch.diff
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ diff --git a/setuptools/__init__.py b/setuptools/__init__.py
index 83882511..259effd5 100644
--- a/setuptools/__init__.py
+++ b/setuptools/__init__.py
@@ -155,14 +155,63 @@ def _install_setup_requires(attrs):
@@ -155,14 +155,64 @@ def _install_setup_requires(attrs):

# Honor setup.cfg's options.
dist.parse_config_files(ignore_option_errors=True)
- if dist.setup_requires:
Expand Down Expand Up @@ -56,6 +56,7 @@ index 83882511..259effd5 100644
+ meta_attrs = {'description', 'url', 'license', 'version'}
+ for meta_attr in meta_attrs:
+ meta[meta_attr] = attrs.get(meta_attr)
+ meta['_fmt'] = 'setuptools'
+ with (out / 'meta.json').open('w') as fp:
+ json.dump(meta, fp)
+ else:
Expand All @@ -69,6 +70,6 @@ index 83882511..259effd5 100644
- return distutils.core.setup(**attrs)
+ if 'PYNIXIFY' not in os.environ:
+ return distutils.core.setup(**attrs)


setup.__doc__ = distutils.core.setup.__doc__
93 changes: 89 additions & 4 deletions pynixify/data/parse_setuppy_data.nix
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{ file, stdenv ? (import <nixpkgs> { }).stdenv, lib ? (import <nixpkgs> { }).lib
, unzip ? (import <nixpkgs> { }).unzip, python ? (import <nixpkgs> { }).python3
, git ? (import <nixpkgs> { }).git, fetchFromGitLab ? (import <nixpkgs> { }).fetchFromGitLab
}:

let
Expand All @@ -21,8 +22,88 @@ let
];

});
setuptoolsscm = python.pkgs.buildPythonPackage rec {
pname = "setuptools-scm";
version = "7.0.5";

pythonWithPackages = python.withPackages (ps: [ patchedSetuptools ]);
src = python.pkgs.fetchPypi {
pname = "setuptools_scm";
inherit version;
sha256 = "sha256-Ax4Tr3cdb4krlBrbbqBFRbv5Hrxc5ox4qvP/9uH7SEQ=";
};

propagatedBuildInputs = [
python.pkgs.packaging
python.pkgs.typing-extensions
python.pkgs.tomli
patchedSetuptools
];

pythonImportsCheck = [ "setuptools_scm" ];

# check in passthru.tests.pytest to escape infinite recursion on pytest
doCheck = false;
};
hatchling = python.pkgs.hatchling.overrideAttrs
(ps: { patches = [ ./hatchling_patch.diff ]; });
hatchvcs = python.pkgs.buildPythonPackage rec {
pname = "hatch-vcs";
version = "0.2.0";
format = "pyproject";

disabled = python.pkgs.pythonOlder "3.7";

src = python.pkgs.fetchPypi {
pname = "hatch_vcs";
inherit version;
sha256 = "sha256-mRPXM7NO7JuwNF0GJsoyFlpK0t4V0c5kPDbQnKkIq/8=";
};

nativeBuildInputs = [ hatchling ];

propagatedBuildInputs = [ hatchling setuptoolsscm ];

checkInputs = [ git python.pkgs.pytestCheckHook ];

disabledTests = [
# incompatible with setuptools-scm>=7
# https://github.com/ofek/hatch-vcs/issues/8
"test_write"
];

pythonImportsCheck = [ "hatch_vcs" ];
};
patchedflitcore = python.pkgs.flit-core.overrideAttrs
(ps: { patches = [ ./flitcore_patch.diff ]; });
flitscm = python.pkgs.buildPythonPackage rec {
pname = "flit-scm";
version = "1.7.0";

format = "pyproject";

src = fetchFromGitLab {
owner = "WillDaSilva";
repo = "flit_scm";
rev = version;
sha256 = "sha256-K5sH+oHgX/ftvhkY+vIg6wUokAP96YxrTWds3tnEtyg=";
leaveDotGit = true;
};

nativeBuildInputs =
[ patchedflitcore setuptoolsscm python.pkgs.tomli git ];
propagatedBuildInputs = [ patchedflitcore setuptoolsscm ]
++ lib.optionals (python.pkgs.pythonOlder "3.11")
[ python.pkgs.tomli ];
};

pythonWithPackages = python.withPackages (ps: [
patchedSetuptools
setuptoolsscm
hatchling
hatchvcs
flitscm
python.pkgs.pip
]);

cleanSource = src:
lib.cleanSourceWith {
Expand All @@ -43,10 +124,14 @@ in stdenv.mkDerivation {
'';
buildPhase = ''
mkdir -p $out
if ! PYNIXIFY=1 python setup.py install; then
# Indicate that fetching the result failed, but let the build succeed
touch $out/failed
if PYNIXIFY=1 python setup.py install; then
exit 0
fi
if pip --no-cache-dir wheel --config-settings PYNIXIFY_OUT=$out --no-build-isolation $PWD; then
exit 0
fi
# Indicate that fetching the result failed, but let the build succeed
touch $out/failed
'';
dontInstall = true;
}
Expand Down
9 changes: 5 additions & 4 deletions pynixify/data/setuptools_patch.diff
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ diff --git a/setuptools/__init__.py b/setuptools/__init__.py
index 89f6f06e..2d772eed 100644
--- a/setuptools/__init__.py
+++ b/setuptools/__init__.py
@@ -76,36 +76,64 @@ def _install_setup_requires(attrs):
@@ -76,36 +76,65 @@ def _install_setup_requires(attrs):

# Honor setup.cfg's options.
dist.parse_config_files(ignore_option_errors=True)
- if dist.setup_requires:
Expand Down Expand Up @@ -77,6 +77,7 @@ index 89f6f06e..2d772eed 100644
+ meta_attrs = {'description', 'url', 'license', 'version'}
+ for meta_attr in meta_attrs:
+ meta[meta_attr] = attrs.get(meta_attr)
+ meta['_fmt'] = 'setuptools'
+ with (out / 'meta.json').open('w') as fp:
+ json.dump(meta, fp)
+ else:
Expand All @@ -91,6 +92,6 @@ index 89f6f06e..2d772eed 100644
- return distutils.core.setup(**attrs)
+ if 'PYNIXIFY' not in os.environ:
+ return distutils.core.setup(**attrs)


setup.__doc__ = distutils.core.setup.__doc__
1 change: 1 addition & 0 deletions pynixify/expression_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
buildPythonPackage rec {
pname = ${package.pypi_name | nix};
version = ${version | nix};
format = ${metadata._fmt | nix};

% if package.local_source:
src = lib.cleanSource ../../..;
Expand Down