diff --git a/evennia/__init__.py b/evennia/__init__.py index e04ab84dba..ab23ff7abf 100644 --- a/evennia/__init__.py +++ b/evennia/__init__.py @@ -105,7 +105,7 @@ def _create_version(): print(err) try: version = "%s (rev %s)" % (version, check_output("git rev-parse --short HEAD", shell=True, cwd=root, stderr=STDOUT).strip()) - except (IOError, CalledProcessError): + except (IOError, CalledProcessError, WindowsError): # ignore if we cannot get to git pass return version diff --git a/evennia/prototypes/protfuncs.py b/evennia/prototypes/protfuncs.py index a13aa7e532..e222876221 100644 --- a/evennia/prototypes/protfuncs.py +++ b/evennia/prototypes/protfuncs.py @@ -37,12 +37,15 @@ prototype key (this value must be possible to serialize in an Attribute). from ast import literal_eval from random import randint as base_randint, random as base_random, choice as base_choice +import re from evennia.utils import search from evennia.utils.utils import justify as base_justify, is_iter, to_str _PROTLIB = None +_RE_DBREF = re.compile(r"\#[0-9]+") + # default protfuncs @@ -325,3 +328,14 @@ def objlist(*args, **kwargs): """ return ["#{}".format(obj.id) for obj in _obj_search(return_list=True, *args, **kwargs)] + + +def dbref(*args, **kwargs): + """ + Usage $dbref(<#dbref>) + Returns one Object searched globally by #dbref. Error if #dbref is invalid. + """ + if not args or len(args) < 1 or _RE_DBREF.match(args[0]) is None: + raise ValueError('$dbref requires a valid #dbref argument.') + + return obj(args[0]) diff --git a/evennia/prototypes/prototypes.py b/evennia/prototypes/prototypes.py index 833316cf59..a3281777e0 100644 --- a/evennia/prototypes/prototypes.py +++ b/evennia/prototypes/prototypes.py @@ -5,7 +5,6 @@ Handling storage of prototypes, both database-based ones (DBPrototypes) and thos """ -import re import hashlib import time from ast import literal_eval @@ -33,8 +32,6 @@ _PROTOTYPE_TAG_CATEGORY = "from_prototype" _PROTOTYPE_TAG_META_CATEGORY = "db_prototype" PROT_FUNCS = {} -_RE_DBREF = re.compile(r"(?') + mocked__obj_search.assert_not_called() + + with mock.patch("evennia.prototypes.protfuncs._obj_search", wraps=protofuncs._obj_search) as mocked__obj_search: + self.assertRaises(ValueError, protlib.protfunc_parser, "$dbref(Char)") + mocked__obj_search.assert_not_called() + self.assertEqual(protlib.value_to_obj( protlib.protfunc_parser("#6", session=self.session)), self.char1) diff --git a/evennia/server/evennia_launcher.py b/evennia/server/evennia_launcher.py index 50c355dc58..6387055736 100644 --- a/evennia/server/evennia_launcher.py +++ b/evennia/server/evennia_launcher.py @@ -98,7 +98,10 @@ TWISTED_MIN = '18.0.0' DJANGO_MIN = '1.11' DJANGO_REC = '1.11' -sys.path[1] = EVENNIA_ROOT +try: + sys.path[1] = EVENNIA_ROOT +except IndexError: + sys.path.append(EVENNIA_ROOT) # ------------------------------------------------------------ # @@ -274,7 +277,7 @@ INFO_WINDOWS_BATFILE = \ twistd.bat to point to the actual location of the Twisted executable (usually called twistd.py) on your machine. - This procedure is only done once. Run evennia.py again when you + This procedure is only done once. Run `evennia` again when you are ready to start the server. """ @@ -1214,7 +1217,7 @@ def evennia_version(): "git rev-parse --short HEAD", shell=True, cwd=EVENNIA_ROOT, stderr=STDOUT).strip() version = "%s (rev %s)" % (version, rev) - except (IOError, CalledProcessError): + except (IOError, CalledProcessError, WindowsError): # move on if git is not answering pass return version @@ -1641,7 +1644,7 @@ def error_check_python_modules(): # # ------------------------------------------------------------ -def init_game_directory(path, check_db=True): +def init_game_directory(path, check_db=True, need_gamedir=True): """ Try to analyze the given path to find settings.py - this defines the game directory and also sets PYTHONPATH as well as the django @@ -1650,15 +1653,17 @@ def init_game_directory(path, check_db=True): Args: path (str): Path to new game directory, including its name. check_db (bool, optional): Check if the databae exists. + need_gamedir (bool, optional): set to False if Evennia doesn't require to be run in a valid game directory. """ # set the GAMEDIR path - set_gamedir(path) + if need_gamedir: + set_gamedir(path) # Add gamedir to python path sys.path.insert(0, GAMEDIR) - if TEST_MODE: + if TEST_MODE or not need_gamedir: if ENFORCED_SETTING: print(NOTE_TEST_CUSTOM.format(settings_dotpath=SETTINGS_DOTPATH)) os.environ['DJANGO_SETTINGS_MODULE'] = SETTINGS_DOTPATH @@ -1685,6 +1690,10 @@ def init_game_directory(path, check_db=True): if check_db: check_database() + # if we don't have to check the game directory, return right away + if not need_gamedir: + return + # set up the Evennia executables and log file locations global AMP_PORT, AMP_HOST, AMP_INTERFACE global SERVER_PY_FILE, PORTAL_PY_FILE @@ -2088,6 +2097,10 @@ def main(): elif option != "noop": # pass-through to django manager check_db = False + need_gamedir = True + # some commands don't require the presence of a game directory to work + if option in ('makemessages', 'compilemessages'): + need_gamedir = False # handle special django commands if option in ('runserver', 'testserver'): @@ -2100,7 +2113,7 @@ def main(): global TEST_MODE TEST_MODE = True - init_game_directory(CURRENT_DIR, check_db=check_db) + init_game_directory(CURRENT_DIR, check_db=check_db, need_gamedir=need_gamedir) # pass on to the manager args = [option] @@ -2116,6 +2129,11 @@ def main(): kwargs[arg.lstrip("--")] = value else: args.append(arg) + + # makemessages needs a special syntax to not conflict with the -l option + if len(args) > 1 and args[0] == "makemessages": + args.insert(1, "-l") + try: django.core.management.call_command(*args, **kwargs) except django.core.management.base.CommandError as exc: diff --git a/evennia/settings_default.py b/evennia/settings_default.py index 6fb053f1a7..be06f46f7f 100644 --- a/evennia/settings_default.py +++ b/evennia/settings_default.py @@ -117,7 +117,7 @@ AMP_INTERFACE = '127.0.0.1' EVENNIA_DIR = os.path.dirname(os.path.abspath(__file__)) # Path to the game directory (containing the server/conf/settings.py file) # This is dynamically created- there is generally no need to change this! -if sys.argv[1] == 'test' if len(sys.argv) > 1 else False: +if EVENNIA_DIR.lower() == os.getcwd().lower() or (sys.argv[1] == 'test' if len(sys.argv) > 1 else False): # unittesting mode GAME_DIR = os.getcwd() else: