github.com/anchore/syft@v1.38.2/.github/scripts/fingerprint_docker_fixtures.py (about)

     1  #!/usr/bin/env python3
     2  
     3  import os
     4  import subprocess
     5  import hashlib
     6  
     7  BOLD = '\033[1m'
     8  YELLOW = '\033[0;33m'
     9  RESET = '\033[0m'
    10  
    11  
    12  def print_message(message):
    13      print(f"{YELLOW}{message}{RESET}")
    14  
    15  
    16  def sha256sum(filepath):
    17      h = hashlib.sha256()
    18      with open(filepath, 'rb') as f:
    19          for chunk in iter(lambda: f.read(4096), b""):
    20              h.update(chunk)
    21      return h.hexdigest()
    22  
    23  
    24  def is_git_tracked_or_untracked(directory):
    25      """Returns a sorted list of files in the directory that are tracked or not ignored by Git."""
    26      result = subprocess.run(
    27          ["git", "ls-files", "--cached", "--others", "--exclude-standard"],
    28          cwd=directory,
    29          stdout=subprocess.PIPE,
    30          text=True
    31      )
    32      return sorted(result.stdout.strip().splitlines())
    33  
    34  
    35  def find_test_fixture_dirs_with_images(base_dir):
    36      """Find directories that contain 'test-fixtures' and at least one 'image-*' directory."""
    37      for root, dirs, files in os.walk(base_dir):
    38          if 'test-fixtures' in root:
    39              image_dirs = [d for d in dirs if d.startswith('image-')]
    40              if image_dirs:
    41                  yield os.path.realpath(root)
    42  
    43  
    44  def generate_fingerprints():
    45      print_message("creating fingerprint files for docker fixtures...")
    46  
    47      for test_fixture_dir in find_test_fixture_dirs_with_images('.'):
    48          cache_fingerprint_path = os.path.join(test_fixture_dir, 'cache.fingerprint')
    49  
    50          with open(cache_fingerprint_path, 'w') as fingerprint_file:
    51              for image_dir in find_image_dirs(test_fixture_dir):
    52                  for file in is_git_tracked_or_untracked(image_dir):
    53                      file_path = os.path.join(image_dir, file)
    54                      checksum = sha256sum(file_path)
    55                      path_from_fixture_dir = os.path.relpath(file_path, test_fixture_dir)
    56                      fingerprint_file.write(f"{checksum}  {path_from_fixture_dir}\n")
    57  
    58  
    59  def find_image_dirs(test_fixture_dir):
    60      """Find all 'image-*' directories inside a given test-fixture directory."""
    61      result = []
    62      for root, dirs, files in os.walk(test_fixture_dir):
    63          for dir_name in dirs:
    64              if dir_name.startswith('image-'):
    65                  result.append(os.path.join(root, dir_name))
    66      return sorted(result)
    67  
    68  
    69  if __name__ == "__main__":
    70      generate_fingerprints()