text: #!/usr/bin/env python3
  from pathlib import Path
  import sys
  import argparse
  from collections import defaultdict
  
  from esphome.helpers import write_file_if_changed
  from esphome.config import get_component, get_platform
  from esphome.core import CORE
  
  parser = argparse.ArgumentParser()
  parser.add_argument(
      "--check", help="Check if the CODEOWNERS file is up to date.", action="store_true"
  )
  args = parser.parse_args()
  
  # The root directory of the repo
  root = Path(__file__).parent.parent
  components_dir = root / "esphome" / "components"
  
  BASE = """
  # This file is generated by script/build_codeowners.py
  # People marked here will be automatically requested for a review
  # when the code that they own is touched.
  #
  # Every time an issue is created with a label corresponding to an integration,
  # the integration's code owner is automatically notified.
  
  # Core Code
  setup.py @esphome/core
  esphome/*.py @esphome/core
  esphome/core/* @esphome/core
  
  # Integrations
  """.strip()
  
  parts = [BASE]
  
  # Fake some directory so that get_component works
  CORE.config_path = str(root)
  
  codeowners = defaultdict(list)
  
  for path in components_dir.iterdir():
      if not path.is_dir():
          continue
      if not (path / "__init__.py").is_file():
          continue
  
      name = path.name
      comp = get_component(name)
      if comp is None:
          print(
              f"Cannot find component {name}. Make sure current path is pip installed ESPHome"
          )
          sys.exit(1)
  
      codeowners[f"esphome/components/{name}/*"].extend(comp.codeowners)
  
      for platform_path in path.iterdir():
          platform_name = platform_path.stem
          platform = get_platform(platform_name, name)
          if platform is None:
              continue
  
          if platform_path.is_dir():
              # Sub foldered platforms get their own line
              if not (platform_path / "__init__.py").is_file():
                  continue
              codeowners[f"esphome/components/{name}/{platform_name}/*"].extend(
                  platform.codeowners
              )
              continue
  
          # Non-subfoldered platforms add to codeowners at component level
          if not platform_path.is_file() or platform_path.name == "__init__.py":
              continue
          codeowners[f"esphome/components/{name}/*"].extend(platform.codeowners)
  
  
  for path, owners in sorted(codeowners.items()):
      owners = sorted(set(owners))
      if not owners:
          continue
      for owner in owners:
          if not owner.startswith("@"):
              print(
                  f"Codeowner {owner} for integration {path} must start with an '@' symbol!"
              )
              sys.exit(1)
      parts.append(f"{path} {' '.join(owners)}")
  
  
  # End newline
  parts.append("")
  content = "\n".join(parts)
  codeowners_file = root / "CODEOWNERS"
  
  if args.check:
      if codeowners_file.read_text() != content:
          print("CODEOWNERS file is not up to date.")
          print("Please run `script/build_codeowners.py`")
          sys.exit(1)
      print("CODEOWNERS file is up to date")
  else:
      write_file_if_changed(codeowners_file, content)
      print("Wrote CODEOWNERS")
  