Skip to content

Commit

Permalink
Merge branch 'main' into fix-python2-builtin
Browse files Browse the repository at this point in the history
  • Loading branch information
echoix authored Jan 7, 2024
2 parents 35ac261 + 5e86482 commit 9d8c953
Show file tree
Hide file tree
Showing 29 changed files with 5,761 additions and 140 deletions.
1 change: 0 additions & 1 deletion .github/workflows/macos_gunittest.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ exclude =
python/grass/script/testsuite/test_script_doctests.py
python/grass/temporal/testsuite/unittests_temporal_raster_algebra_equal_ts.py
python/grass/temporal/testsuite/unittests_temporal_raster_conditionals_complement_else.py
raster/r.contour/testsuite/testrc.py
raster/r.in.gdal/testsuite/test_r_in_gdal.py
raster/r.in.lidar/testsuite/test_base_resolution.sh
raster/r.in.lidar/testsuite/test_base_resolution.sh
Expand Down
10 changes: 9 additions & 1 deletion .github/workflows/super-linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,19 @@ jobs:

runs-on: ubuntu-latest

permissions:
contents: read
packages: read
# To report GitHub Actions status checks
statuses: write

steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
- name: Lint code base
uses: github/super-linter@v5
uses: super-linter/super-linter/slim@v5.7.2
env:
DEFAULT_BRANCH: main
# To report GitHub Actions status checks
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Listed but commented out linters would be nice to have.
# (see https://github.com/github/super-linter#environment-variables)
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/verify-success.yml
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,10 @@ jobs:
echo "cancelled=${{ inputs.fail_if_cancelled &&
fromJson(steps.has-result.outputs.cancelled) && 1 || 0
}}" >> "$GITHUB_OUTPUT"
echo "skipped=${{ inputs.fail_if_skipped &&
echo "skipped=${{ inputs.fail_if_skipped &&
fromJson(steps.has-result.outputs.skipped) && 1 || 0
}}" >> "$GITHUB_OUTPUT"
echo "success=${{ inputs.require_success &&
echo "success=${{ inputs.require_success &&
!fromJson(steps.has-result.outputs.success) && 1 || 0
}}" >> "$GITHUB_OUTPUT"
- name: Set messages for each job result type
Expand Down
1 change: 0 additions & 1 deletion .gunittest.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ exclude =
python/grass/script/testsuite/test_script_doctests.py
python/grass/temporal/testsuite/unittests_temporal_raster_algebra_equal_ts.py
python/grass/temporal/testsuite/unittests_temporal_raster_conditionals_complement_else.py
raster/r.contour/testsuite/testrc.py
raster/r.in.gdal/testsuite/test_r_in_gdal.py
raster/r.in.lidar/testsuite/test_base_resolution.sh
raster/r.in.lidar/testsuite/test_base_resolution.sh
Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ $(ARCH_DISTDIR)/%: %
$(INSTALL_DATA) $< $@

LIBDIRS = \
lib/external/parson \
lib/external/shapelib \
lib/datetime \
lib/gis \
Expand Down
2 changes: 1 addition & 1 deletion doc/infrastructure.md
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ User settings:

- The GRASS GIS CI user at Docker hub is "grassgis" (joined June 3, 2023),
see also <https://hub.docker.com/u/grassgis>
- Docker Hub access token are managed via grass-ci-admin@osgeo.org.
- Docker Hub access token are managed via <grass-ci-admin@osgeo.org>.
- The OSGeo Org membership is managed at <https://hub.docker.com/orgs>
through OSGeo-SAC

Expand Down
18 changes: 17 additions & 1 deletion grasslib.dox
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ href="https://grass.osgeo.org">https://grass.osgeo.org</a>
\subsection misclibs Miscellaneous Libraries

