[Resolve merge conflicts

This commit is contained in:
Griatch 2020-09-19 14:19:40 +02:00
commit 443310b1c4
22 changed files with 76 additions and 129 deletions

View file

@ -1,7 +1,7 @@
# This Evennia workflow will install Python dependencies, run tests with a variety of Python versions # This Evennia workflow will install Python dependencies, run tests with a variety of Python versions
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions # For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
name: Evennia test-suite and coveralls name: test-suite
on: on:
push: push:
@ -14,11 +14,10 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
fail-fast: false
matrix: matrix:
python-version: [3.7, 3.8] python-version: [3.7, 3.8]
# TODO: mysql disabled, not able to connect to it so far TESTING_DB: ['sqlite3', 'postgresql', 'mysql']
TESTING_DB: ['sqlite3', 'postgresql'] # , 'mysql']
fail-fast: False
steps: steps:
@ -36,7 +35,7 @@ jobs:
uses: mirromutth/mysql-action@v1.1 uses: mirromutth/mysql-action@v1.1
if: ${{ matrix.TESTING_DB == 'mysql'}} if: ${{ matrix.TESTING_DB == 'mysql'}}
with: with:
mysql version: '5.7' host port: 3306
character set server: 'utf8mb4' character set server: 'utf8mb4'
collation server: 'utf8mb4_unicode_ci' collation server: 'utf8mb4_unicode_ci'
mysql database: 'evennia' mysql database: 'evennia'
@ -72,10 +71,10 @@ jobs:
- name: Install extra dependencies - name: Install extra dependencies
run: pip install -r requirements_extra.txt run: pip install -r requirements_extra.txt
- name: Install and initialize evennia - name: Initialize evennia
run: | run: |
evennia --init testing_mygame evennia --init testing_mygame
cp .travis/${{ matrix.TESTING_DB }}_settings.py testing_mygame/server/conf/settings.py cp .github/workflows/${{ matrix.TESTING_DB }}_settings.py testing_mygame/server/conf/settings.py
cd testing_mygame cd testing_mygame
evennia migrate evennia migrate
evennia collectstatic --noinput evennia collectstatic --noinput
@ -86,7 +85,9 @@ jobs:
coverage run --source=../evennia --omit=*/migrations/*,*/urls.py,*/test*.py,*.sh,*.txt,*.md,*.pyc,*.service ../bin/unix/evennia test --settings=settings --keepdb evennia coverage run --source=../evennia --omit=*/migrations/*,*/urls.py,*/test*.py,*.sh,*.txt,*.md,*.pyc,*.service ../bin/unix/evennia test --settings=settings --keepdb evennia
coverage xml coverage xml
# we only want to run coverall once, so we only do it for one of the matrix combinations # we only want to run coverall/codacy once, so we only do it for one of the matrix combinations
# it's also not critical if pushing to either service fails (happens for PRs since env is not
# available outside of the evennia org)
- name: Send data to Coveralls - name: Send data to Coveralls
if: ${{ matrix.TESTING_DB == 'sqlite3' && matrix.python-version == 3.7 }} if: ${{ matrix.TESTING_DB == 'sqlite3' && matrix.python-version == 3.7 }}
continue-on-error: true continue-on-error: true
@ -95,6 +96,7 @@ jobs:
run: | run: |
cd testing_mygame cd testing_mygame
coveralls coveralls
- name: Send data to Codacy - name: Send data to Codacy
if: ${{ matrix.TESTING_DB == 'sqlite3' && matrix.python-version == 3.7 }} if: ${{ matrix.TESTING_DB == 'sqlite3' && matrix.python-version == 3.7 }}
continue-on-error: true continue-on-error: true

View file

@ -44,18 +44,17 @@ DATABASES = {
"NAME": "evennia", "NAME": "evennia",
"USER": "evennia", "USER": "evennia",
"PASSWORD": "password", "PASSWORD": "password",
"HOST": "localhost", "HOST": "127.0.0.1",
"PORT": "", # use default port "PORT": "", # use default port
"OPTIONS": { "OPTIONS": {
"charset": "utf8mb4", "charset": "utf8mb4",
"init_command": "set collation_connection=utf8mb4_unicode_ci", "init_command": "set collation_connection=utf8mb4_unicode_ci",
}, },
"TEST": { "TEST": {
"NAME": "default", "NAME": "evennia",
"OPTIONS": { "OPTIONS": {
"charset": "utf8mb4", "charset": "utf8mb4",
# 'init_command': 'set collation_connection=utf8mb4_unicode_ci' "init_command": "set collation_connection=utf8mb4_unicode_ci",
"init_command": "SET NAMES 'utf8mb4'",
}, },
}, },
} }

