Skip to content

Commit a8230bd

Browse files
authored
Merge pull request #247 from fosslight/git
Fix a bug that causes github's login prompt to be activated
2 parents a10fbca + 7a84e2d commit a8230bd

1 file changed

Lines changed: 83 additions & 19 deletions

File tree

src/fosslight_util/download.py

Lines changed: 83 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import logging
1111
import argparse
1212
import shutil
13-
from git import Repo, GitCommandError, Git
13+
from git import Git
1414
import bz2
1515
import contextlib
1616
from datetime import datetime
@@ -217,7 +217,19 @@ def get_remote_refs(git_url: str):
217217
tags = []
218218
branches = []
219219
try:
220-
cp = subprocess.run(["git", "ls-remote", "--tags", "--heads", git_url], capture_output=True, text=True, timeout=30)
220+
env = os.environ.copy()
221+
env["GIT_TERMINAL_PROMPT"] = "0"
222+
env["GIT_ASKPASS"] = "echo"
223+
env["GIT_CREDENTIAL_HELPER"] = ""
224+
if "GIT_SSH_COMMAND" not in env:
225+
env["GIT_SSH_COMMAND"] = "ssh -o BatchMode=yes -o StrictHostKeyChecking=no"
226+
else:
227+
env["GIT_SSH_COMMAND"] = env["GIT_SSH_COMMAND"] + " -o BatchMode=yes"
228+
cp = subprocess.run(
229+
["git", "-c", "credential.helper=", "-c", "credential.helper=!",
230+
"ls-remote", "--tags", "--heads", git_url],
231+
env=env, capture_output=True, text=True, timeout=30,
232+
stdin=subprocess.DEVNULL)
221233
if cp.returncode == 0:
222234
for line in cp.stdout.splitlines():
223235
parts = line.split('\t')
@@ -291,32 +303,84 @@ def download_git_repository(refs_to_checkout, git_url, target_dir, tag, called_c
291303

292304
logger.info(f"Download git url :{git_url}")
293305
env = os.environ.copy()
294-
if not called_cli:
295-
env["GIT_TERMINAL_PROMPT"] = "0"
306+
env["GIT_TERMINAL_PROMPT"] = "0"
307+
if platform.system() == "Windows":
308+
env["GIT_ASKPASS"] = "echo"
309+
else:
310+
env["GIT_ASKPASS"] = "/bin/echo"
311+
env["GIT_CREDENTIAL_HELPER"] = ""
312+
# Disable credential helper via config
313+
if "GIT_CONFIG_COUNT" not in env:
314+
env["GIT_CONFIG_COUNT"] = "1"
315+
env["GIT_CONFIG_KEY_0"] = "credential.helper"
316+
env["GIT_CONFIG_VALUE_0"] = ""
317+
if "GIT_SSH_COMMAND" not in env:
318+
env["GIT_SSH_COMMAND"] = "ssh -o BatchMode=yes -o StrictHostKeyChecking=no"
319+
else:
320+
env["GIT_SSH_COMMAND"] = env["GIT_SSH_COMMAND"] + " -o BatchMode=yes"
321+
296322
if refs_to_checkout:
297323
try:
298-
# gitPython uses the branch argument the same whether you check out to a branch or a tag.
299-
Repo.clone_from(git_url, target_dir, branch=refs_to_checkout, env=env)
300-
if any(Path(target_dir).iterdir()):
301-
success = True
302-
oss_version = refs_to_checkout
303-
logger.info(f"Files found in {target_dir} after clone.")
324+
# For tags, we need full history. For branches, shallow clone is possible but
325+
# we use full clone to ensure compatibility with all cases
326+
# Use subprocess to ensure environment variables are properly passed
327+
cmd = ["git", "-c", "credential.helper=", "-c", "credential.helper=!", "clone", git_url, target_dir]
328+
result = subprocess.run(cmd, env=env, capture_output=True, text=True, timeout=600, stdin=subprocess.DEVNULL)
329+
if result.returncode == 0:
330+
# Checkout the specific branch or tag
331+
checkout_cmd = ["git", "-C", target_dir, "checkout", refs_to_checkout]
332+
checkout_result = subprocess.run(
333+
checkout_cmd, env=env, capture_output=True, text=True,
334+
timeout=60, stdin=subprocess.DEVNULL)
335+
if checkout_result.returncode == 0:
336+
if any(Path(target_dir).iterdir()):
337+
success = True
338+
oss_version = refs_to_checkout
339+
logger.info(f"Files found in {target_dir} after clone and checkout.")
340+
else:
341+
logger.info(f"No files found in {target_dir} after clone.")
342+
success = False
343+
else:
344+
logger.info(f"Git checkout error: {checkout_result.stderr}")
345+
# Clone succeeded but checkout failed (e.g. non-existent ref):
346+
# repo has default branch; treat as success with empty version
347+
if any(Path(target_dir).iterdir()):
348+
success = True
349+
oss_version = ""
350+
logger.info("Checkout failed; keeping default branch.")
304351
else:
305-
logger.info(f"No files found in {target_dir} after clone.")
352+
logger.info(f"Git clone error: {result.stderr}")
306353
success = False
307-
except GitCommandError as error:
308-
logger.info(f"Git checkout error:{error}")
354+
except subprocess.TimeoutExpired:
355+
logger.info("Git clone timeout")
309356
success = False
310357
except Exception as e:
311-
logger.info(f"Repo.clone_from error:{e}")
358+
logger.info(f"Git clone error:{e}")
312359
success = False
313360

314361
if not success:
315-
Repo.clone_from(git_url, target_dir, env=env)
316-
if any(Path(target_dir).iterdir()):
317-
success = True
318-
else:
319-
logger.info(f"No files found in {target_dir} after clone.")
362+
try:
363+
# Use subprocess to ensure environment variables are properly passed
364+
# No checkout needed, so shallow clone is sufficient
365+
cmd = [
366+
"git", "-c", "credential.helper=", "-c", "credential.helper=!",
367+
"clone", "--depth", "1", git_url, target_dir
368+
]
369+
result = subprocess.run(cmd, env=env, capture_output=True, text=True, timeout=600, stdin=subprocess.DEVNULL)
370+
if result.returncode == 0:
371+
if any(Path(target_dir).iterdir()):
372+
success = True
373+
else:
374+
logger.info(f"No files found in {target_dir} after clone.")
375+
success = False
376+
else:
377+
logger.info(f"Git clone error: {result.stderr}")
378+
success = False
379+
except subprocess.TimeoutExpired:
380+
logger.info("Git clone timeout")
381+
success = False
382+
except Exception as e:
383+
logger.info(f"Git clone error:{e}")
320384
success = False
321385
return success, oss_version
322386

0 commit comments

Comments
 (0)