diff --git a/python/grass/app/cli.py b/python/grass/app/cli.py index b8b41afa8e4..6dd217fc57f 100644 --- a/python/grass/app/cli.py +++ b/python/grass/app/cli.py @@ -27,6 +27,7 @@ import grass.script as gs from grass.app.data import lock_mapset, unlock_mapset, MapsetLockingException +from grass.grassdb.create import create_mapset from grass.exceptions import ScriptError from grass.tools import Tools @@ -91,6 +92,24 @@ def subcommand_create_project(args) -> int: return 0 +def add_mapset_subparser(subparsers): + mapset_subparser = subparsers.add_parser("mapset", help="mapset related operations") + mapset_subparsers = mapset_subparser.add_subparsers(dest="mapset_command") + + subparser = mapset_subparsers.add_parser("create", help="create a new mapset") + subparser.add_argument("path", help="path to the new mapset") + subparser.set_defaults(func=subcommand_mapset_create) + + +def subcommand_mapset_create(args) -> int: + try: + create_mapset(args.path) + except (ScriptError, OSError) as error: + print(_("Error creating mapset: {}").format(error), file=sys.stderr) + return 1 + return 0 + + def subcommand_lock_mapset(args): gs.setup.setup_runtime_env() try: @@ -201,6 +220,7 @@ def main(args=None, program=None): run_subparser.set_defaults(func=subcommand_run_tool) add_project_subparser(subparsers) + add_mapset_subparser(subparsers) subparser = subparsers.add_parser("lock", help="lock a mapset") subparser.add_argument("mapset_path", type=str) diff --git a/python/grass/app/tests/grass_app_cli_test.py b/python/grass/app/tests/grass_app_cli_test.py index afc98037b4d..2fc6b53832e 100644 --- a/python/grass/app/tests/grass_app_cli_test.py +++ b/python/grass/app/tests/grass_app_cli_test.py @@ -129,6 +129,99 @@ def test_subcommand_run_with_crs_as_pack_subprocess(pack_raster_file4x5_rows, ca assert json.loads(result.stdout)["srid"] == "EPSG:3358" +def test_create_mapset(tmp_path): + """Check that we can create mapset and we can set its computational region""" + project = tmp_path / "test_1" + mapset = project / "data_1" + assert main(["project", "create", str(project), "--crs", "EPSG:3358"]) == 0 + assert main(["mapset", "create", str(mapset)]) == 0 + assert mapset.exists() + assert mapset.is_dir() + rows = 13 + cols = 17 + assert ( + main( + [ + "run", + "--project", + str(mapset), + "g.region", + f"rows={rows}", + f"cols={cols}", + ] + ) + == 0 + ) + result = subprocess.run( + [ + sys.executable, + "-m", + "grass.app", + "run", + "--project", + str(mapset), + "g.region", + "-p", + "format=json", + ], + capture_output=True, + text=True, + check=True, + ) + region = json.loads(result.stdout) + assert region["rows"] == rows + assert region["cols"] == cols + # Also check it is linked with the project. + result = subprocess.run( + [ + sys.executable, + "-m", + "grass.app", + "run", + "--project", + str(mapset), + "g.proj", + "-p", + "format=json", + ], + capture_output=True, + text=True, + check=True, + ) + assert json.loads(result.stdout)["srid"] == "EPSG:3358" + # And check that we are really using the newly created mapset, + # so the computational region in the default mapset is different. + result = subprocess.run( + [ + sys.executable, + "-m", + "grass.app", + "run", + "--project", + str(project), + "g.region", + "-p", + "format=json", + ], + capture_output=True, + text=True, + check=True, + ) + region = json.loads(result.stdout) + assert region["rows"] == 1 + assert region["cols"] == 1 + + +def test_mapset_create_exists(tmp_path): + """Check that creating mapset fails when mapset already exists""" + project = tmp_path / "test_1" + mapset = project / "data_1" + assert main(["project", "create", str(project)]) == 0 + assert main(["mapset", "create", str(mapset)]) == 0 + assert main(["mapset", "create", str(mapset)]) == 1 + # There is no overwrite option for mapset yet, so we don't test that. + + def test_create_overwrite(tmp_path): """Check that creating when project exists fails unless overwrite is True""" project = tmp_path / "test_1" diff --git a/python/grass/grassdb/create.py b/python/grass/grassdb/create.py index c1b00031504..6dba94e1af3 100644 --- a/python/grass/grassdb/create.py +++ b/python/grass/grassdb/create.py @@ -103,7 +103,7 @@ def _directory_to_mapset(path: MapsetPath): shutil.copy(region_path1, region_path2) -def create_mapset(database, location, mapset): +def create_mapset(database, location=None, mapset=None): """Creates a mapset in a specified location""" path = resolve_mapset_path( database,