Browse Source

fix:丢失内部层级文件匹配

tanjingyu 4 weeks ago
parent
commit
0c2867d417
1 changed files with 34 additions and 10 deletions
  1. 34 10
      app/services/gogs_client.py

+ 34 - 10
app/services/gogs_client.py

@@ -31,16 +31,40 @@ class GogsClient:
             return resp.json()
 
     async def get_recursive_tree(self, owner: str, repo: str, commit_id: str) -> dict:
-        """Get recursive tree."""
-        url = f"{self.base_url}/api/v1/repos/{owner}/{repo}/git/trees/{commit_id}?recursive=1"
-        try:
-            async with httpx.AsyncClient() as client:
-                resp = await client.get(url, headers=self.headers)
-                resp.raise_for_status()
-                return resp.json()
-        except httpx.HTTPStatusError as e:
-            logger.error(f"Failed to get recursive tree: {e}")
-            return {"tree": []}
+        """Get recursive tree by manually traversing subdirectories.
+
+        Gogs API doesn't support recursive parameter, so we need to
+        manually traverse each subdirectory.
+        """
+        all_items = []
+
+        async def fetch_tree(tree_sha: str, prefix: str = ""):
+            """Recursively fetch tree contents."""
+            url = f"{self.base_url}/api/v1/repos/{owner}/{repo}/git/trees/{tree_sha}"
+            try:
+                async with httpx.AsyncClient() as client:
+                    resp = await client.get(url, headers=self.headers)
+                    resp.raise_for_status()
+                    data = resp.json()
+
+                    for item in data.get("tree", []):
+                        # Build full path
+                        full_path = f"{prefix}{item['path']}" if prefix else item['path']
+                        item_copy = item.copy()
+                        item_copy['path'] = full_path
+                        all_items.append(item_copy)
+
+                        # Recursively fetch subdirectories
+                        if item['type'] == 'tree':
+                            await fetch_tree(item['sha'], f"{full_path}/")
+
+            except httpx.HTTPStatusError as e:
+                logger.error(f"Failed to get tree {tree_sha}: {e}")
+
+        # Start from the commit SHA
+        await fetch_tree(commit_id)
+
+        return {"tree": all_items}
 
     async def get_file_content(self, owner: str, repo: str, commit_id: str, file_path: str) -> bytes:
         """Download raw file content."""