aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--patchtree/cli.py13
-rw-r--r--patchtree/config.py20
-rw-r--r--patchtree/context.py27
3 files changed, 50 insertions, 10 deletions
diff --git a/patchtree/cli.py b/patchtree/cli.py
index 2535256..8e923dd 100644
--- a/patchtree/cli.py
+++ b/patchtree/cli.py
@@ -39,6 +39,12 @@ def parse_arguments(config: Config) -> Context:
help="lines of context in output diff",
type=int,
)
+ parser.add_argument(
+ "-s",
+ "--shebang",
+ help="output shebang in resulting patch",
+ action="store_true",
+ )
parser.add_argument("target", help="target directory or archive")
parser.add_argument("patch", help="patch input glob(s)", nargs="+")
@@ -47,8 +53,11 @@ def parse_arguments(config: Config) -> Context:
if options.context is not None:
config.diff_context = options.context
+ if options.shebang:
+ config.output_shebang = True
+
try:
- return config.context(options)
+ return config.context(config, options)
except Exception as e:
parser.error(str(e))
@@ -70,7 +79,7 @@ def main():
print("no files to patch!", file=stderr)
return 0
- config.header(context)
+ config.header(config, context)
for file in files:
patch = config.patch(config, file)
diff --git a/patchtree/config.py b/patchtree/config.py
index 743307b..196ecb1 100644
--- a/patchtree/config.py
+++ b/patchtree/config.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
from dataclasses import dataclass, field
from argparse import ArgumentParser
from importlib import metadata
@@ -21,17 +23,32 @@ DEFAULT_DIFFS: dict[str, type[Diff]] = {
class Header:
+ config: Config
context: Context
+
name = "patchtree"
license = None
- def __init__(self, context: Context):
+ def __init__(self, config: Config, context: Context):
+ self.config = config
self.context = context
+ self.write_shebang()
self.write_version()
self.write_version_extra()
self.write_license()
+ def write_shebang(self):
+ if not self.config.output_shebang:
+ return
+ cmd = [
+ "/usr/bin/env",
+ "-S",
+ *self.context.get_apply_cmd(),
+ ]
+ cmdline = " ".join(cmd)
+ self.context.output.write(f"#!{cmdline}\n")
+
def write_version(self):
version = metadata.version("patchtree")
self.context.output.write(f"{self.name} output (version {version})\n")
@@ -59,6 +76,7 @@ class Config:
)
header: type[Header] = Header
diff_context: int = 3
+ output_shebang: bool = False
def __post_init__(self):
self.processors = {**DEFAULT_PROCESSORS, **self.processors}
diff --git a/patchtree/context.py b/patchtree/context.py
index 554d09e..0ff769a 100644
--- a/patchtree/context.py
+++ b/patchtree/context.py
@@ -1,5 +1,7 @@
+from __future__ import annotations
+from typing import TYPE_CHECKING, IO, cast
+
from argparse import Namespace
-from typing import IO, cast
from pathlib import Path
from zipfile import ZipInfo, is_zipfile
from tempfile import TemporaryFile
@@ -9,6 +11,9 @@ from subprocess import run
from zipfile import ZipFile
from stat import S_IFDIR, S_IFREG
+if TYPE_CHECKING:
+ from .config import Config
+
ZIP_CREATE_SYSTEM_UNX = 3
@@ -107,10 +112,14 @@ class ZipFS(FS):
class Context:
fs: FS
output: IO
+
+ config: Config
options: Namespace
- def __init__(self, options: Namespace):
+ def __init__(self, config: Config, options: Namespace):
+ self.config = config
self.options = options
+
self.fs = self.get_fs()
self.output = self.get_output()
@@ -166,16 +175,20 @@ class Context:
return stdout
- def apply(self, reverse: bool) -> None:
- location = cast(DiskFS, self.fs).path
- cache = location.joinpath(".patchtree.diff")
-
+ def get_apply_cmd(self) -> list[str]:
cmd = [
"git",
"apply",
- "--unidiff-zero",
"--allow-empty",
]
+ if self.config.diff_context == 0:
+ cmd.append("--unidiff-zero")
+ return cmd
+
+ def apply(self, reverse: bool) -> None:
+ location = cast(DiskFS, self.fs).path
+ cache = location.joinpath(".patchtree.diff")
+ cmd = self.get_apply_cmd()
if reverse:
if not cache.exists():