View file

@ -1,52 +0,0 @@
dist: xenial
language: python
cache: pip
services:
- postgresql
- mysql
python:
- "3.7"
- "3.8"
env:
- TESTING_DB=sqlite3
- TESTING_DB=postgresql
- TESTING_DB=mysql
before_install:
# - psql -U postgres -c "GRANT ALL PRIVILEGES ON DATABASE evennia TO evennia;"
- psql --version
- psql -U postgres -c "CREATE DATABASE evennia;"
- psql -U postgres -c "CREATE USER evennia WITH PASSWORD 'password';"
- psql -U postgres -c "ALTER USER evennia CREATEDB;"
- mysql --version
- mysql -u root -e "CREATE DATABASE evennia CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
- mysql -u root -e "CREATE USER 'evennia'@'localhost' IDENTIFIED BY 'password';"
- mysql -u root -e "GRANT ALL ON *.* TO 'evennia'@'localhost' IDENTIFIED BY 'password';"
install:
- pip install psycopg2-binary
- pip install mysqlclient
- pip install coveralls
- pip install codacy-coverage
- pip install -e .
- pip install -r requirements_extra.txt
before_script:
- make format
- evennia --init testing_mygame
- cp .travis/${TESTING_DB}_settings.py testing_mygame/server/conf/settings.py
- cd testing_mygame
- evennia migrate
- evennia collectstatic --noinput
script:
- coverage run --source=../evennia --omit=*/migrations/*,*/urls.py,*/test*.py,*.sh,*.txt,*.md,*.pyc,*.service ../bin/unix/evennia test --settings=settings --keepdb evennia
after_success:
- coveralls
- coverage xml
- python-codacy-coverage -r coverage.xml

View file

@ -1 +0,0 @@
init_connect='SET collation_connection = utf8_general_ci; SET NAMES utf8;'

View file

@ -1,5 +1,6 @@
# Evennia MUD/MU\* Creation System ![evennia logo][logo] # Evennia MUD/MU\* Creation System ![evennia logo][logo]
[![Build Status][travisimg]][travislink] [![Coverage Status][coverimg]][coverlink] [![Build Status][unittestciimg]][unittestcilink] [![Coverage Status][coverimg]][coverlink]
*Evennia* is a modern library for creating [online multiplayer text *Evennia* is a modern library for creating [online multiplayer text
games][wikimudpage] (MUD, MUSH, MUX, MUCK, MOO etc) in pure Python. It games][wikimudpage] (MUD, MUSH, MUX, MUCK, MOO etc) in pure Python. It
@ -69,8 +70,8 @@ Welcome!
[wiki]: https://github.com/evennia/evennia/wiki [wiki]: https://github.com/evennia/evennia/wiki
[screenshot]: https://user-images.githubusercontent.com/294267/30773728-ea45afb6-a076-11e7-8820-49be2168a6b8.png [screenshot]: https://user-images.githubusercontent.com/294267/30773728-ea45afb6-a076-11e7-8820-49be2168a6b8.png
[logo]: https://github.com/evennia/evennia/blob/master/evennia/web/website/static/website/images/evennia_logo.png [logo]: https://github.com/evennia/evennia/blob/master/evennia/web/website/static/website/images/evennia_logo.png
[travisimg]: https://travis-ci.org/evennia/evennia.svg?branch=master [unittestciimg]: https://github.com/evennia/evennia/workflows/test-suite/badge.svg
[travislink]: https://travis-ci.org/evennia/evennia [unittestcilink]: https://github.com/evennia/evennia/actions?query=workflow%3Atest-suite
[coverimg]: https://coveralls.io/repos/github/evennia/evennia/badge.svg?branch=master [coverimg]: https://coveralls.io/repos/github/evennia/evennia/badge.svg?branch=master
[coverlink]: https://coveralls.io/github/evennia/evennia?branch=master [coverlink]: https://coveralls.io/github/evennia/evennia?branch=master
[introduction]: https://github.com/evennia/evennia/wiki/Evennia-Introduction [introduction]: https://github.com/evennia/evennia/wiki/Evennia-Introduction

View file

@ -3077,6 +3077,7 @@ class CmdScript(COMMAND_DEFAULT_CLASS):
elif not self.switches: elif not self.switches:
# view all scripts # view all scripts
from evennia.commands.default.system import ScriptEvMore from evennia.commands.default.system import ScriptEvMore
ScriptEvMore(self.caller, scripts.order_by("id"), session=self.session) ScriptEvMore(self.caller, scripts.order_by("id"), session=self.session)
return return
elif "start" in self.switches: elif "start" in self.switches:

