Browse Source

Add config support to SignatureVendor implementations

Jelmer Vernooij 4 tuần trước cách đây
mục cha
commit
f919687939
2 tập tin đã thay đổi với 67 bổ sung3 xóa
  1. 38 3
      dulwich/signature.py
  2. 29 0
      tests/test_signature.py

+ 38 - 3
dulwich/signature.py

@@ -21,11 +21,23 @@
 """Signature vendors for signing and verifying Git objects."""
 
 from collections.abc import Iterable
+from typing import TYPE_CHECKING
+
+if TYPE_CHECKING:
+    from dulwich.config import Config
 
 
 class SignatureVendor:
     """A signature implementation for signing and verifying Git objects."""
 
+    def __init__(self, config: "Config | None" = None) -> None:
+        """Initialize the signature vendor.
+
+        Args:
+          config: Optional Git configuration to use for settings like gpg.program
+        """
+        self.config = config
+
     def sign(self, data: bytes, keyid: str | None = None) -> bytes:
         """Sign data with a key.
 
@@ -61,6 +73,14 @@ class SignatureVendor:
 class GPGSignatureVendor(SignatureVendor):
     """Signature vendor that uses the GPG package for signing and verification."""
 
+    def __init__(self, config: "Config | None" = None) -> None:
+        """Initialize the GPG package vendor.
+
+        Args:
+          config: Optional Git configuration (currently unused by this vendor)
+        """
+        super().__init__(config)
+
     def sign(self, data: bytes, keyid: str | None = None) -> bytes:
         """Sign data with a GPG key.
 
@@ -129,13 +149,28 @@ class GPGSignatureVendor(SignatureVendor):
 class GPGCliSignatureVendor(SignatureVendor):
     """Signature vendor that uses the GPG command-line tool for signing and verification."""
 
-    def __init__(self, gpg_command: str = "gpg") -> None:
+    def __init__(
+        self, config: "Config | None" = None, gpg_command: str | None = None
+    ) -> None:
         """Initialize the GPG CLI vendor.
 
         Args:
-          gpg_command: Path to the GPG command (defaults to 'gpg')
+          config: Optional Git configuration to read gpg.program setting from
+          gpg_command: Path to the GPG command. If not specified, will try to
+                      read from config's gpg.program setting, or default to 'gpg'
         """
-        self.gpg_command = gpg_command
+        super().__init__(config)
+
+        if gpg_command is not None:
+            self.gpg_command = gpg_command
+        elif config is not None:
+            try:
+                gpg_program = config.get((b"gpg",), b"program")
+                self.gpg_command = gpg_program.decode("utf-8")
+            except KeyError:
+                self.gpg_command = "gpg"
+        else:
+            self.gpg_command = "gpg"
 
     def sign(self, data: bytes, keyid: str | None = None) -> bytes:
         """Sign data with a GPG key using the command-line tool.

+ 29 - 0
tests/test_signature.py

@@ -25,6 +25,7 @@ import shutil
 import subprocess
 import unittest
 
+from dulwich.config import ConfigDict
 from dulwich.signature import GPGCliSignatureVendor, GPGSignatureVendor, SignatureVendor
 
 try:
@@ -226,3 +227,31 @@ class GPGCliSignatureVendorTests(unittest.TestCase):
             self.assertIsInstance(signature, bytes)
         except subprocess.CalledProcessError as e:
             self.skipTest(f"GPG not available: {e}")
+
+    def test_gpg_program_from_config(self) -> None:
+        """Test reading gpg.program from config."""
+        # Create a config with gpg.program set
+        config = ConfigDict()
+        config.set((b"gpg",), b"program", b"gpg2")
+
+        vendor = GPGCliSignatureVendor(config=config)
+        self.assertEqual(vendor.gpg_command, "gpg2")
+
+    def test_gpg_program_override(self) -> None:
+        """Test that gpg_command parameter overrides config."""
+        config = ConfigDict()
+        config.set((b"gpg",), b"program", b"gpg2")
+
+        vendor = GPGCliSignatureVendor(config=config, gpg_command="gpg")
+        self.assertEqual(vendor.gpg_command, "gpg")
+
+    def test_gpg_program_default(self) -> None:
+        """Test default gpg command when no config provided."""
+        vendor = GPGCliSignatureVendor()
+        self.assertEqual(vendor.gpg_command, "gpg")
+
+    def test_gpg_program_default_when_not_in_config(self) -> None:
+        """Test default gpg command when config doesn't have gpg.program."""
+        config = ConfigDict()
+        vendor = GPGCliSignatureVendor(config=config)
+        self.assertEqual(vendor.gpg_command, "gpg")