Skip to content

Commit c6636e1

Browse files
authored
feat: Detect Antigravity IDE for usage tracking (#183)
1 parent bec1604 commit c6636e1

2 files changed

Lines changed: 99 additions & 6 deletions

File tree

google/cloud/dataproc_spark_connect/environment.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@
1717
from typing import Callable, Tuple, List
1818

1919

20+
def is_antigravity() -> bool:
21+
"""True if running inside the Antigravity environment."""
22+
return "antigravity" in os.getenv("__CFBundleIdentifier", "").lower()
23+
24+
2025
def is_vscode() -> bool:
2126
"""True if running inside VS Code at all."""
2227
return os.getenv("VSCODE_PID") is not None
@@ -148,12 +153,13 @@ def get_client_environment_label() -> str:
148153
10. Google Cloud Shell ("cloud-shell")
149154
11. Hex ("hex")
150155
12. Polynote ("polynote")
151-
13. VS Code ("vscode")
152-
14. JetBrains IDE ("jetbrains")
153-
15. Spyder ("spyder")
154-
16. Eclipse ("eclipse")
155-
17. Jupyter ("jupyter")
156-
18. Unknown ("unknown")
156+
13. Antigravity ("antigravity")
157+
14. VS Code ("vscode")
158+
15. JetBrains IDE ("jetbrains")
159+
16. Spyder ("spyder")
160+
17. Eclipse ("eclipse")
161+
18. Jupyter ("jupyter")
162+
19. Unknown ("unknown")
157163
"""
158164
checks: List[Tuple[Callable[[], bool], str]] = [
159165
(is_colab_enterprise, "colab-enterprise"),
@@ -168,6 +174,7 @@ def get_client_environment_label() -> str:
168174
(is_cloud_shell, "cloud-shell"),
169175
(is_hex, "hex"),
170176
(is_polynote, "polynote"),
177+
(is_antigravity, "antigravity"),
171178
(is_vscode, "vscode"),
172179
(is_jetbrains_ide, "jetbrains"),
173180
(is_spyder, "spyder"),

tests/unit/test_environment.py

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,22 @@ def tearDown(self):
3030
os.environ.clear()
3131
os.environ.update(self.original_environ)
3232

33+
def test_is_antigravity_true(self):
34+
os.environ["__CFBundleIdentifier"] = "com.google.antigravity"
35+
self.assertTrue(environment.is_antigravity())
36+
37+
def test_is_antigravity_true_case_insensitive(self):
38+
os.environ["__CFBundleIdentifier"] = "AntiGravity-App"
39+
self.assertTrue(environment.is_antigravity())
40+
41+
def test_is_antigravity_false_not_present(self):
42+
os.environ.pop("__CFBundleIdentifier", None)
43+
self.assertFalse(environment.is_antigravity())
44+
45+
def test_is_antigravity_false_different_value(self):
46+
os.environ["__CFBundleIdentifier"] = "com.example.app"
47+
self.assertFalse(environment.is_antigravity())
48+
3349
def test_is_vscode_true(self):
3450
os.environ["VSCODE_PID"] = "12345"
3551
self.assertTrue(environment.is_vscode())
@@ -231,6 +247,10 @@ def test_is_jetbrains_ide_false_env_var_not_jetbrains(self):
231247
"google.cloud.dataproc_spark_connect.environment.is_polynote",
232248
return_value=False,
233249
)
250+
@mock.patch(
251+
"google.cloud.dataproc_spark_connect.environment.is_antigravity",
252+
return_value=False,
253+
)
234254
@mock.patch(
235255
"google.cloud.dataproc_spark_connect.environment.is_vscode",
236256
return_value=False,
@@ -371,6 +391,68 @@ def test_get_client_environment_label_kaggle(self, *mocks):
371391
"google.cloud.dataproc_spark_connect.environment.is_polynote",
372392
return_value=False,
373393
)
394+
@mock.patch(
395+
"google.cloud.dataproc_spark_connect.environment.is_antigravity",
396+
return_value=True,
397+
)
398+
def test_get_client_environment_label_antigravity(self, *mocks):
399+
self.assertEqual(
400+
environment.get_client_environment_label(),
401+
"antigravity",
402+
)
403+
404+
@mock.patch(
405+
"google.cloud.dataproc_spark_connect.environment.is_colab_enterprise",
406+
return_value=False,
407+
)
408+
@mock.patch(
409+
"google.cloud.dataproc_spark_connect.environment.is_colab",
410+
return_value=False,
411+
)
412+
@mock.patch(
413+
"google.cloud.dataproc_spark_connect.environment.is_workbench",
414+
return_value=False,
415+
)
416+
@mock.patch(
417+
"google.cloud.dataproc_spark_connect.environment.is_kaggle",
418+
return_value=False,
419+
)
420+
@mock.patch(
421+
"google.cloud.dataproc_spark_connect.environment.is_sagemaker",
422+
return_value=False,
423+
)
424+
@mock.patch(
425+
"google.cloud.dataproc_spark_connect.environment.is_databricks",
426+
return_value=False,
427+
)
428+
@mock.patch(
429+
"google.cloud.dataproc_spark_connect.environment.is_deepnote",
430+
return_value=False,
431+
)
432+
@mock.patch(
433+
"google.cloud.dataproc_spark_connect.environment.is_datalore",
434+
return_value=False,
435+
)
436+
@mock.patch(
437+
"google.cloud.dataproc_spark_connect.environment.is_codespaces",
438+
return_value=False,
439+
)
440+
@mock.patch(
441+
"google.cloud.dataproc_spark_connect.environment.is_cloud_shell",
442+
return_value=False,
443+
)
444+
@mock.patch(
445+
"google.cloud.dataproc_spark_connect.environment.is_hex",
446+
return_value=False,
447+
)
448+
@mock.patch(
449+
"google.cloud.dataproc_spark_connect.environment.is_polynote",
450+
return_value=False,
451+
)
452+
@mock.patch(
453+
"google.cloud.dataproc_spark_connect.environment.is_antigravity",
454+
return_value=False,
455+
)
374456
@mock.patch(
375457
"google.cloud.dataproc_spark_connect.environment.is_vscode",
376458
return_value=True,
@@ -429,6 +511,10 @@ def test_get_client_environment_label_vscode(self, *mocks):
429511
"google.cloud.dataproc_spark_connect.environment.is_polynote",
430512
return_value=False,
431513
)
514+
@mock.patch(
515+
"google.cloud.dataproc_spark_connect.environment.is_antigravity",
516+
return_value=False,
517+
)
432518
@mock.patch(
433519
"google.cloud.dataproc_spark_connect.environment.is_vscode",
434520
return_value=False,

0 commit comments

Comments
 (0)