View file

@ -40,7 +40,6 @@ __all__ = (
"CmdIRCStatus", "CmdIRCStatus",
"CmdRSS2Chan", "CmdRSS2Chan",
"CmdGrapevine2Chan", "CmdGrapevine2Chan",
) )
_DEFAULT_WIDTH = settings.CLIENT_DEFAULT_WIDTH _DEFAULT_WIDTH = settings.CLIENT_DEFAULT_WIDTH

View file

@ -441,7 +441,7 @@ class ScriptEvMore(EvMore):
"|wdesc|n", "|wdesc|n",
align="r", align="r",
border="tablecols", border="tablecols",
width=self.width width=self.width,
) )
for script in scripts: for script in scripts:
@ -572,7 +572,7 @@ class CmdScripts(COMMAND_DEFAULT_CLASS):
caller.msg(string) caller.msg(string)
else: else:
# No stopping or validation. We just want to view things. # No stopping or validation. We just want to view things.
ScriptEvMore(caller, scripts.order_by('id'), session=self.session) ScriptEvMore(caller, scripts.order_by("id"), session=self.session)
class CmdObjects(COMMAND_DEFAULT_CLASS): class CmdObjects(COMMAND_DEFAULT_CLASS):

View file

@ -1252,7 +1252,6 @@ class TestBuilding(CommandTest):
) )
def test_spawn(self): def test_spawn(self):
def get_object(commandTest, obj_key): def get_object(commandTest, obj_key):
# A helper function to get a spawned object and # A helper function to get a spawned object and
# check that it exists in the process. # check that it exists in the process.

View file

