From a83ae0ab08ba0a694270785734de64d282511d6f Mon Sep 17 00:00:00 2001 From: Allefant Date: Tue, 21 Jan 2014 02:05:47 +0100 Subject: [PATCH] [wmlunits] Filter out eras from dependencies --- data/tools/wmlunits | 136 +++++++++++++++++++++++++++++++------------- 1 file changed, 97 insertions(+), 39 deletions(-) diff --git a/data/tools/wmlunits b/data/tools/wmlunits index a3953290203..2b0d2e0cd30 100755 --- a/data/tools/wmlunits +++ b/data/tools/wmlunits @@ -81,10 +81,77 @@ def get_info(addon): options.data_dir, no_preprocess = False) parser.parse_file(path) _info[addon] = parser + else: + print("Cannot find " + path) except wmlparser2.WMLError as e: print(e) return _info[addon] +_deps = {} +global_addons = set() +def get_dependencies(addon): + global _deps + global global_addons + if addon in _deps: + return _deps[addon] + _deps[addon] = [] + try: + info = get_info(addon).get_all(tag = "info")[0] + row = info.get_text_val("dependencies") + if row: + deps1 = row.split(",") + else: + deps1 = [] + for d in deps1: + if d in global_addons: + _deps[addon].append(d) + else: + print("Missing dependency for " + addon + ": " + d) + except Exception as e: + print(e) + return _deps[addon] + +def set_dependencies(addon, depends_on): + _deps[addon] = depends_on + +def get_all_dependencies(addon): + result = [] + check = get_dependencies(addon)[:] + while check: + d = check.pop() + if d == addon: continue + if d in result: continue + result.append(d) + check += get_dependencies(d) + return result + +def sorted_by_dependencies(addons): + sorted = [] + unsorted = addons[:] + while unsorted: + n = 0 + for addon in unsorted: + for d in get_dependencies(addon): + if d not in sorted: + break + else: + sorted.append(addon) + unsorted.remove(addon) + n += 1 + continue + if n == 0: + print("Cannot sort dependencies for these addons: " + str(unsorted)) + sorted += unsorted + break + return sorted + +def search(batchlist, name): + for info in batchlist: + if info and info["name"] == name: return info + batchlist.append({}) + batchlist[-1]["name"] = name + return batchlist[-1] + def list_contents(): class Empty: pass local = Empty() @@ -114,21 +181,29 @@ def list_contents(): if t != info[-1]["name"]: info[-1]["translations"][isocode] = t - def list_eras(addon): + def get_dependency_eras(batchlist, addon): + dependency_eras = list(mainline_eras) + for d in get_all_dependencies(addon): + dinfo = search(batchlist, d) + for era in dinfo["eras"]: + dependency_eras.append(era["id"]) + return dependency_eras + + def list_eras(batchlist, addon): eras = local.wesnoth.parser.get_all(tag = "era") if addon != "mainline": - eras = [x for x in eras if not x.get_text_val("id") in mainline_eras] + dependency_eras = get_dependency_eras(batchlist, addon) + eras = [x for x in eras if not x.get_text_val("id") in dependency_eras] info = [] for era in eras: eid = era.get_text_val("id") if addon == "mainline": mainline_eras.add(eid) append(info, eid, "MULTIPLAYER", c = era) - return info - def list_campaigns(addon): + def list_campaigns(batchlist, addon): campaigns = local.wesnoth.parser.get_all(tag = "campaign") info = [] @@ -182,60 +257,38 @@ def list_contents(): batchlist = yaml.load(open(options.list)) except IOError: batchlist = [] - - def search(name): - for info in batchlist: - if info and info["name"] == name: return info - batchlist.append({}) - batchlist[-1]["name"] = name - return batchlist[-1] print("mainline") - info = search("mainline") + info = search(batchlist, "mainline") info["version"] = "mainline" info["parsed"] = "false" parse("{core}{multiplayer/eras.cfg}", "SKIP_CORE") - info["eras"] = list_eras("mainline") + info["eras"] = list_eras(batchlist, "mainline") # Fake mainline campaign to have an overview of the mainline units info["campaigns"] = [] append(info["campaigns"], "mainline", "", name = "Units", domain = "wesnoth-help") if not options.addons_only: - parse("{core}{campaigns}", "SKIP_CORE") - info["campaigns"] += list_campaigns("mainline") + info["campaigns"] += list_campaigns(batchlist, "mainline") addons = [] if options.addons: addons = os.listdir(options.addons) + global global_addons + global_addons = set(addons) - _deps = [{}] - def get_dependencies(addon): - if addon in _deps[0]: - return _deps[0][addon] - _deps[0][addon] = [] - try: - info = get_info(addon).get_all(tag = "info")[0] - row = info.get_text_val("dependencies") - if row: - deps1 = row.split(",") - else: - deps = [] - for d in deps1: - if d in addons: - _deps[0][addon].append(d) - else: - print("Missing dependency for " + addon + ": " + d) - except Exception as e: - pass - return _deps[0][addon] - + # fill in the map for all dependencies for addon in addons: get_dependencies(addon) + # this ensures that info about eras in dependant addons is available + # already + addons = sorted_by_dependencies(addons) + for i, addon in enumerate(addons): if not os.path.isdir(options.addons + "/" + addon): continue sys.stdout.write("%4d/%4d " % (1 + i, len(addons)) + addon + " ... ") @@ -249,7 +302,7 @@ def list_contents(): for d in get_dependencies(addon): move(options.addons, options.config_dir + "/data/add-ons", d) try: - info = search(addon) + info = search(batchlist, addon) if info.get("version", "") == version and info.get("parsed", False) == True: sys.stdout.write("up to date\n") @@ -257,8 +310,8 @@ def list_contents(): info["parsed"] = False parse("{core}{multiplayer}{~add-ons}", "MULTIPLAYER,SKIP_CORE") - info["eras"] = list_eras(addon) - info["campaigns"] = list_campaigns(addon) + info["eras"] = list_eras(batchlist, addon) + info["campaigns"] = list_campaigns(batchlist, addon) info["version"] = version info["dependencies"] = get_dependencies(addon) sys.stdout.write("ok\n") @@ -363,6 +416,11 @@ def process_campaign_or_era(addon, cid, define, batchlist): def batch_process(): batchlist = yaml.load(open(options.batch)) + + for addon in batchlist: + name = addon["name"] + set_dependencies(name, addon.get("dependencies", [])) + for addon in batchlist: name = addon["name"]