def test_default_mapset_does_not_exist(self): """Check that default mapset is found for non-existent path/location. The location (or mapset) do not exist. """ mapset_path = resolve_mapset_path(path="does/not/exist", location="does_not_exit") self.assertEqual(mapset_path.mapset, "PERMANENT")
def test_default_mapset_exists(self): """Check that default mapset is found for real path/location. The location (or mapset) may not exist, but exist in the test. """ db_path = call_module("g.gisenv", get="GISDBASE").strip() loc_name = call_module("g.gisenv", get="LOCATION_NAME").strip() mapset_path = resolve_mapset_path(path=db_path, location=loc_name) self.assertEqual(mapset_path.mapset, "PERMANENT")
def test_default_mapset_with_path(self): """Check that default mapset is found for path. This requires the location (with default mapset) to exists. """ db_path = call_module("g.gisenv", get="GISDBASE").strip() loc_name = call_module("g.gisenv", get="LOCATION_NAME").strip() mapset_path = resolve_mapset_path(path=Path(db_path) / loc_name) self.assertEqual(mapset_path.mapset, "PERMANENT")
def switch_mapset(self, path, location=None, mapset=None): """Switch to a mapset provided as a name or path. The mapset can be provided as a name, as a path, or as database, location, and mapset. Specifically, the *path* positional-only parameter can be either name of a mapset in the current location or a full path to a mapset. When location and mapset are provided using the additional parameters, the *path* parameter is path to a database. Raises ValueError if the mapset does not exist (e.g., when the name is misspelled or the mapset is invalid). """ # The method could be a function, but this is more general (would work even for # a non-global session). # pylint: disable=no-self-use # Functions needed only here. # pylint: disable=import-outside-toplevel from grass.grassdb.checks import ( get_mapset_invalid_reason, is_mapset_valid, mapset_exists, ) from grass.grassdb.manage import resolve_mapset_path # For only one parameter, try if it is a mapset in the current location to # support switching only by its name. gisenv = gs.gisenv() if ( not location and not mapset and mapset_exists( path=gisenv["GISDBASE"], location=gisenv["LOCATION_NAME"], mapset=path ) ): gs.run_command("g.gisenv", set=f"MAPSET={path}") return mapset_path = resolve_mapset_path(path=path, location=location, mapset=mapset) if not is_mapset_valid(mapset_path): raise ValueError( _("Mapset {path} is not valid: {reason}").format( path=mapset_path.path, reason=get_mapset_invalid_reason( mapset_path.directory, mapset_path.location, mapset_path.mapset ), ) ) # This requires direct session file modification using g.gisenv because # g.mapset locks the mapset which is not how init and finish behave. # For code simplicity, we just change all even when only mapset is changed. gs.run_command("g.gisenv", set=f"GISDBASE={mapset_path.directory}") gs.run_command("g.gisenv", set=f"LOCATION_NAME={mapset_path.location}") gs.run_command("g.gisenv", set=f"MAPSET={mapset_path.mapset}")
def test_mapset_from_path(self): """Check that a non-existing path is correctly parsed.""" path = "does/not/exist/" location_name = "test_location_A" mapset_name = "test_mapset_1" full_path = str(Path(path) / location_name / mapset_name) mapset_path = resolve_mapset_path(path=full_path) self.assertEqual(mapset_path.directory, str(Path(path).resolve())) self.assertEqual(mapset_path.location, location_name) self.assertEqual(mapset_path.mapset, mapset_name) self.assertEqual(mapset_path.path, Path(path).resolve() / location_name / mapset_name)
def test_mapset_from_parts(self): """Check that a non-existing path is correctly constructed.""" path = "does/not/exist" location_name = "test_location_A" mapset_name = "test_mapset_1" mapset_path = resolve_mapset_path(path=path, location=location_name, mapset=mapset_name) self.assertEqual(mapset_path.directory, str(Path(path).resolve())) self.assertEqual(mapset_path.location, location_name) self.assertEqual(mapset_path.mapset, mapset_name) self.assertEqual(mapset_path.path, Path(path).resolve() / location_name / mapset_name)
def init(path, location=None, mapset=None, grass_path=None): """Initialize system variables to run GRASS modules This function is for running GRASS GIS without starting it with the standard main executable grass. No GRASS modules shall be called before call of this function but any module or user script can be called afterwards because a GRASS session has been set up. GRASS Python libraries are usable as well in general but the ones using C libraries through ``ctypes`` are not (which is caused by library path not being updated for the current process which is a common operating system limitation). When the path or specified mapset does not exist, ValueError is raised. The :func:`get_install_path` function is used to determine where the rest of GRASS files is installed. The *grass_path* parameter is passed to it if provided. If the path cannot be determined, ValueError is raised. Exceptions from the underlying function are propagated. To create a GRASS session a session file (aka gisrc file) is created. Caller is responsible for deleting the file which is normally done with the function :func:`finish`. Basic usage:: # ... setup GISBASE and sys.path before import import grass.script as gs gs.setup.init( "~/grassdata/nc_spm_08/user1", grass_path="/usr/lib/grass", ) # ... use GRASS modules here # end the session gs.setup.finish() :param path: path to GRASS database :param location: location name :param mapset: mapset within given location (default: 'PERMANENT') :param grass_path: path to GRASS installation or executable :returns: path to ``gisrc`` file (may change in future versions) """ grass_path = get_install_path(grass_path) if not grass_path: raise ValueError( _("Parameter grass_path or GISBASE environmental variable must be set") ) # We reduce the top-level imports because this is initialization code. # pylint: disable=import-outside-toplevel from grass.grassdb.checks import get_mapset_invalid_reason, is_mapset_valid from grass.grassdb.manage import resolve_mapset_path # Support ~ in the path for user home directory. path = Path(path).expanduser() # A simple existence test. The directory, whatever it is, should exist. if not path.exists(): raise ValueError(_("Path '{path}' does not exist").format(path=path)) # A specific message when it exists, but it is a file. if path.is_file(): raise ValueError( _("Path '{path}' is a file, but a directory is needed").format(path=path) ) mapset_path = resolve_mapset_path(path=path, location=location, mapset=mapset) if not is_mapset_valid(mapset_path): raise ValueError( _("Mapset {path} is not valid: {reason}").format( path=mapset_path.path, reason=get_mapset_invalid_reason( mapset_path.directory, mapset_path.location, mapset_path.mapset ), ) ) setup_runtime_env(grass_path) # TODO: lock the mapset? os.environ["GIS_LOCK"] = str(os.getpid()) os.environ["GISRC"] = write_gisrc( mapset_path.directory, mapset_path.location, mapset_path.mapset ) return os.environ["GISRC"]