diff --git a/display/d.barscale/Makefile b/display/d.barscale/Makefile
index d1e59dddc2e..7637e8811e0 100644
--- a/display/d.barscale/Makefile
+++ b/display/d.barscale/Makefile
@@ -10,11 +10,18 @@ include $(MODULE_TOPDIR)/include/Make/Module.make
# thumbnail previews
IMGSRC := $(wildcard thumbnails/*.png)
IMGDST := $(patsubst thumbnails/%,$(HTMLDIR)/barscales/%,$(IMGSRC))
+MDIMGDST := $(patsubst thumbnails/%,$(MDDIR)/source/barscales/%,$(IMGSRC))
-default: cmd $(IMGDST)
+default: cmd $(IMGDST) $(MDIMGDST)
$(HTMLDIR)/barscales/%.png: thumbnails/%.png | $(HTMLDIR)/barscales
$(INSTALL_DATA) $< $@
+$(MDDIR)/source/barscales/%.png: thumbnails/%.png | $(MDDIR)/source/barscales
+ $(INSTALL_DATA) $< $@
+
$(HTMLDIR)/barscales: $(HTMLDIR)
$(MKDIR) $@
+
+$(MDDIR)/source/barscales: $(MDDIR)
+ $(MKDIR) $@
diff --git a/display/d.graph/Makefile b/display/d.graph/Makefile
index eb2cd3c1a6c..84c3cc65bfd 100644
--- a/display/d.graph/Makefile
+++ b/display/d.graph/Makefile
@@ -7,7 +7,10 @@ DEPENDENCIES = $(DISPLAYDEP) $(SYMBDEP) $(GISDEP)
include $(MODULE_TOPDIR)/include/Make/Module.make
-default: cmd $(HTMLDIR)/grass_logo.txt
+default: cmd $(HTMLDIR)/grass_logo.txt $(MDDIR)/source/grass_logo.txt
$(HTMLDIR)/%.txt: %.txt
$(INSTALL_DATA) $< $@
+
+$(MDDIR)/source/%.txt: %.txt
+ $(INSTALL_DATA) $< $@
diff --git a/display/d.northarrow/Makefile b/display/d.northarrow/Makefile
index 493446a3289..bf11eda33e7 100644
--- a/display/d.northarrow/Makefile
+++ b/display/d.northarrow/Makefile
@@ -10,11 +10,18 @@ include $(MODULE_TOPDIR)/include/Make/Module.make
# thumbnail previews
IMGSRC := $(wildcard thumbnails/*.png)
IMGDST := $(patsubst thumbnails/%,$(HTMLDIR)/northarrows/%,$(IMGSRC))
+MDIMGDST := $(patsubst thumbnails/%,$(MDDIR)/source/northarrows/%,$(IMGSRC))
-default: cmd $(IMGDST)
+default: cmd $(IMGDST) $(MDIMGDST)
$(HTMLDIR)/northarrows/%.png: thumbnails/%.png | $(HTMLDIR)/northarrows
$(INSTALL_DATA) $< $@
+$(MDDIR)/source/northarrows/%.png: thumbnails/%.png | $(MDDIR)/source/northarrows
+ $(INSTALL_DATA) $< $@
+
$(HTMLDIR)/northarrows: $(HTMLDIR)
$(MKDIR) $@
+
+$(MDDIR)/source/northarrows: $(MDDIR)
+ $(MKDIR) $@
diff --git a/doc/Makefile b/doc/Makefile
index 042789d064a..8a5b6e3de1c 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -3,5 +3,8 @@ MODULE_TOPDIR = ..
include $(MODULE_TOPDIR)/include/Make/Other.make
FILES := $(wildcard *.html)
+# So far, we disntinguished user and contributor documentation here by
+# extension. This is no longer possible with Markdown.
+MDFILES := grass_database.md projectionintro.md
-default: $(patsubst %,$(HTMLDIR)/%,$(FILES))
+default: $(patsubst %,$(HTMLDIR)/%,$(FILES)) $(patsubst %,$(MDDIR)/source/%,$(MDFILES))
diff --git a/gui/icons/Makefile b/gui/icons/Makefile
index 20a27fb7279..501a378795b 100644
--- a/gui/icons/Makefile
+++ b/gui/icons/Makefile
@@ -7,6 +7,7 @@ SRCICONS := $(wildcard grass/*.png)
SRCFLAGS := $(wildcard flags/*.png)
ETCICONS := $(patsubst %,$(GUIDIR)/icons/%,$(SRCICONS) $(SRCICO) $(SRCFLAGS))
HTMLICONS := $(patsubst grass/%,$(HTMLDIR)/icons/%,$(SRCICONS))
+MDDIRICONS := $(patsubst grass/%,$(MDDIR)/source/icons/%,$(SRCICONS))
DSTDIRS = \
$(GUIDIR) \
@@ -17,7 +18,10 @@ DSTDIRS = \
HTMLDIRS = \
$(HTMLDIR)/icons
-default: $(ETCICONS) $(HTMLICONS)
+MDDIRS = \
+ $(MDDIR)/source/icons
+
+default: $(ETCICONS) $(HTMLICONS) $(MDDIRICONS)
$(MKDIR) $(ARCH_DISTDIR)/share/applications
$(INSTALL_DATA) grass.desktop $(ARCH_DISTDIR)/share/applications
$(MKDIR) $(ARCH_DISTDIR)/share/icons/hicolor/8x8/apps
@@ -66,5 +70,8 @@ $(GUIDIR)/icons/%: % | $(DSTDIRS)
$(HTMLDIR)/icons/%: grass/% | $(HTMLDIRS)
$(INSTALL_DATA) $< $@
-$(DSTDIRS) $(HTMLDIRS): %:
+$(MDDIR)/source/icons/%: grass/% | $(MDDIRS)
+ $(INSTALL_DATA) $< $@
+
+$(DSTDIRS) $(HTMLDIRS) $(MDDIRS): %:
$(MKDIR) $@
diff --git a/gui/wxpython/docs/Makefile b/gui/wxpython/docs/Makefile
index c19abf3fd0e..e83f3340e14 100644
--- a/gui/wxpython/docs/Makefile
+++ b/gui/wxpython/docs/Makefile
@@ -3,5 +3,6 @@ MODULE_TOPDIR = ../../..
include $(MODULE_TOPDIR)/include/Make/Other.make
FILES := $(wildcard *.html)
+MDFILES := $(wildcard *.md)
-default: $(patsubst %,$(HTMLDIR)/%,$(FILES))
+default: $(patsubst %,$(HTMLDIR)/%,$(FILES)) $(patsubst %,$(MDDIR)/source/%,$(MDFILES))
diff --git a/gui/wxpython/gmodeler/Makefile b/gui/wxpython/gmodeler/Makefile
index 38f7382ddcb..7deff8050b6 100644
--- a/gui/wxpython/gmodeler/Makefile
+++ b/gui/wxpython/gmodeler/Makefile
@@ -6,3 +6,4 @@ default: guiscript sample_model
sample_model: g_gui_gmodeler_zipcodes_avg_elevation.gxm
$(INSTALL_DATA) $< $(HTMLDIR)
+ $(INSTALL_DATA) $< $(MDDIR)/source
diff --git a/include/Make/DB.make b/include/Make/DB.make
index 797da921ee5..dba3970f7e4 100644
--- a/include/Make/DB.make
+++ b/include/Make/DB.make
@@ -10,7 +10,7 @@ include $(MODULE_TOPDIR)/include/Make/Compile.make
dbmi: $(DBDRIVERDIR)/$(PGM)$(EXE) db_html
-db_html: $(HTMLDIR)/grass-$(PGM).html $(MANDIR)/grass-$(PGM).$(MANSECT) # $(MDDIR)/source/grass-$(PGM).md
+db_html: $(HTMLDIR)/grass-$(PGM).html $(MANDIR)/grass-$(PGM).$(MANSECT) $(MDDIR)/source/grass-$(PGM).md
$(DBDRIVERDIR)/$(PGM)$(EXE): $(ARCH_OBJS) $(DEPENDENCIES)
$(call linker)
diff --git a/include/Make/GuiScript.make b/include/Make/GuiScript.make
index 7451e2b693d..bbe6df85cb7 100644
--- a/include/Make/GuiScript.make
+++ b/include/Make/GuiScript.make
@@ -27,8 +27,8 @@ ifndef CROSS_COMPILING
$(MAKE) $(CMDHTML)
-rm -f g.gui.*.tmp.html
$(MAKE) $(GUIHTML)
-# $(MAKE) $(CMDMAN)
-# $(MAKE) $(GUIMAN)
+ $(MAKE) $(CMDMAN)
+ $(MAKE) $(GUIMAN)
endif
$(HTMLDIR)/g.gui.%.html: g.gui.%.html g.gui.%.tmp.html | $(HTMLDIR)
diff --git a/include/Make/Html.make b/include/Make/Html.make
index 335c841e149..42d5284ecd9 100644
--- a/include/Make/Html.make
+++ b/include/Make/Html.make
@@ -26,7 +26,7 @@ html:
else
-html: $(HTMLDIR)/$(PGM).html $(MANDIR)/$(PGM).$(MANSECT) # $(MDDIR)/source/$(PGM).md
+html: $(HTMLDIR)/$(PGM).html $(MANDIR)/$(PGM).$(MANSECT) $(MDDIR)/source/$(PGM).md
endif
diff --git a/include/Make/Multi.make b/include/Make/Multi.make
index bca014bceb4..bca25733ce2 100644
--- a/include/Make/Multi.make
+++ b/include/Make/Multi.make
@@ -8,6 +8,7 @@ include $(MODULE_TOPDIR)/include/Make/Compile.make
PROGFILES = $(patsubst %,$(BIN)/%$(EXE),$(PROGRAMS))
HTMLFILES = $(patsubst %,$(HTMLDIR)/%.html,$(PROGRAMS))
+MDFILES = $(patsubst %,$(MDDIR)/source/%.md,$(PROGRAMS))
MANFILES = $(patsubst %,$(MANDIR)/%.$(MANSECT),$(PROGRAMS))
multi: progs htmlmulti
@@ -17,7 +18,7 @@ progs: $(PROGFILES)
ifdef CROSS_COMPILING
htmlmulti:
else
-htmlmulti: $(HTMLFILES) $(MANFILES)
+htmlmulti: $(HTMLFILES) $(MANFILES) $(MDFILES)
endif
$(BIN)/%$(EXE): $(DEPENDENCIES)
@@ -28,7 +29,10 @@ $(BIN)/$(1)$(EXE): $$(patsubst %.o,$(OBJDIR)/%.o,$$($$(subst .,_,$(1)_OBJS)))
$(HTMLDIR)/$(1).html: $(1).html $(1).tmp.html $(BIN)/$(1)$(EXE)
$(1).tmp.html: $(BIN)/$(1)$(EXE)
$$(call htmldesc,$$<,$$@)
-.INTERMEDIATE: $(1).tmp.html
+$(MDDIR)/source/$(1).md: $(1).md $(1).tmp.md $(BIN)/$(1)$(EXE)
+$(1).tmp.md: $(BIN)/$(1)$(EXE)
+ $$(call mddesc,$$<,$$@)
+.INTERMEDIATE: $(1).tmp.html $(1).tmp.md
endef
$(foreach prog,$(PROGRAMS),$(eval $(call objs_rule,$(prog))))
diff --git a/man/Makefile b/man/Makefile
index 4ad90b29a74..47bb8bed13e 100644
--- a/man/Makefile
+++ b/man/Makefile
@@ -38,11 +38,11 @@ IDXSRC = full_index index topics keywords graphical_index manual_gallery class_g
INDICES := $(patsubst %,$(HTMLDIR)/%.html,$(IDXSRC))
-IDXSRC_MD = full_index index topics keywords graphical_index manual_gallery parser_standard_options $(IDXCATS)
+IDXSRC_MD = full_index index topics keywords graphical_index manual_gallery class_graphical parser_standard_options $(IDXCATS)
INDICES_MD := $(patsubst %,$(MDDIR)/source/%.md,$(IDXSRC_MD))
ALL_HTML := $(wildcard $(HTMLDIR)/*.*.html)
-ALL_MD := $(wildcard $(MDDIR)/source/*.*.html)
+ALL_MD := $(wildcard $(MDDIR)/source/*.*.md)
ifneq (@(type sphinx-build2 > /dev/null),)
SPHINXBUILD = sphinx-build2
@@ -125,7 +125,13 @@ $(MDDIR)/source/topics.md: $(ALL_MD)
define build_class_graphical
GISBASE="$(RUN_GISBASE)" ARCH="$(ARCH)" ARCH_DISTDIR="$(ARCH_DISTDIR)" \
VERSION_NUMBER=$(GRASS_VERSION_NUMBER) VERSION_DATE=$(GRASS_VERSION_DATE) \
- $(PYTHON) ./build_class_graphical.py $(HTMLDIR)
+ $(PYTHON) ./build_class_graphical.py html $(HTMLDIR)
+endef
+
+define build_class_graphical_md
+GISBASE="$(RUN_GISBASE)" ARCH="$(ARCH)" ARCH_DISTDIR="$(ARCH_DISTDIR)" \
+ VERSION_NUMBER=$(GRASS_VERSION_NUMBER) VERSION_DATE=$(GRASS_VERSION_DATE) \
+ $(PYTHON) ./build_class_graphical.py md $(MDDIR)/source
endef
$(HTMLDIR)/topics.html: $(ALL_HTML) build_topics.py
@@ -187,6 +193,11 @@ $(HTMLDIR)/class_graphical.html: $(ALL_HTML)
$(call build_class_graphical)
touch $@
+# TODO: this should be done in the same way as category_rule
+$(MDDIR)/source/class_graphical.md: $(ALL_MD)
+ $(call build_class_graphical_md)
+ touch $@
+
define category_rule
$$(HTMLDIR)/$(2).html: $$(wildcard $$(HTMLDIR)/$(1).*.html) build_class.py build_html.py
$$(call build,class,$(1) $(2))
diff --git a/man/build_class_graphical.py b/man/build_class_graphical.py
index 0eed97beb46..47ef979d9fe 100644
--- a/man/build_class_graphical.py
+++ b/man/build_class_graphical.py
@@ -34,9 +34,10 @@
man_dir,
)
+import build_md
-header_graphical_index_tmpl = """\
-
+
+graphical_index_style = """\
+"""
+
+header_graphical_index_tmpl = f"""\
+
+{graphical_index_style}
@@ -190,13 +196,80 @@ def generate_page_for_category(
replace_file(filename)
+def generate_page_for_category_md(
+ short_family, module_family, imgs, year, skip_no_image=False
+):
+ filename = module_family + "_graphical.md"
+ with open(filename + ".tmp", "w") as output:
+ output.write(graphical_index_style)
+
+ if module_family.lower() not in {"general", "postscript"}:
+ if module_family == "raster3d":
+ # covert keyword to nice form
+ module_family = "3D raster"
+ output.write(
+ modclass_intro_tmpl.substitute(
+ modclass=module_family, modclass_lower=module_family.lower()
+ )
+ )
+ if module_family == "wxGUI":
+ output.write("# wxGUI components\n")
+ elif module_family == "guimodules":
+ output.write("# g.gui.* modules\n")
+ else:
+ output.write("# {0} tools\n".format(to_title(module_family)))
+ output.write('
')
+
+ # for all modules:
+ for cmd in get_files(
+ build_md.man_dir, short_family, ignore_gui=False, extension="md"
+ ):
+ basename = os.path.splitext(cmd)[0]
+ desc = check_for_desc_override(basename)
+ if desc is None:
+ desc = build_md.get_desc(cmd)
+ img = get_module_image(basename, imgs)
+ img_class = "linkimg"
+ if skip_no_image and not img:
+ continue
+ if not img:
+ img = "grass_logo.png"
+ img_class = "default-img"
+ if basename.startswith("wxGUI"):
+ basename = basename.replace(".", " ")
+ output.write(
+ "- "
+ ''
+ '
'
+ ""
+ ''
+ '{name} '
+ '{desc}'
+ ""
+ " ".format(
+ html=cmd.removesuffix(".md"),
+ img=img,
+ name=basename,
+ desc=desc,
+ img_class=img_class,
+ )
+ )
+
+ output.write("
")
+
+ write_footer(output, "index.html", year, template="md")
+
+ replace_file(filename)
+
+
# TODO: dependencies in makefile for this have to be fixed
# TODO: there is a potential overlap with other scripts (-> refactoring)
def main():
year = default_year
- html_dir = sys.argv[1]
+ output_format = sys.argv[1]
+ html_dir = sys.argv[2]
os.chdir(html_dir)
img_extensions = ["png", "jpg", "gif"]
@@ -227,16 +300,24 @@ def main():
# partial compatibility with build_class.py
# first arg is dist html dir but the 3 other are like first 3 there
- if len(sys.argv) > 2:
- short_family = sys.argv[2]
- module_family = sys.argv[3]
- if len(sys.argv) > 4:
- year = sys.argv[4]
+ if len(sys.argv) > 3:
+ short_family = sys.argv[3]
+ module_family = sys.argv[4]
+ if len(sys.argv) > 5:
+ year = sys.argv[5]
for short_family, module_family in families:
- generate_page_for_category(
- short_family, module_family, imgs, year=year, skip_no_image=False
- )
+ if output_format == "html":
+ generate_page_for_category(
+ short_family, module_family, imgs, year=year, skip_no_image=False
+ )
+ elif output_format == "md":
+ generate_page_for_category_md(
+ short_family, module_family, imgs, year=year, skip_no_image=False
+ )
+ else:
+ msg = f"Unknown format: {output_format}"
+ raise ValueError(msg)
if __name__ == "__main__":
diff --git a/man/build_graphical_index.py b/man/build_graphical_index.py
index bc7dd5299d9..f29feef786b 100755
--- a/man/build_graphical_index.py
+++ b/man/build_graphical_index.py
@@ -87,8 +87,8 @@ def main(ext):
)
else:
output.write(
- "- []({link})".format(
- link=html_file, img=image, name=label
+ "- []({link}.md)".format(
+ link=html_file.removesuffix(".html"), img=image, name=label
)
)
diff --git a/man/build_topics.py b/man/build_topics.py
index 2ef3e8c57df..a9a42ea3108 100644
--- a/man/build_topics.py
+++ b/man/build_topics.py
@@ -61,7 +61,12 @@ def build_topics(ext):
try:
desc = lines[index_desc].split("-", 1)[1].strip()
except Exception:
- desc.strip()
+ desc = desc.strip()
+
+ # Line ending can appear here on Windows.
+ key = key.strip()
+ if not key:
+ continue
if key not in keywords.keys():
keywords[key] = {}
@@ -102,7 +107,7 @@ def build_topics(ext):
topicsfile.writelines(
[
moduletopics_tmpl.substitute(
- key=key, name=key.replace("_", " ")
+ key=key.replace(" ", "_"), name=key.replace("_", " ")
)
]
)
@@ -125,9 +130,10 @@ def build_topics(ext):
# expecting markdown
keyfile.write(
"*See also the corresponding keyword"
- " [{key}](keywords.md#{key})"
+ " [{name}](keywords.md#{key})"
" for additional references.*\n".format(
- key=key.replace(" ", "-").replace("_", "-").lower()
+ key=key.replace(" ", "-").replace("_", "-").lower(),
+ name=key.replace("_", " "),
)
)
diff --git a/raster/Makefile b/raster/Makefile
index a8f00ee9c7c..a571f47f1e2 100644
--- a/raster/Makefile
+++ b/raster/Makefile
@@ -44,7 +44,6 @@ SUBDIRS = \
r.latlong \
r.lake \
r.li \
- r.mapcalc \
r.mask.status \
r.mfilter \
r.mode \
diff --git a/raster/r.colors/Makefile b/raster/r.colors/Makefile
index de53e51244b..7d691dbbc28 100644
--- a/raster/r.colors/Makefile
+++ b/raster/r.colors/Makefile
@@ -12,14 +12,18 @@ include $(MODULE_TOPDIR)/include/Make/Multi.make
default: multi thumbnails
-thumbnails: $(BIN)/r.mapcalc$(EXE) $(BIN)/r.colors$(EXE) $(HTMLDIR)/colortables
+thumbnails: $(BIN)/r.mapcalc$(EXE) $(BIN)/r.colors$(EXE) $(HTMLDIR)/colortables $(MDDIR)/source/colortables
ifndef CROSS_COMPILING
- -$(call run_grass, $(GRASS_HOME)/utils/thumbnails.py)
+ $(call run_grass, $(GRASS_HOME)/utils/thumbnails.py $(MDDIR)/source/colortables)
+ $(call run_grass, $(GRASS_HOME)/utils/thumbnails.py $(HTMLDIR)/colortables)
endif
$(HTMLDIR)/colortables: $(HTMLDIR)
$(MKDIR) $@
+$(MDDIR)/source/colortables: $(MDDIR)
+ $(MKDIR) $@
+
$(BIN)/r.mapcalc$(EXE):
$(MAKE) -C ../r.mapcalc
diff --git a/scripts/g.extension/g.extension.py b/scripts/g.extension/g.extension.py
index f694e73c23a..afa3f17a60c 100644
--- a/scripts/g.extension/g.extension.py
+++ b/scripts/g.extension/g.extension.py
@@ -1957,6 +1957,23 @@ def download_source_code(
return directory, url
+def create_md_if_missing(root_dir):
+ """Recursively searches for HTML files in the specified directory.
+ If an HTML file does not have a corresponding Markdown (.md) file,
+ it creates one by copying the HTML file and renaming it.
+ """
+ for dirpath, _, filenames in os.walk(root_dir):
+ html_files = [f for f in filenames if f.endswith(".html")]
+
+ for html_file in html_files:
+ md_file = os.path.splitext(html_file)[0] + ".md"
+ md_path = os.path.join(dirpath, md_file)
+
+ if not os.path.exists(md_path):
+ html_path = os.path.join(dirpath, html_file)
+ shutil.copy(html_path, md_path)
+
+
def install_extension_std_platforms(name, source, url, branch):
"""Install extension on standard platforms"""
gisbase = os.getenv("GISBASE")
@@ -1976,6 +1993,7 @@ def install_extension_std_platforms(name, source, url, branch):
tmpdir=TMPDIR,
branch=branch,
)
+ create_md_if_missing(srcdir)
os.chdir(srcdir)
pgm_not_found_message = _(
diff --git a/utils/mkdocs.py b/utils/mkdocs.py
index 1323fe06229..ecbca5f4a0f 100644
--- a/utils/mkdocs.py
+++ b/utils/mkdocs.py
@@ -1,14 +1,16 @@
# common functions used by mkmarkdown.py and mkhtml.py
-import sys
-import os
import json
-import subprocess
+import os
import re
+import shutil
+import subprocess
+import sys
+import tempfile
import urllib.parse as urlparse
+from datetime import datetime
from http import HTTPStatus
from pathlib import Path
-from datetime import datetime
from urllib import request as urlrequest
from urllib.error import HTTPError, URLError
@@ -368,68 +370,75 @@ def get_addon_path(base_url, pgm, major_version):
:return str|None: pgm path if pgm is addon else None
"""
addons_base_dir = os.getenv("GRASS_ADDON_BASE")
- if addons_base_dir and major_version:
- grass_addons_dir = Path(addons_base_dir) / "grass-addons"
- if gs:
- call = gs.call
- popen = gs.Popen
- fatal = gs.fatal
- else:
- call = subprocess.call
- popen = subprocess.Popen
- fatal = sys.stderr.write
- addons_branch = get_version_branch(
- major_version=major_version,
- addons_git_repo_url=urlparse.urljoin(base_url, "grass-addons/"),
- )
- if not Path(addons_base_dir).exists():
- Path(addons_base_dir).mkdir(parents=True, exist_ok=True)
- if not grass_addons_dir.exists():
- call(
- [
- "git",
- "clone",
- "-q",
- "--no-checkout",
- f"--branch={addons_branch}",
- "--filter=blob:none",
- urlparse.urljoin(base_url, "grass-addons/"),
- ],
- cwd=addons_base_dir,
- )
- addons_file_list = popen(
- ["git", "ls-tree", "--name-only", "-r", addons_branch],
- cwd=grass_addons_dir,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
+ if not addons_base_dir or not major_version:
+ return None
+ grass_addons_dir = Path(addons_base_dir) / "grass-addons"
+ if gs:
+ call = gs.call
+ popen = gs.Popen
+ fatal = gs.fatal
+ else:
+ call = subprocess.call
+ popen = subprocess.Popen
+ fatal = sys.stderr.write
+ addons_branch = get_version_branch(
+ major_version=major_version,
+ addons_git_repo_url=urlparse.urljoin(base_url, "grass-addons/"),
+ )
+ if not Path(addons_base_dir).exists():
+ Path(addons_base_dir).mkdir(parents=True, exist_ok=True)
+ if not grass_addons_dir.exists():
+ try:
+ with tempfile.TemporaryDirectory(dir=addons_base_dir) as tmpdir:
+ tmp_clone_path = Path(tmpdir) / "grass-addons"
+ call(
+ [
+ "git",
+ "clone",
+ "-q",
+ "--no-checkout",
+ f"--branch={addons_branch}",
+ "--filter=blob:none",
+ urlparse.urljoin(base_url, "grass-addons/"),
+ str(tmp_clone_path),
+ ]
+ )
+ shutil.move(tmp_clone_path, grass_addons_dir)
+ except shutil.Error:
+ pass # Another process created it first; proceed normally
+ addons_file_list = popen(
+ ["git", "ls-tree", "--name-only", "-r", addons_branch],
+ cwd=grass_addons_dir,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ )
+ addons_file_list, stderr = addons_file_list.communicate()
+ if stderr:
+ message = (
+ "Failed to get addons files list from the"
+ " Git repository <{repo_path}>.\n{error}"
)
- addons_file_list, stderr = addons_file_list.communicate()
- if stderr:
- message = (
- "Failed to get addons files list from the"
- " Git repository <{repo_path}>.\n{error}"
- )
- if gs:
- fatal(
- _(
- message,
- ).format(
- repo_path=grass_addons_dir,
- error=gs.decode(stderr),
- )
+ if gs:
+ fatal(
+ _(
+ message,
+ ).format(
+ repo_path=grass_addons_dir,
+ error=gs.decode(stderr),
)
- else:
- message += "\n"
- fatal(
- message.format(
- repo_path=grass_addons_dir,
- error=stderr.decode(),
- )
+ )
+ else:
+ message += "\n"
+ fatal(
+ message.format(
+ repo_path=grass_addons_dir,
+ error=stderr.decode(),
)
- addon_paths = re.findall(
- rf".*{pgm}*.",
- gs.decode(addons_file_list) if gs else addons_file_list.decode(),
- )
- for addon_path in addon_paths:
- if pgm == Path(addon_path).name:
- return addon_path
+ )
+ addon_paths = re.findall(
+ rf".*{pgm}*.",
+ gs.decode(addons_file_list) if gs else addons_file_list.decode(),
+ )
+ for addon_path in addon_paths:
+ if pgm == Path(addon_path).name:
+ return addon_path
diff --git a/utils/thumbnails.py b/utils/thumbnails.py
index b0197b712df..c04c806bb13 100755
--- a/utils/thumbnails.py
+++ b/utils/thumbnails.py
@@ -15,6 +15,7 @@
import os
import atexit
+import sys
from pathlib import Path
import grass.script as gs
@@ -106,7 +107,7 @@ def make_gradient(path):
def make_image(output_dir, table, grad, height, width):
- outfile = os.path.join(output_dir, "colortables", "%s.png" % table)
+ outfile = os.path.join(output_dir, "%s.png" % table)
os.environ["GRASS_RENDER_FILE"] = outfile
gs.run_command("r.colors", map=grad, color=table, quiet=True)
@@ -158,7 +159,7 @@ def main():
os.environ["GRASS_OVERWRITE"] = "1"
color_dir = os.path.join(os.environ["GISBASE"], "etc", "colors")
- output_dir = os.path.join(os.environ["GISBASE"], "docs", "html")
+ output_dir = sys.argv[1]
if not os.path.exists(output_dir):
os.makedirs(output_dir)