瀏覽代碼

init/pythonlib: unified use of addonbase for mac (#2004)

- set default GRASS_ADDON_BASE for macOS to reflect the settings of
  GRASS app bundle
- for pythonlib grassscript.setup: use GRASS_ADDON_BASE if set, else
  fallback to defaults for each OS
- replaces hardcoded GRASS version as part file/dir names with a
  generated/dynamic version
nilason 3 年之前
父節點
當前提交
711cc2989f
共有 4 個文件被更改,包括 64 次插入42 次删除
  1. 4 0
      lib/init/Makefile
  2. 25 22
      lib/init/grass.py
  3. 2 0
      python/grass/script/Makefile
  4. 33 20
      python/grass/script/setup.py

+ 4 - 0
lib/init/Makefile

@@ -70,6 +70,8 @@ endif
 	sed \
 	-e 's#@GISBASE@#$(RUN_GISBASE)#' \
 	-e 's#@GRASS_VERSION_NUMBER@#$(GRASS_VERSION_NUMBER)#' \
+	-e 's#@GRASS_VERSION_MAJOR@#$(GRASS_VERSION_MAJOR)#' \
+	-e 's#@GRASS_VERSION_MINOR@#$(GRASS_VERSION_MINOR)#' \
 	-e 's#@GRASS_VERSION_GIT@#$(GRASS_VERSION_GIT)#' \
 	-e 's#@LD_LIBRARY_PATH_VAR@#$(LD_LIBRARY_PATH_VAR)#' \
 	-e 's#@START_UP@#$(START_UP)#' \
@@ -81,6 +83,8 @@ $(ARCH_DISTDIR)/$(START_UP).tmp: grass.py
 	rm -f $@
 	sed \
 	-e 's#@GRASS_VERSION_NUMBER@#$(GRASS_VERSION_NUMBER)#' \
+	-e 's#@GRASS_VERSION_MAJOR@#$(GRASS_VERSION_MAJOR)#' \
+	-e 's#@GRASS_VERSION_MINOR@#$(GRASS_VERSION_MINOR)#' \
 	-e 's#@GRASS_VERSION_GIT@#$(GRASS_VERSION_GIT)#' \
 	-e 's#@START_UP@#$(START_UP)#' \
 	-e 's#@GRASS_CONFIG_DIR@#$(GRASS_CONFIG_DIR)#' \

+ 25 - 22
lib/init/grass.py

@@ -92,13 +92,15 @@ else:
     os.environ["GISBASE"] = GISBASE
 CMD_NAME = "@START_UP@"
 GRASS_VERSION = "@GRASS_VERSION_NUMBER@"
+GRASS_VERSION_MAJOR = "@GRASS_VERSION_MAJOR@"
+GRASS_VERSION_MINOR = "@GRASS_VERSION_MINOR@"
 LD_LIBRARY_PATH_VAR = "@LD_LIBRARY_PATH_VAR@"
 CONFIG_PROJSHARE = os.environ.get("GRASS_PROJSHARE", "@CONFIG_PROJSHARE@")
 
 # Get the system name
-WINDOWS = sys.platform == "win32"
-CYGWIN = "cygwin" in sys.platform
-MACOSX = "darwin" in sys.platform
+WINDOWS = sys.platform.startswith("win")
+CYGWIN = sys.platform.startswith("cygwin")
+MACOS = sys.platform.startswith("darwin")
 
 
 def decode(bytes_, encoding=ENCODING):
@@ -440,8 +442,8 @@ def get_grass_config_dir():
     Configuration directory is for example used for grass env file
     (the one which caries mapset settings from session to session).
     """
-    if sys.platform == "win32":
-        grass_config_dirname = "GRASS8"
+    if WINDOWS:
+        grass_config_dirname = f"GRASS{GRASS_VERSION_MAJOR}"
         win_conf_path = os.getenv("APPDATA")
         # this can happen with some strange settings
         if not win_conf_path:
@@ -460,7 +462,7 @@ def get_grass_config_dir():
             )
         directory = os.path.join(win_conf_path, grass_config_dirname)
     else:
-        grass_config_dirname = ".grass8"
+        grass_config_dirname = f".grass{GRASS_VERSION_MAJOR}"
         directory = os.path.join(os.getenv("HOME"), grass_config_dirname)
     if not os.path.isdir(directory):
         try:
@@ -490,10 +492,9 @@ def create_tmp(user, gis_lock):
     if not tmp:
         tmp = tempfile.gettempdir()
 
+    tmpdir_name = f"grass{GRASS_VERSION_MAJOR}-{user}-{gis_lock}"
     if tmp:
-        tmpdir = os.path.join(
-            tmp, "grass8-%(user)s-%(lock)s" % {"user": user, "lock": gis_lock}
-        )
+        tmpdir = os.path.join(tmp, tmpdir_name)
         try:
             os.mkdir(tmpdir, 0o700)
         except:  # noqa: E722
@@ -502,9 +503,7 @@ def create_tmp(user, gis_lock):
     if not tmp:
         for ttmp in ("/tmp", "/var/tmp", "/usr/tmp"):
             tmp = ttmp
-            tmpdir = os.path.join(
-                tmp, "grass8-%(user)s-%(lock)s" % {"user": user, "lock": gis_lock}
-            )
+            tmpdir = os.path.join(tmp, tmpdir_name)
             try:
                 os.mkdir(tmpdir, 0o700)
             except:  # noqa: E722
@@ -514,11 +513,9 @@ def create_tmp(user, gis_lock):
 
     if not tmp:
         fatal(
-            _(
-                "Unable to create temporary directory <grass8-%(user)s-"
-                "%(lock)s>! Exiting."
+            _("Unable to create temporary directory <{tmpdir_name}>! Exiting.").format(
+                tmpdir_name=tmpdir_name
             )
-            % {"user": user, "lock": gis_lock}
         )
 
     # promoting the variable even if it was not defined before
@@ -716,7 +713,13 @@ def set_paths(grass_config_dir):
     # addons (base)
     addon_base = os.getenv("GRASS_ADDON_BASE")
     if not addon_base:
-        addon_base = os.path.join(grass_config_dir, "addons")
+        if MACOS:
+            version = f"{GRASS_VERSION_MAJOR}.{GRASS_VERSION_MINOR}"
+            addon_base = os.path.join(
+                os.getenv("HOME"), "Library", "GRASS", version, "Addons"
+            )
+        else:
+            addon_base = os.path.join(grass_config_dir, "addons")
         os.environ["GRASS_ADDON_BASE"] = addon_base
     if not WINDOWS:
         path_prepend(os.path.join(addon_base, "scripts"), "PATH")
@@ -817,7 +820,7 @@ def set_browser():
     # GRASS_HTML_BROWSER
     browser = os.getenv("GRASS_HTML_BROWSER")
     if not browser:
-        if MACOSX:
+        if MACOS:
             # OSX doesn't execute browsers from the shell PATH - route through a
             # script
             browser = gpath("etc", "html_browser_mac.sh")
@@ -852,7 +855,7 @@ def set_browser():
                     browser = b
                     break
 
-    elif MACOSX:
+    elif MACOS:
         # OSX doesn't execute browsers from the shell PATH - route through a
         # script
         os.environ["GRASS_HTML_BROWSER_MACOSX"] = "-b %s" % browser
@@ -886,7 +889,7 @@ MAPSET: <UNKNOWN>
 def check_gui(expected_gui):
     grass_gui = expected_gui
     # Check if we are running X windows by checking the DISPLAY variable
-    if os.getenv("DISPLAY") or WINDOWS or MACOSX:
+    if os.getenv("DISPLAY") or WINDOWS or MACOS:
         # Check if python is working properly
         if expected_gui in ("wxpython", "gtext"):
             nul = open(os.devnull, "w")
@@ -1656,7 +1659,7 @@ def get_shell():
 
     # cygwin has many problems with the shell setup
     # below, so i hardcoded everything here.
-    if sys.platform == "cygwin":
+    if CYGWIN:
         sh = "CYGWIN"
         shellname = "GNU Bash (Cygwin)"
         os.environ["SHELL"] = "/usr/bin/bash.exe"
@@ -2063,7 +2066,7 @@ PROMPT_COMMAND=grass_prompt\n""".format(
         for line in readfile(env_file).splitlines():
             # Bug related to OS X "SIP", see
             # https://trac.osgeo.org/grass/ticket/3462#comment:13
-            if MACOSX or not line.startswith("export"):
+            if MACOS or not line.startswith("export"):
                 f.write(line + "\n")
 
     f.write('export PATH="%s"\n' % os.getenv("PATH"))

+ 2 - 0
python/grass/script/Makefile

@@ -26,4 +26,6 @@ $(DSTDIR)/setup.py: setup.py.tmp | $(DSTDIR)
 setup.py.tmp: setup.py
 	sed \
 	-e 's#@LD_LIBRARY_PATH_VAR@#$(LD_LIBRARY_PATH_VAR)#' \
+	-e 's#@GRASS_VERSION_MAJOR@#$(GRASS_VERSION_MAJOR)#' \
+	-e 's#@GRASS_VERSION_MINOR@#$(GRASS_VERSION_MINOR)#' \
 	$< > $@

+ 33 - 20
python/grass/script/setup.py

@@ -87,7 +87,11 @@ import subprocess
 import sys
 import tempfile as tmpfile
 
-windows = sys.platform == "win32"
+WINDOWS = sys.platform.startswith("win")
+MACOS = sys.platform.startswith("darwin")
+
+VERSION_MAJOR = "@GRASS_VERSION_MAJOR@"
+VERSION_MINOR = "@GRASS_VERSION_MINOR@"
 
 
 def write_gisrc(dbase, location, mapset):
@@ -196,26 +200,35 @@ def setup_runtime_env(gisbase):
     gisbase = os.fspath(gisbase)
     # Set GISBASE
     os.environ["GISBASE"] = gisbase
-    mswin = sys.platform.startswith("win")
+
     # define PATH
-    os.environ["PATH"] += os.pathsep + os.path.join(gisbase, "bin")
-    os.environ["PATH"] += os.pathsep + os.path.join(gisbase, "scripts")
-    if mswin:  # added for winGRASS
-        os.environ["PATH"] += os.pathsep + os.path.join(gisbase, "extrabin")
+    path_addition = os.pathsep + os.path.join(gisbase, "bin")
+    path_addition += os.pathsep + os.path.join(gisbase, "scripts")
+    if WINDOWS:
+        path_addition += os.pathsep + os.path.join(gisbase, "extrabin")
 
-    # add addons to the PATH
+    # add addons to the PATH, use GRASS_ADDON_BASE if set
     # copied and simplified from lib/init/grass.py
-    if mswin:
-        config_dirname = "GRASS8"
-        config_dir = os.path.join(os.getenv("APPDATA"), config_dirname)
-    else:
-        config_dirname = ".grass8"
-        config_dir = os.path.join(os.getenv("HOME"), config_dirname)
-    addon_base = os.path.join(config_dir, "addons")
-    os.environ["GRASS_ADDON_BASE"] = addon_base
-    if not mswin:
-        os.environ["PATH"] += os.pathsep + os.path.join(addon_base, "scripts")
-    os.environ["PATH"] += os.pathsep + os.path.join(addon_base, "bin")
+    addon_base = os.getenv("GRASS_ADDON_BASE")
+    if not addon_base:
+        if WINDOWS:
+            config_dirname = f"GRASS{VERSION_MAJOR}"
+            addon_base = os.path.join(os.getenv("APPDATA"), config_dirname, "addons")
+        elif MACOS:
+            version = f"{VERSION_MAJOR}.{VERSION_MINOR}"
+            addon_base = os.path.join(
+                os.getenv("HOME"), "Library", "GRASS", version, "Addons"
+            )
+        else:
+            config_dirname = f".grass{VERSION_MAJOR}"
+            addon_base = os.path.join(os.getenv("HOME"), config_dirname, "addons")
+        os.environ["GRASS_ADDON_BASE"] = addon_base
+
+    if not WINDOWS:
+        path_addition += os.pathsep + os.path.join(addon_base, "scripts")
+    path_addition += os.pathsep + os.path.join(addon_base, "bin")
+
+    os.environ["PATH"] = path_addition + os.pathsep + os.getenv("PATH")
 
     # define LD_LIBRARY_PATH
     if "@LD_LIBRARY_PATH_VAR@" not in os.environ:
@@ -224,7 +237,7 @@ def setup_runtime_env(gisbase):
 
     # Set GRASS_PYTHON and PYTHONPATH to find GRASS Python modules
     if not os.getenv("GRASS_PYTHON"):
-        if sys.platform == "win32":
+        if WINDOWS:
             os.environ["GRASS_PYTHON"] = "python3.exe"
         else:
             os.environ["GRASS_PYTHON"] = "python3"
@@ -348,7 +361,7 @@ def clean_default_db():
 
 def call(cmd, **kwargs):
     """Wrapper for subprocess.call to deal with platform-specific issues"""
-    if windows:
+    if WINDOWS:
         kwargs["shell"] = True
     return subprocess.call(cmd, **kwargs)