@ -167,8 +167,9 @@ for mod in settings.PROTOTYPE_MODULES:
if "prototype_locks" in prot if "prototype_locks" in prot
else "use:all();edit:false()" else "use:all();edit:false()"
), ),
"prototype_tags": list(set(list( "prototype_tags": list(
make_iter(prot.get("prototype_tags", []))) + ["module"])), set(list(make_iter(prot.get("prototype_tags", []))) + ["module"])
),
} }
) )
_MODULE_PROTOTYPES[actual_prot_key] = prot _MODULE_PROTOTYPES[actual_prot_key] = prot
@ -392,35 +393,23 @@ def search_prototype(key=None, tags=None, require_single=False, return_iterators
# exact match on tag(s) # exact match on tag(s)
tags = make_iter(tags) tags = make_iter(tags)
tag_categories = ["db_prototype" for _ in tags] tag_categories = ["db_prototype" for _ in tags]
db_matches = DbPrototype.objects.get_by_tag( db_matches = DbPrototype.objects.get_by_tag(tags, tag_categories)
tags, tag_categories)
else: else:
db_matches = DbPrototype.objects.all() db_matches = DbPrototype.objects.all()
if key: if key:
# exact or partial match on key # exact or partial match on key
exact_match = ( exact_match = db_matches.filter(Q(db_key__iexact=key)).order_by("db_key")
db_matches
.filter(
Q(db_key__iexact=key))
.order_by("db_key")
)
if not exact_match: if not exact_match:
# try with partial match instead # try with partial match instead
db_matches = ( db_matches = db_matches.filter(Q(db_key__icontains=key)).order_by("db_key")
db_matches
.filter(
Q(db_key__icontains=key))
.order_by("db_key")
)
else: else:
db_matches = exact_match db_matches = exact_match
# convert to prototype # convert to prototype
db_ids = db_matches.values_list("id", flat=True) db_ids = db_matches.values_list("id", flat=True)
db_matches = ( db_matches = (
Attribute.objects Attribute.objects.filter(scriptdb__pk__in=db_ids, db_key="prototype")
.filter(scriptdb__pk__in=db_ids, db_key="prototype")
.values_list("db_value", flat=True) .values_list("db_value", flat=True)
.order_by("scriptdb__db_key") .order_by("scriptdb__db_key")
) )
@ -517,7 +506,7 @@ class PrototypeEvMore(EvMore):
"|wDesc|n", "|wDesc|n",
border="tablecols", border="tablecols",
crop=True, crop=True,
width=self.width width=self.width,
) )
for prototype in page: for prototype in page:
@ -554,8 +543,9 @@ class PrototypeEvMore(EvMore):
return str(table) return str(table)
def list_prototypes(caller, key=None, tags=None, show_non_use=False, def list_prototypes(
show_non_edit=True, session=None): caller, key=None, tags=None, show_non_use=False, show_non_edit=True, session=None
):
""" """
Collate a list of found prototypes based on search criteria and access. Collate a list of found prototypes based on search criteria and access.
@ -581,10 +571,14 @@ def list_prototypes(caller, key=None, tags=None, show_non_use=False,
return None return None
# get specific prototype (one value or exception) # get specific prototype (one value or exception)
return PrototypeEvMore(caller, (dbprot_query, modprot_list), return PrototypeEvMore(
caller,
(dbprot_query, modprot_list),
session=session, session=session,
show_non_use=show_non_use, show_non_use=show_non_use,
show_non_edit=show_non_edit) show_non_edit=show_non_edit,
)
def validate_prototype( def validate_prototype(
prototype, protkey=None, protparents=None, is_prototype_base=True, strict=True, _flags=None prototype, protkey=None, protparents=None, is_prototype_base=True, strict=True, _flags=None

View file

@ -630,10 +630,8 @@ class TestPrototypeStorage(EvenniaTest):
# partial match # partial match
with mock.patch("evennia.prototypes.prototypes._MODULE_PROTOTYPES", {}): with mock.patch("evennia.prototypes.prototypes._MODULE_PROTOTYPES", {}):
self.assertCountEqual( self.assertCountEqual(protlib.search_prototype("prot"), [prot1b, prot2, prot3])
protlib.search_prototype("prot"), [prot1b, prot2, prot3]) self.assertCountEqual(protlib.search_prototype(tags="foo1"), [prot1b, prot2, prot3])
self.assertCountEqual(
protlib.search_prototype(tags="foo1"), [prot1b, prot2, prot3])
self.assertTrue(str(str(protlib.list_prototypes(self.char1)))) self.assertTrue(str(str(protlib.list_prototypes(self.char1))))
@ -1078,6 +1076,7 @@ class TestOLCMenu(TestEvMenu):
], ],
] ]
class PrototypeCrashTest(EvenniaTest): class PrototypeCrashTest(EvenniaTest):
# increase this to 1000 for optimization testing # increase this to 1000 for optimization testing
@ -1089,9 +1088,9 @@ class PrototypeCrashTest(EvenniaTest):
# print(f"Creating {num} additional prototypes...") # print(f"Creating {num} additional prototypes...")
for x in range(num): for x in range(num):
prot = { prot = {
'prototype_key': str(uuid.uuid4()), "prototype_key": str(uuid.uuid4()),
'some_attributes': [str(uuid.uuid4()) for x in range(10)], "some_attributes": [str(uuid.uuid4()) for x in range(10)],
'prototype_tags': list(sample(['demo', 'test', 'stuff'], 2)), "prototype_tags": list(sample(["demo", "test", "stuff"], 2)),
} }
protlib.save_prototype(prot) protlib.save_prototype(prot)
@ -1101,5 +1100,5 @@ class PrototypeCrashTest(EvenniaTest):
self.create(num_prototypes) self.create(num_prototypes)
# print("Attempting to list prototypes...") # print("Attempting to list prototypes...")
# start_time = time() # start_time = time()
self.char1.execute_cmd('spawn/list') self.char1.execute_cmd("spawn/list")
# print(f"Prototypes listed in {time()-start_time} seconds.") # print(f"Prototypes listed in {time()-start_time} seconds.")

View file

@ -344,8 +344,10 @@ class TickerHandler(object):
raise TypeError(f"{callback} is not a callable function or method.") raise TypeError(f"{callback} is not a callable function or method.")
if outobj and not inherits_from(outobj, "evennia.typeclasses.models.TypedObject"): if outobj and not inherits_from(outobj, "evennia.typeclasses.models.TypedObject"):
raise TypeError(f"{callback} is a method on a normal object - it must " raise TypeError(
"be either a method on a typeclass, or a stand-alone function.") f"{callback} is a method on a normal object - it must "
"be either a method on a typeclass, or a stand-alone function."
)
return outobj, outpath, outcallfunc return outobj, outpath, outcallfunc

View file

@ -176,17 +176,14 @@ def node_start(wizard):
node_game_index_start, node_game_index_start,
{}, {},
), ),
"2": ("MSSP setup (for mud-list crawlers)", "2": ("MSSP setup (for mud-list crawlers)", node_mssp_start, {}),
node_mssp_start, {}
),
# "3": ("Add Grapevine listing", # "3": ("Add Grapevine listing",
# node_grapevine_start, {}), # node_grapevine_start, {}),
# "4": ("Add IRC link", # "4": ("Add IRC link",
# "node_irc_start", {}), # "node_irc_start", {}),
# "5" ("Add RSS feed", # "5" ("Add RSS feed",
# "node_rss_start", {}), # "node_rss_start", {}),
"s": ("View and (optionally) Save created settings", "s": ("View and (optionally) Save created settings", node_view_and_apply_settings, {}),
node_view_and_apply_settings, {}),
"q": ("Quit", lambda *args: sys.exit(), {}), "q": ("Quit", lambda *args: sys.exit(), {}),
} }
@ -263,7 +260,7 @@ def node_game_index_fields(wizard, status=None):
return True return True
wizard.display(text) wizard.display(text)
wizard.game_index_listing['game_name'] = wizard.ask_input( wizard.game_index_listing["game_name"] = wizard.ask_input(
default=name_default, validator=name_validator default=name_default, validator=name_validator
) )
@ -494,8 +491,9 @@ def node_view_and_apply_settings(wizard):
# game index # game index
game_index_save_text = "" game_index_save_text = ""
game_index_listing = (wizard.game_index_listing if game_index_listing = (
hasattr(wizard, "game_index_listing") else None) wizard.game_index_listing if hasattr(wizard, "game_index_listing") else None
)
if not game_index_listing and settings.GAME_INDEX_ENABLED: if not game_index_listing and settings.GAME_INDEX_ENABLED:
game_index_listing = settings.GAME_INDEX_LISTING game_index_listing = settings.GAME_INDEX_LISTING
if game_index_listing: if game_index_listing:

View file

@ -1278,8 +1278,11 @@ def check_main_evennia_dependencies():
# only the main version (1.5, not 1.5.4.0) # only the main version (1.5, not 1.5.4.0)
dversion_main = ".".join(dversion.split(".")[:2]) dversion_main = ".".join(dversion.split(".")[:2])
if LooseVersion(dversion) < LooseVersion(DJANGO_MIN): if LooseVersion(dversion) < LooseVersion(DJANGO_MIN):
print(ERROR_DJANGO_MIN.format(dversion=dversion_main, django_min=DJANGO_MIN, print(
django_lt=DJANGO_LT)) ERROR_DJANGO_MIN.format(
dversion=dversion_main, django_min=DJANGO_MIN, django_lt=DJANGO_LT
)
)
error = True error = True
elif LooseVersion(DJANGO_LT) <= LooseVersion(dversion_main): elif LooseVersion(DJANGO_LT) <= LooseVersion(dversion_main):
print(NOTE_DJANGO_NEW.format(dversion=dversion_main, django_rec=DJANGO_LT)) print(NOTE_DJANGO_NEW.format(dversion=dversion_main, django_rec=DJANGO_LT))

View file

@ -87,6 +87,7 @@ class TelnetProtocol(Telnet, StatefulTelnetProtocol, _BASE_SESSION_CLASS):
super().dataReceived(data) super().dataReceived(data)
except ValueError as err: except ValueError as err:
from evennia.utils import logger from evennia.utils import logger
logger.log_err(f"Malformed telnet input: {err}") logger.log_err(f"Malformed telnet input: {err}")
def connectionMade(self): def connectionMade(self):

View file

@ -339,7 +339,6 @@ class EvMore(object):
# goto top of the text # goto top of the text
self.page_top() self.page_top()
# default paginators - responsible for extracting a specific page number # default paginators - responsible for extracting a specific page number
def paginator_index(self, pageno): def paginator_index(self, pageno):

View file

@ -2100,9 +2100,11 @@ def at_search_result(matches, caller, query="", quiet=False, **kwargs):
# we need to consider Commands, where .aliases is a list # we need to consider Commands, where .aliases is a list
aliases = result.aliases.all() if hasattr(result.aliases, "all") else result.aliases aliases = result.aliases.all() if hasattr(result.aliases, "all") else result.aliases
# remove any pluralization aliases # remove any pluralization aliases
aliases = [alias for alias in aliases if aliases = [
hasattr(alias, "category") alias
and alias.category not in ("plural_key", )] for alias in aliases
if hasattr(alias, "category") and alias.category not in ("plural_key",)
]
error += _MULTIMATCH_TEMPLATE.format( error += _MULTIMATCH_TEMPLATE.format(
number=num + 1, number=num + 1,
name=result.get_display_name(caller) name=result.get_display_name(caller)

View file

@ -535,6 +535,7 @@ let goldenlayout = (function () {
onText: onText, onText: onText,
getGL: function () { return myLayout; }, getGL: function () { return myLayout; },
addKnownType: addKnownType, addKnownType: addKnownType,
onTabCreate: onTabCreate,
} }
}()); }());
window.plugin_handler.add("goldenlayout", goldenlayout); window.plugin_handler.add("goldenlayout", goldenlayout);