Repository: napari/napari

Issue:
running_as_bundled_app no longer works
## 🐛 Bug
The `running_as_bundled_app`  function no longer seems to work, and the reason is that the METADATA file currently produced (at `app/napari-...dist-info/METADATA`) is extremely minimal, and lacks the stuff (like Briefcase-Version) that is "supposed" to be in there as per https://briefcase.readthedocs.io/en/latest/how-to/access-packaging-metadata.html?highlight=briefcase-version.

@goanpeca, @jaimergp ... do you have any ideas why that might be?
Perhaps we can come up with another strategy?  like adding a package metadata flag ourselves (in `bundle.py` that we could look for?


Discussion:
>app/napari-...dist-info/METADATA

@tlambert03 what command produces that file? is this a `python sdist...` thing that might have changed? Maybe we have to pass a flag to preserve whatever information is missing?

Or maybe I am not understanding the issue 🤔 

---

Also was this the result of the last PR that added constructor things?
I gave up with the metadata approach and introduced a sentinel file next to `sys.executable` in my PR.

See [creation](https://github.com/napari/napari/pull/3555/files#diff-192446c64cc8dd900288f1523d9d032513bf68066f0c0ad4fd3a29b8baf6fd3bR226-R234) and [detection](https://github.com/napari/napari/pull/3555/files#diff-09b82be2ee4fc3ca890d1d940d9b55e60d35290e15ad69d74f53734da25dda8cR15-R32).
> @tlambert03 what command produces that file?

briefcase itself, during installation, based on the setup.cfg and pyproject.toml in the project

> See creation and detection.

that works for me!  any chance we could get that in main?  or does it really require the full toolchain that you're working on there?
Yep I'll port it, it's totally independent from conda.

Resolving patch:
diff --git a/bundle.py b/bundle.py
--- a/bundle.py
+++ b/bundle.py
@@ -7,6 +7,7 @@
 import sys
 import time
 from contextlib import contextmanager
+from pathlib import Path
 
 import tomlkit
 
@@ -33,8 +34,10 @@
 
 if WINDOWS:
     BUILD_DIR = os.path.join(HERE, 'windows')
+    APP_DIR = os.path.join(BUILD_DIR, APP, 'src')
 elif LINUX:
     BUILD_DIR = os.path.join(HERE, 'linux')
+    APP_DIR = os.path.join(BUILD_DIR, APP, f'{APP}.AppDir')
 elif MACOS:
     BUILD_DIR = os.path.join(HERE, 'macOS')
     APP_DIR = os.path.join(BUILD_DIR, APP, f'{APP}.app')
@@ -205,6 +208,17 @@ def patch_python_lib_location():
         print("symlinking", orig, "to", dest)
 
 
+def add_sentinel_file():
+    if MACOS:
+        (Path(APP_DIR) / "Contents" / "MacOS" / ".napari_is_bundled").touch()
+    elif LINUX:
+        (Path(APP_DIR) / "usr" / "bin" / ".napari_is_bundled").touch()
+    elif WINDOWS:
+        (Path(APP_DIR) / "python" / ".napari_is_bundled").touch()
+    else:
+        print("!!! Sentinel files not yet implemented in", sys.platform)
+
+
 def patch_environment_variables():
     os.environ["ARCH"] = architecture()
 
@@ -262,6 +276,7 @@ def bundle():
         time.sleep(0.5)
 
         add_site_packages_to_path()
+        add_sentinel_file()
 
         if WINDOWS:
             patch_wxs()
diff --git a/napari/utils/misc.py b/napari/utils/misc.py
--- a/napari/utils/misc.py
+++ b/napari/utils/misc.py
@@ -54,6 +54,9 @@ def running_as_bundled_app() -> bool:
     # https://github.com/beeware/briefcase/issues/412
     # https://github.com/beeware/briefcase/pull/425
     # note that a module may not have a __package__ attribute
+    # From 0.4.12 we add a sentinel file next to the bundled sys.executable
+    if (Path(sys.executable).parent / ".napari_is_bundled").exists():
+        return True
     try:
         app_module = sys.modules['__main__'].__package__
     except AttributeError:


Test patch: