From 901eb71df1021b52ca87adfdcb9e1fa7ff31fec8 Mon Sep 17 00:00:00 2001 From: John Bytheway Date: Mon, 10 Feb 2020 06:50:34 +0000 Subject: [PATCH] Add script to generate tags for CDDA json data (#37877) * Fix typo in keys.py * Add cddatags.py This is a tool to augment a tags file with CDDA json tags, to allow for easier navigation of the CDDA game data via standard text-editor support. For more on the tags file format: http://ctags.sourceforge.net/FORMAT --- tools/json_tools/cddatags.py | 79 ++++++++++++++++++++++++++++++++++++ tools/json_tools/keys.py | 2 +- 2 files changed, 80 insertions(+), 1 deletion(-) create mode 100755 tools/json_tools/cddatags.py diff --git a/tools/json_tools/cddatags.py b/tools/json_tools/cddatags.py new file mode 100755 index 0000000000000..15b13bbcc0d74 --- /dev/null +++ b/tools/json_tools/cddatags.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python3 + +import argparse +import json +import os +import sys + +SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__)) +TOP_DIR = os.path.normpath(os.path.join(SCRIPT_DIR, "..", "..")) +JSON_DIR = os.path.join(TOP_DIR, "data") +TAGS_FILE = os.path.join(TOP_DIR, "tags") + +def make_tags_line(id_key, id, filename): + pattern = '/"{id_key}": "{id}"/'.format(id_key=id_key, id=id) + return '\t'.join((id, filename, pattern)).encode('utf-8') + +def is_json_tag_line(line): + return b'.json\t' in line + +def main(args): + parser = argparse.ArgumentParser(description= + """\ +Update a tags file with locations of the definitions of CDDA json entities. + +If you already have a tags file with some data in, this will only replace tags +in json files, not e.g. cpp files, so it should be safe to use after running +e.g. ctags.""") + + args = parser.parse_args(args) + + definitions = [] + + for dirpath, dirnames, filenames in os.walk(JSON_DIR): + for filename in filenames: + if filename.endswith('.json'): + full_path = os.path.join(dirpath, filename) + assert full_path.startswith(TOP_DIR) + relative_path = full_path[len(TOP_DIR):].lstrip('/') + with open(full_path) as file: + try: + json_data = json.load(file) + except Exception as err: + sys.stderr.write( + "Problem reading file %s, reason: %s" % + (filename, err)) + continue + if type(json_data) == dict: + json_data = [json_data] + elif type(json_data) != list: + sys.stderr.write( + "Problem parsing data from file %s, reason: " + "expected a list." % filename) + continue + + for obj in json_data: + for id_key in ('id', 'abstract', 'ident', 'nested_mapgen_id'): + if id_key in obj: + id = obj[id_key] + if type(id) == str and id: + definitions.append((id_key, id, relative_path)) + + json_tags_lines = [make_tags_line(*d) for d in definitions] + existing_tags_lines = [] + try: + with open(TAGS_FILE, 'rb') as tags_file: + existing_tags_lines = tags_file.readlines() + except FileNotFoundError: + pass + + existing_tags_lines = [l.rstrip(b'\n') for l in existing_tags_lines if + not is_json_tag_line(l)] + + all_tags_lines = sorted(json_tags_lines + existing_tags_lines) + + with open(TAGS_FILE, 'wb') as tags_file: + tags_file.write(b'\n'.join(all_tags_lines)) + +if __name__ == '__main__': + main(sys.argv[1:]) diff --git a/tools/json_tools/keys.py b/tools/json_tools/keys.py index 245f196ca68b3..ab45c6d197611 100755 --- a/tools/json_tools/keys.py +++ b/tools/json_tools/keys.py @@ -41,7 +41,7 @@ # If we start getting unexpected JSON or other things, might need to # revisit quitting on load_errors print("Error loading JSON data.") - for e in load_errrors: + for e in load_errors: print(e) sys.exit(1) elif not json_data: