Skip to content

Conversation

wenzeslaus
Copy link
Member

@wenzeslaus wenzeslaus commented Oct 2, 2025

The lock and unlock subcommands are operating on a mapset and are low-level (they specifically just lock and unlock and don't do anything with any session). So, this is moving them under a new top-level subcommand mapset.

With the lock subcommands being accessible outside of GRASS through CLI without a Python API or a GRASS tools (with or without #6442), other applications which can call subprocesses (such as QGIS) can use GRASS locking when accessing GRASS mapsets.

This is using the new structure in the cli.py file with parser definitions having their own functions (minimizing name conflicts between parses and keeping the main function short), but additionally the interface and execution code are placed together because they would be changed at the same time.

Waiting for #6462: Additionally, for symmetry with project create, this adds a new mapset create subcommand which is used in the test. The creation uses the semi-internal function grass.grassdb.create.create_mapset. The function parameters were adjusted to allow for a single path being provided (which was already supported through path resolution function).

Examples

Assuming #6442 in the examples to simply the commands, but setting up PYTHONPATH and using python -m grass.app would work too.

grass mapset lock

$ grass project create /tmp/project_1
$ grass mapset create /tmp/project_1/work_2
$ grass mapset lock /tmp/project_1/work_2
$ grass mapset lock /tmp/project_1/work_2
Mapset <.../project_1/work_2> locked (attempt 1), but will retry in 1.00 seconds...
Mapset <.../project_1/work_2> locked (attempt 2), but will retry in 2.00 seconds...
Mapset <.../project_1/work_2> locked (attempt 3), but will retry in 4.00 seconds...
Mapset <.../project_1/work_2> locked (attempt 4), but will retry in 8.00 seconds...
Mapset <.../project_1/work_2> locked (attempt 5), but will retry in 15.00 seconds...
Selected mapset is currently being used by another GRASS session. File /tmp/project_1/work_2/.gislock owned by vpetras found. Concurrent access to a mapset is not allowed. However, you can either use another mapset within the same project or remove the lock if you are sure that no other session is active.
On the command line, you can force GRASS to start by using the -f flag.
In Python, you can start a session with force_unlock=True.
Make sure you have sufficient access permissions to remove the lock file. You may want to use a process manager to check that no other process is using the mapset.
$ grass mapset unlock /tmp/project_1/work_2

grass mapset create (with grass project create)

$ grass project create /tmp/project_2 --crs EPSG:3358
$ grass run --project /tmp/project_2 g.proj -p format=json | jq
{
  "name": "NAD83(HARN) / North Carolina",
  "datum": "nad83harn",
  "ellps": "grs80",
  "proj": "lcc",
  "lat_0": "33.75",
  "lon_0": "-79",
  "lat_1": "36.1666666666667",
  "lat_2": "34.3333333333333",
  "x_0": "609601.22",
  "y_0": "0",
  "no_defs": "defined",
  "srid": "EPSG:3358",
  "unit": "meter",
  "units": "meters",
  "meters": "1"
}
$ grass mapset create /tmp/project_2/work_1
$ grass run --project /tmp/project_2/work_1 g.mapset -p format=json | jq
{
  "project": "project_2",
  "mapset": "work_1"
}

This enables access to the subcommands from the main command. It keeps the commands not documeneted at the top level, so they remain hidden and experimental.

The lock and unlock, now under 'grass mapset lock' and 'grass mapset unlock', are accessible from outside of GRASS through CLI (no Python API or GRASS tools), providing a way of other applications (such as QGIS) to use GRASS locking when accessing GRASS mapsets.

Given that lock and unlock are under mapset (they are too low level to be at subcommand top level), it is clear there should be also project. The create_project function is readily available for CLI use (espetially after OSGeo#6415), so it is now under 'grass project create' and the subcommand is utilized in tests.

For symmetry, this adds also 'grass mapset create' which uses the semi-internal function grass.grassdb.create.create_mapset. The function parameters were adjusted to allow for a single path being provided (which was already supported through path resolution function).

The create_project function was also improved by adding description parameter as full word replacing (but keeping) desc parameter. The behavior was sligtly changes so that MYNAME is only created when description is provided which is what the documenetation suggests ('desc...creates MYNAME file'), but it was implemented that MYNAME was always created even if empty. Finally, missing documentation for the CRS parameter was added.

The new structure in the cli file is that project and mapset subcommand parser definitions have their own functions. This minimizes name conflicts and keeps the main function short.

Finally, 'grass run' subcommad now has --project to use an existing project (defaulting to PERMANENT mapset) or a mapset within that project. This is needed now for testing the created project using the subcommand interface.
@github-actions github-actions bot added Python Related code is in Python libraries tests Related to Test Suite labels Oct 2, 2025
@wenzeslaus wenzeslaus marked this pull request as draft October 3, 2025 02:56
@wenzeslaus
Copy link
Member Author

This is now a draft because I moves some of the pieces to separate PRs, but this now depends on these PRs and it will also need little more cleanup.

@wenzeslaus wenzeslaus changed the title grass.app: Enable lock subcommands, add project create grass.app: Enable lock subcommands, add mapset create Oct 3, 2025
wenzeslaus added a commit that referenced this pull request Oct 3, 2025
This adds description parameter to create_project as a full word replacing (but keeping) the desc parameter.

The behavior slightly changes so that MYNAME (project description file) is only created when description is provided. This is what the current documentation suggests ('desc...creates MYNAME file'), but it was implemented that MYNAME was always created even if empty.

The description file is now created for empty text (description is empty), but not for None (no description).

This is a project description specific part of #6437.
wenzeslaus added a commit that referenced this pull request Oct 3, 2025
The create_project function is readily available for CLI use especially with the new crs parameter (added in #6415), so this is adding the functionality under as `project create` subcommand. All create_project parameters are exposed, so the user is not limited to what crs parameter can currently handle.

This will be useful in tests of the subcommand CLI itself if we want to use the other subcommands rather than the Python functions in the tests (of subcommands). It is used for lock and unlock tests in #6437.

A --project parameter is added to the run subcommand which now can use existing project instead of creating a new one. This makes subcommand `run --project project/path ...` roughly equivalent to `grass project/path --exec ...`. The functionality is used in the test to check the resulting project CRS.

Example subcomands:
project create --crs EPSG:3358 /tmp/project_1
run --project /tmp/project_1 g.mapset -p

Adds missing documentation for crs parameter of create_project. Also, this uses the description parameter from #6440 not desc.

Implementation of the subcommand now uses StackExit context manager to handle the only-sometimes-needed temporary directory.
@wenzeslaus wenzeslaus changed the title grass.app: Enable lock subcommands, add mapset create grass.app: Move lock to mapset subcommand, add create Oct 4, 2025
@wenzeslaus wenzeslaus marked this pull request as ready for review October 4, 2025 02:52
@wenzeslaus wenzeslaus marked this pull request as draft October 6, 2025 03:35
@wenzeslaus wenzeslaus changed the title grass.app: Move lock to mapset subcommand, add create grass.app: Move lock to mapset subcommand Oct 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libraries Python Related code is in Python tests Related to Test Suite
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant