appconnect_cli.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. #!/usr/bin/env sentry exec
  2. """Dumb CLI to experiment with our App Store Connect functionality.
  3. It contains several useful tools to manipulate the database during development. Exactly
  4. what it does can be easily changed based on new needs though, nothing is set in stone.
  5. Most actions assume you have only one App Store Connect source and will simply pick the
  6. first one found.
  7. """
  8. import sys
  9. from pprint import pprint
  10. import orjson
  11. from sentry.lang.native.appconnect import SYMBOL_SOURCES_PROP_NAME
  12. from sentry.models.appconnectbuilds import AppConnectBuild
  13. from sentry.models.project import Project
  14. from sentry.tasks import app_store_connect
  15. PROJECT_ID = 2
  16. def main(argv):
  17. if argv[0] == "dump-cfg":
  18. # Dumps the symbolSource configuration as stored in the project option.
  19. project = Project.objects.get(pk=PROJECT_ID)
  20. raw_config = project.get_option(SYMBOL_SOURCES_PROP_NAME, default="[]")
  21. config = orjson.loads(raw_config)
  22. pprint(config)
  23. elif argv[0] == "dsyms":
  24. # Start the dsym_download task for first config found (needs running workers).
  25. config = appconnect_config()
  26. app_store_connect.dsym_download(PROJECT_ID, config["id"])
  27. elif argv[0] == "zip":
  28. # "Uploads" DIFs into sentry from a zipfile passed as argument.
  29. project = Project.objects.get(pk=PROJECT_ID)
  30. app_store_connect.create_difs_from_dsyms_zip(argv[1], project)
  31. elif argv[0] == "dump-db":
  32. # Dumps (part of) the AppConnectBuild table.
  33. for build in AppConnectBuild.objects.all():
  34. print( # noqa: S002
  35. f"{build!r} app_id={build.app_id} bundle_id={build.bundle_id} platform={build.platform} version={build.bundle_short_version} build={build.bundle_version} fetched={build.fetched}"
  36. )
  37. elif argv[0] == "reset-fetched":
  38. # Resets the fetched state of the AppConnectBuild table, so dsym_download task will
  39. # process the entries again.
  40. for build in AppConnectBuild.objects.all():
  41. build.fetched = False
  42. build.save()
  43. elif argv[0] == "task":
  44. # Manually trigger the dsym_download task right now (needs running workers).
  45. config = appconnect_config()
  46. app_store_connect.dsym_download.apply_async(
  47. kwargs={"project_id": PROJECT_ID, "config_id": config["id"]}
  48. )
  49. else:
  50. raise ValueError("Unknown command")
  51. def appconnect_config():
  52. project = Project.objects.get(pk=PROJECT_ID)
  53. raw_config = project.get_option(SYMBOL_SOURCES_PROP_NAME, default="[]")
  54. symbol_sources = orjson.loads(raw_config)
  55. for config in symbol_sources:
  56. if config["type"] == "appStoreConnect":
  57. return config
  58. else:
  59. raise KeyError("appStoreConnect config not found")
  60. if __name__ == "__main__":
  61. if sys.argv[2].startswith("--project="):
  62. project_arg = sys.argv.pop(2)
  63. PROJECT_ID = int(project_arg[10:])
  64. main(sys.argv[2:])