- datetime: \ref datetime (DateTime library)
- external: \ref external (External libraries from other projects such as shapelib and \ref ccmathlib)
- external: \ref external (External libraries from other projects such as shapelib, parson and \ref ccmathlib)
- fonts: \ref fonts (GRASS fonts library)
- init: \ref init (GRASS initialization code + scripts)
- iostream: \ref iostream (fast I/O library)
Expand All @@ -131,6 +131,22 @@ href="https://grass.osgeo.org">https://grass.osgeo.org</a>
- manage: \ref managelib
- symbol: \ref symbol (Drawing symbols for %point %vector data library)

\subsection external Adding External Libraries

The following files must be added or updated when including a new external library.

- <b>add:</b> lib/external/<b>newlib</b>
- <b>add:</b> lib/external/<b>newlib</b>/*.c
- <b>add:</b> lib/external/<b>newlib</b>/*.h
- <b>add:</b> lib/external/<b>newlib</b>/LICENSE
- <b>add:</b> lib/external/<b>newlib</b>/Makefile
- <b>update:</b> lib/external/Makefile
- <b>update:</b> lib/external/README.license
- <b>update:</b> lib/README.md
- <b>update:</b> include/Make/Install.make
- <b>update:</b> include/Make/Grass.make
- <b>update:</b> Makefile

\section location File structure of GRASS Location

A GRASS <b>raster map</b> consists of several files in several subdirectories in a mapset,
Expand Down
163 changes: 163 additions & 0 deletions gui/wxpython/core/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -1198,5 +1198,168 @@ def is_shell_running():
return True


def parse_mapcalc_cmd(command):
"""Parse r.mapcalc/r3.mapcalc module command
>>> parse_mapcalc_cmd(command="r.mapcalc map = 1")
"r.mapcalc expression='map = 1'"
>>> parse_mapcalc_cmd(command="r.mapcalc map = 1")
"r.mapcalc expression='map = 1'"
>>> parse_mapcalc_cmd(command="r.mapcalc map=1")
"r.mapcalc expression='map=1'"
>>> parse_mapcalc_cmd(command="r.mapcalc map = a - b")
"r.mapcalc expression='map = a - b'"
>>> parse_mapcalc_cmd(command="r.mapcalc expression=map = a - b")
"r.mapcalc expression='map = a - b'"
>>> parse_mapcalc_cmd(command="r.mapcalc expression=map = a - b")
"r.mapcalc expression='map = a - b'"
>>> cmd = "r.mapcalc expr='map = a - b' region=clip --overwrite"
>>> parse_mapcalc_cmd(command=cmd)
"r.mapcalc --overwrite expr='map = a - b' region=clip"
>>> cmd = 'r.mapcalc expr="map = a - b" region=clip --overwrite'
>>> parse_mapcalc_cmd(command=cmd)
"r.mapcalc --overwrite expr='map = a - b' region=clip"
>>> cmd = "r.mapcalc -s map = (a - b) / c region=clip --overwrite --verbose"
>>> parse_mapcalc_cmd(command=cmd)
"r.mapcalc -s --overwrite --verbose expression='map = (a - b) / c' region=clip"
>>> cmd = 'r.mapcalc e="map = 1" region=clip --overwrite'
>>> parse_mapcalc_cmd(command=cmd)
"r.mapcalc --overwrite e='map = 1' region=clip"
>>> cmd = 'r.mapcalc ex="map = 1" region=clip --overwrite'
>>> parse_mapcalc_cmd(command=cmd)
"r.mapcalc --overwrite ex='map = 1' region=clip"
>>> cmd = 'r.mapcalc exp="map = 1" region=clip --overwrite'
>>> parse_mapcalc_cmd(command=cmd)
"r.mapcalc --overwrite exp='map = 1' region=clip"
>>> cmd = 'r.mapcalc expr="map = 1" region=clip --overwrite'
>>> parse_mapcalc_cmd(command=cmd)
"r.mapcalc --overwrite expr='map = 1' region=clip"
>>> cmd = 'r.mapcalc expre="map = 1" region=clip --overwrite'
>>> parse_mapcalc_cmd(command=cmd)
"r.mapcalc --overwrite expre='map = 1' region=clip"
>>> cmd = 'r.mapcalc expres="map = 1" region=clip --overwrite'
>>> parse_mapcalc_cmd(command=cmd)
"r.mapcalc --overwrite expres='map = 1' region=clip"
>>> cmd = 'r.mapcalc express="map = 1" region=clip --overwrite'
>>> parse_mapcalc_cmd(command=cmd)
"r.mapcalc --overwrite express='map = 1' region=clip"
>>> cmd = 'r.mapcalc expressi="map = 1" region=clip --overwrite'
>>> parse_mapcalc_cmd(command=cmd)
"r.mapcalc --overwrite expressi='map = 1' region=clip"
>>> cmd = 'r.mapcalc expressio="map = 1" region=clip --overwrite'
>>> parse_mapcalc_cmd(command=cmd)
"r.mapcalc --overwrite expressio='map = 1' region=clip"
>>> cmd = 'r.mapcalc expression="map = 1" region=clip --overwrite'
>>> parse_mapcalc_cmd(command=cmd)
"r.mapcalc --overwrite expression='map = 1' region=clip"
>>> cmd = 'r.mapcalc exp="map = a + e" region=clip --overwrite'
>>> parse_mapcalc_cmd(command=cmd)
"r.mapcalc --overwrite exp='map = a + e' region=clip"
>>> cmd = 'r.mapcalc exp="map = a + exp(5)" region=clip --overwrite'
>>> parse_mapcalc_cmd(command=cmd)
"r.mapcalc --overwrite exp='map = a + exp(5)' region=clip"
:param str command: r.mapcalc command string
:return str: parsed r.mapcalc command string
"""
flags = []
others_params_args = []
expr_param_regex = re.compile(r"e.*?=")
flag_regex = re.compile(
r"^-[a-z]|^--overwrite|^--quiet|^--verbose|^--help|^--o|^--q|^--v|^--h",
)

command = split(command)
module = command.pop(0)

for arg in command[:]:
flag = flag_regex.search(arg)
if flag:
flags.append(command.pop(command.index(flag.group())))
elif "region=" in arg or "file=" in arg or "seed=" in arg:
others_params_args.append(command.pop(command.index(arg)))

cmd = " ".join(command)
expr_param = expr_param_regex.search(cmd)
if not expr_param:
expr_param_name = "expression="
else:
# Remove expression param
command = split(cmd.replace(expr_param.group(), ""))
expr_param_name = expr_param.group()
# Add quotes
if "'" not in cmd or '"' not in cmd:
cmd = f"'{' '.join(command)}'"
expression_param_arg = f"{expr_param_name}{cmd}"

return " ".join(
[
module,
*flags,
expression_param_arg,
*others_params_args,
]
)


def replace_module_cmd_special_flags(command):
"""Replace module command special flags short version with
full version
Flags:
--o -> --overwrite
--q -> --quiet
--v -> --verbose
--h -> --help
>>> cmd = "r.mapcalc -s --o --v expression='map = 1' region=clip"
>>> replace_module_cmd_special_flags(command=cmd)
"r.mapcalc -s --overwrite --verbose expression='map = 1' region=clip"
>>> cmd = "r.mapcalc -s --o --q expression='map = 1' region=clip"
>>> replace_module_cmd_special_flags(command=cmd)
"r.mapcalc -s --overwrite --quiet expression='map = 1' region=clip"
:param str command: module command string
:return str: module command string with replaced flags
"""
flags_regex = re.compile(
r"(--o(\s+|$))|(--q(\s+|$))|(--v(\s+|$))|(--h(\s+|$))",
)
replace = {
"--o": "--overwrite ",
"--q": "--quiet ",
"--v": "--verbose ",
"--h": "--help ",
}
return flags_regex.sub(
lambda flag: replace[flag.group().strip()],
command,
)


if __name__ == "__main__":
sys.exit(doc_test())
5 changes: 3 additions & 2 deletions gui/wxpython/gui_core/dialogs.py
Original file line number Diff line number Diff line change
Expand Up @@ -1933,6 +1933,7 @@ def __init__(
style=wx.DEFAULT_DIALOG_STYLE,
**kwargs,
):
img_size = kwargs.pop("img_size", None)
self.parent = parent

wx.Dialog.__init__(self, parent, id=id, style=style, title=title, **kwargs)
Expand All @@ -1946,11 +1947,11 @@ def __init__(
size = self.parent.GetWindow().GetClientSize()
self.width = SpinCtrl(parent=self.panel, id=wx.ID_ANY, style=wx.SP_ARROW_KEYS)
self.width.SetRange(20, 1e6)
self.width.SetValue(size.width)
self.width.SetValue(img_size[0] if img_size else size.width)
wx.CallAfter(self.width.SetFocus)
self.height = SpinCtrl(parent=self.panel, id=wx.ID_ANY, style=wx.SP_ARROW_KEYS)
self.height.SetRange(20, 1e6)
self.height.SetValue(size.height)
self.height.SetValue(img_size[1] if img_size else size.height)
self.template = wx.Choice(
parent=self.panel,
id=wx.ID_ANY,
Expand Down
37 changes: 35 additions & 2 deletions gui/wxpython/history/browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,14 @@

from core import globalvar
from core.gcmd import GError, GException
from core.utils import (
parse_mapcalc_cmd,
replace_module_cmd_special_flags,
split,
)
from gui_core.forms import GUI
from gui_core.treeview import CTreeView
from gui_core.wrap import SearchCtrl
from history.tree import HistoryBrowserTree

from grass.pydispatch.signal import Signal
Expand Down Expand Up @@ -57,11 +63,23 @@ def __init__(
lambda cmd: self.UpdateHistoryModelByCommand(cmd)
)

self.search = SearchCtrl(self)
self.search.SetDescriptiveText(_("Search"))
self.search.ShowCancelButton(True)
self.search.Bind(wx.EVT_TEXT, lambda evt: self.Filter(evt.GetString()))
self.search.Bind(wx.EVT_SEARCHCTRL_CANCEL_BTN, lambda evt: self.Filter(""))

self._layout()

def _layout(self):
"""Dialog layout"""
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(
self.search,
proportion=0,
flag=wx.ALL | wx.EXPAND,
border=5,
)
sizer.Add(
self._tree, proportion=1, flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=5
)
Expand Down Expand Up @@ -90,6 +108,18 @@ def _getSelectedNode(self):
def _refreshTree(self):
self._tree.SetModel(self._model.GetModel())

def Filter(self, text):
"""Filter history
:param str text: text string
"""
model = self._model.GetModel()
if text:
model = self._model.model.Filtered(key=["command"], value=text)
self._tree.SetModel(model)
else:
self._tree.SetModel(model)

def UpdateHistoryModelFromScratch(self):
"""Update the model from scratch and refresh the tree"""
self._model.CreateModel()
Expand All @@ -110,15 +140,18 @@ def Run(self, node=None):
node = node or self._getSelectedNode()
if node:
command = node.data["command"]
lst = re.split(r"\s+", command)
if (
globalvar.ignoredCmdPattern
and re.compile(globalvar.ignoredCmdPattern).search(command)
and "--help" not in command
and "--ui" not in command
):
self.runIgnoredCmdPattern.emit(cmd=lst)
self.runIgnoredCmdPattern.emit(cmd=split(command))
return
if re.compile(r"^r[3]?\.mapcalc").search(command):
command = parse_mapcalc_cmd(command)
command = replace_module_cmd_special_flags(command)
lst = split(command)
try:
GUI(parent=self, giface=self._giface).ParseCommand(lst)
except GException as e:
Expand Down
Loading

0 comments on commit 9d8c953

Please sign in to comment.