Skip to content

Commit

Permalink
Add script to generate tags for CDDA json data (#37877)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
jbytheway authored Feb 10, 2020
1 parent 64ea322 commit 901eb71
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 1 deletion.
79 changes: 79 additions & 0 deletions tools/json_tools/cddatags.py
Original file line number Diff line number Diff line change
@@ -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:])
2 changes: 1 addition & 1 deletion tools/json_tools/keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down

0 comments on commit 901eb71

Please sign in to comment.