makepatch 0.2.1__py3-none-any.whl → 0.2.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -13,15 +13,14 @@ if __debug__ and __import__("typing").TYPE_CHECKING:
13
13
 
14
14
  @final
15
15
  class PatchApplier:
16
- if __debug__ and __import__("typing").TYPE_CHECKING:
17
- __slots__ = (
18
- "__config",
19
- "__excludes",
20
- "__excludes_dev",
21
- "__patches",
22
- "__src",
23
- "__sources",
24
- )
16
+ __slots__ = (
17
+ "__config",
18
+ "__excludes",
19
+ "__excludes_dev",
20
+ "__patches",
21
+ "__sources",
22
+ "__src",
23
+ )
25
24
 
26
25
  def __init__(self, config: PatcherConfig, /) -> None:
27
26
  self.__config: Final = config
@@ -35,6 +34,9 @@ class PatchApplier:
35
34
  self.__src: Path | None = None
36
35
  self.__sources: Path | None = None
37
36
 
37
+ def has_sdist_cache(self, /):
38
+ return (self.__config.project_root / "src" / self.__config.module_name).resolve().exists()
39
+
38
40
  def setup_required(self, /):
39
41
  return not (self.__config.project_root / "work/patched").resolve().exists()
40
42
 
makepatch/hooks/_patch.py CHANGED
@@ -1,60 +1,66 @@
1
- from typing import override
2
-
3
- from hatchling.builders.hooks.plugin.interface import BuildHookInterface
4
-
5
- import shutil
6
-
7
- from makepatch._config import PatcherConfig
8
- from makepatch.core import PatchApplier
9
-
10
- if __debug__ and __import__("typing").TYPE_CHECKING:
11
- from typing import Any, Final
12
-
13
-
14
- class PatcherBuildHook(BuildHookInterface):
15
- PLUGIN_NAME = "makepatch"
16
-
17
- def __init__(self, /, *args, **kwargs):
18
- super().__init__(*args, **kwargs)
19
- self.__config: Final = PatcherConfig.from_hatch(self)
20
- self.__patcher: Final = PatchApplier(self.__config)
21
-
22
- @override
23
- def initialize(self, version: str, build_data: dict[str, Any]) -> None:
24
- config = self.__config
25
- patcher = self.__patcher
26
-
27
- if patcher.setup_required():
28
- patcher.resolve_sources()
29
- patcher.resolve_src()
30
-
31
- dst = config.project_root / "work/patched"
32
- if dst.exists():
33
- if not dst.is_dir(): raise RuntimeError(f"{dst} is not a directory")
34
- shutil.rmtree(dst)
35
- dst.mkdir(parents=True)
36
-
37
- patcher.copy(dst)
38
- patcher.apply(dst / config.module_source)
39
- self.__success = False
40
- return
41
-
42
- patcher.resolve_src()
43
-
44
- dst = self.__dst = config.project_root / "src" / config.module_name
45
- if dst.exists():
46
- if not dst.is_dir(): raise RuntimeError(f"{dst} is not a directory")
47
- shutil.rmtree(dst)
48
- dst.mkdir(parents=True)
49
-
50
- patcher.copy(dst)
51
- self.__success = patcher.apply(dst)
52
-
53
- @override
54
- def finalize(self, version: str, build_data: dict[str, Any], artifact_path: str) -> None:
55
- if not self.__success:
56
- return
57
-
58
- if not self.__dst.exists() or not self.__dst.is_dir():
59
- raise RuntimeError(f"{self.__dst} does not exists or is not a directory")
60
- shutil.rmtree(self.__dst)
1
+ import shutil
2
+ from typing import override
3
+
4
+ from hatchling.builders.hooks.plugin.interface import BuildHookInterface
5
+
6
+ from makepatch._config import PatcherConfig
7
+ from makepatch.core import PatchApplier
8
+
9
+ if __debug__ and __import__("typing").TYPE_CHECKING:
10
+ from typing import Any, Final
11
+
12
+
13
+ class PatcherBuildHook(BuildHookInterface):
14
+ PLUGIN_NAME = "makepatch"
15
+
16
+ def __init__(self, /, *args, **kwargs):
17
+ super().__init__(*args, **kwargs)
18
+ self.__success = None
19
+ self.__config: Final[PatcherConfig] = PatcherConfig.from_hatch(self)
20
+ self.__patcher: Final = PatchApplier(self.__config)
21
+
22
+ @override
23
+ def initialize(self, version: str, build_data: dict[str, Any]) -> None:
24
+ config = self.__config
25
+ patcher = self.__patcher
26
+
27
+ if patcher.has_sdist_cache():
28
+ dst = self.__dst = config.project_root / "src" / config.module_name
29
+ build_data["force_include"][str(dst)] = dst.name
30
+ return
31
+
32
+ if patcher.setup_required():
33
+ patcher.resolve_sources()
34
+ patcher.resolve_src()
35
+
36
+ dst = config.project_root / "work/patched"
37
+ if dst.exists():
38
+ if not dst.is_dir(): raise RuntimeError(f"{dst} is not a directory")
39
+ shutil.rmtree(dst)
40
+ dst.mkdir(parents=True)
41
+
42
+ patcher.copy(dst)
43
+ patcher.apply(dst / config.module_source)
44
+ self.__success = False
45
+ return
46
+
47
+ patcher.resolve_src()
48
+
49
+ dst = self.__dst = config.project_root / "src" / config.module_name
50
+ if dst.exists():
51
+ if not dst.is_dir(): raise RuntimeError(f"{dst} is not a directory")
52
+ shutil.rmtree(dst)
53
+ dst.mkdir(parents=True)
54
+
55
+ patcher.copy(dst)
56
+ self.__success = patcher.apply(dst)
57
+ build_data["force_include"][str(dst)] = f"src/{dst.name}"
58
+
59
+ @override
60
+ def finalize(self, version: str, build_data: dict[str, Any], artifact_path: str) -> None:
61
+ if not self.__success:
62
+ return
63
+
64
+ if not self.__dst.exists() or not self.__dst.is_dir():
65
+ raise RuntimeError(f"{self.__dst} does not exists or is not a directory")
66
+ shutil.rmtree(self.__dst)
@@ -1,16 +1,17 @@
1
1
  import shutil
2
+ import sys
2
3
  from pathlib import Path
3
4
 
4
5
  from makepatch._config import PatcherConfig
5
6
  from makepatch.core import PatchApplier
6
7
 
8
+ from ._rebuild import rebuild_patches
9
+
7
10
  if __debug__ and __import__("typing").TYPE_CHECKING:
8
11
  from typing import Final
9
12
 
10
13
 
11
- from ._rebuild import rebuild_patches
12
-
13
- def init_patches():
14
+ def apply_patches():
14
15
  root: Final = Path(__import__("os").getcwd())
15
16
  config: Final = PatcherConfig.from_pyproject(root)
16
17
  patcher: Final = PatchApplier(config)
@@ -25,4 +26,7 @@ def init_patches():
25
26
  dst.mkdir(parents=True)
26
27
 
27
28
  patcher.copy(dst)
28
- exit(not patcher.apply(dst / config.module_source))
29
+ sys.exit(not patcher.apply(dst / config.module_source))
30
+
31
+
32
+ __all__ = "apply_patches", "rebuild_patches"
@@ -0,0 +1,74 @@
1
+ Metadata-Version: 2.4
2
+ Name: makepatch
3
+ Version: 0.2.6
4
+ Summary: Hatch build hook to easily hard-fork packages with patches!
5
+ Project-URL: source, https://github.com/AlphaKR93/packages/tree/main/python/makepatch
6
+ Project-URL: issues, https://github.com/AlphaKR93/packages/issues
7
+ Project-URL: changelogs, https://github.com/AlphaKR93/packages/blob/main/python/makepatch/CHANGELOG.md
8
+ Author-email: Alpha <dev@alpha93.kr>
9
+ License-Expression: MIT
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Environment :: Console
12
+ Classifier: Environment :: Plugins
13
+ Classifier: Framework :: Hatch
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Programming Language :: Python
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Programming Language :: Python :: 3.14
19
+ Classifier: Programming Language :: Python :: Implementation :: CPython
20
+ Classifier: Topic :: Software Development :: Build Tools
21
+ Requires-Python: >=3.10
22
+ Requires-Dist: hatchling>=1.29.0
23
+ Requires-Dist: pydantic>=2.13.0
24
+ Requires-Dist: typing-extensions>=4.15.0; python_version < '3.15'
25
+ Description-Content-Type: text/markdown
26
+
27
+ # makepatch
28
+
29
+ Hatchling build hook that helps developers freely modify and build Python
30
+ packages through patches, like [`pnpm patch`](https://pnpm.io/cli/patch).
31
+
32
+ > [!WARN]
33
+ > This package was developed for personal use and is still unstable and poorly
34
+ > developed. Only confirmed to work with `uv`. PRs are welcome.
35
+
36
+ ## Usage
37
+
38
+ > [!IMPORTANT]
39
+ > Patching installed packages is not yet supported. To patch a package, you must
40
+ > create a separate project (recommend using workspace).
41
+
42
+ To include patched packages automatically during the build, you need to add
43
+ `makepatch` to `build-system` and register the hook as follows:
44
+ ```toml pyproject.toml
45
+ [build-system]
46
+ requires = ["hatchling", "makepatch"]
47
+ build-backend = "hatchling.build"
48
+
49
+ [tool.hatch.build.hooks.makepatch.options]
50
+ # Add options here
51
+ ```
52
+
53
+ - To initialize the patch development environment, run the following command: <br/>
54
+ `uv run apply-patches` <br/>
55
+ This will create a patched source in `work/patched`.
56
+ - To create a patch file with modifications to `work/patched`, run the following
57
+ command: <br/>
58
+ `uv run rebuild-patches`
59
+
60
+ ### Configuration
61
+
62
+ ```toml pyproject.toml
63
+ [tool.hatch.build.hooks.makepatch.options]
64
+ module-source = "path of the actual package relative to `work/sources` (e.g., `src/mcp`)"
65
+ excludes = [
66
+ # Files to exclude within `module-source`
67
+ # DO NOT delete files from `work/patched`, you must exclude it from there
68
+ ]
69
+ dev-excludes = [
70
+ # Files to exclude when copied from `work/sources` to `work/patched`
71
+ # does not affect build results and only for reducing copy time and storage usage.
72
+ # will be changed to only copy `module-source` in the future.
73
+ ]
74
+ ```
@@ -4,12 +4,12 @@ makepatch/_config.py,sha256=OA0SPKb8R5Q00cs6DwDu79kN6gW8vnDrKGvp6DCUfG8,2492
4
4
  makepatch/_types/__init__.pyi,sha256=SlDWSyq8IncNQKcgvjc9F7jyqKjTCSLW4HLTxgsSYcM,39
5
5
  makepatch/_types/hatch.pyi,sha256=MWAwNXZx1RXrdZ8sVLY8pinoOleSajjDatylnFsLprQ,1604
6
6
  makepatch/core/__init__.py,sha256=F943qvL-FwY0zkSuMxHuVzG55EVDICJYouAE1-3NrOU,36
7
- makepatch/core/_patcher.py,sha256=m5IsO66AC40i7rpHH1y5PE5VFW390svgZxA4SIw1930,4403
7
+ makepatch/core/_patcher.py,sha256=QEyFHQ6yK9BjhpjmBfGob1qRISlBYeByQsr-zTBLzfQ,4450
8
8
  makepatch/hooks/__init__.py,sha256=I7QNThkPOzPtvQiocyUoQKKdWNYWk5wiF-FVRz4LTjo,38
9
- makepatch/hooks/_patch.py,sha256=kSuzOjyeYTWEO457e5ikZI5RN8KGn22n5BVQEj1GOL8,1971
10
- makepatch/scripts/__init__.py,sha256=dggERiHtxr-wWJ6sHvfsfW3a9a3Io3CmNd7xvIC5AnY,769
9
+ makepatch/hooks/_patch.py,sha256=yQwK7p-t6B7Vb5WOO6VoYsQ9HA0fFl0cD10S9aZMdeM,2220
10
+ makepatch/scripts/__init__.py,sha256=gEBpdkVqJeobmUbDLkXCfMUJ0B3S2Ml2TWAmIP_uK84,836
11
11
  makepatch/scripts/_rebuild.py,sha256=iisw0dza8cr4o_FBvzcrNGmxeeje98XW2g6dHlJqsJ0,2810
12
- makepatch-0.2.1.dist-info/METADATA,sha256=PlXbLpB-5oDxPzFot3QArchKvlYLOcawiUvuedpnZpc,1003
13
- makepatch-0.2.1.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
14
- makepatch-0.2.1.dist-info/entry_points.txt,sha256=tDk_T8AJNcjy0KhBEXxf9wZBIAhv3l4pGekKOqXpNpY,159
15
- makepatch-0.2.1.dist-info/RECORD,,
12
+ makepatch-0.2.6.dist-info/METADATA,sha256=AnjknGQleRWHrkB_BILk7rqZl40dDEmqWHziaye2two,2804
13
+ makepatch-0.2.6.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
14
+ makepatch-0.2.6.dist-info/entry_points.txt,sha256=tDk_T8AJNcjy0KhBEXxf9wZBIAhv3l4pGekKOqXpNpY,159
15
+ makepatch-0.2.6.dist-info/RECORD,,
@@ -1,23 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: makepatch
3
- Version: 0.2.1
4
- Summary: Hatch build hook to easily hard-fork packages with patches!
5
- Project-URL: source, https://github.com/AlphaKR93/packages/tree/main/python/makepatch
6
- Project-URL: issues, https://github.com/AlphaKR93/packages/issues
7
- Author-email: Alpha <dev@alpha93.kr>
8
- License-Expression: MIT
9
- Classifier: Development Status :: 4 - Beta
10
- Classifier: Environment :: Console
11
- Classifier: Environment :: Plugins
12
- Classifier: Framework :: Hatch
13
- Classifier: Intended Audience :: Developers
14
- Classifier: Programming Language :: Python
15
- Classifier: Programming Language :: Python :: 3.12
16
- Classifier: Programming Language :: Python :: 3.13
17
- Classifier: Programming Language :: Python :: 3.14
18
- Classifier: Programming Language :: Python :: Implementation :: CPython
19
- Classifier: Topic :: Software Development :: Build Tools
20
- Requires-Python: >=3.12
21
- Requires-Dist: hatchling>=1.29.0
22
- Requires-Dist: pydantic>=2.13.0
23
- Requires-Dist: typing-extensions>=4.15.0; python_version < '3.15'