|
|
@ -29,8 +29,9 @@ import os.path
|
|
|
|
import re
|
|
|
|
import re
|
|
|
|
import subprocess
|
|
|
|
import subprocess
|
|
|
|
import sys
|
|
|
|
import sys
|
|
|
|
import urllib
|
|
|
|
|
|
|
|
import yaml
|
|
|
|
import yaml
|
|
|
|
|
|
|
|
from functools import reduce
|
|
|
|
|
|
|
|
from six.moves.urllib.parse import urlencode, quote
|
|
|
|
|
|
|
|
|
|
|
|
matrix_doc_dir=reduce(lambda acc,_: os.path.dirname(acc),
|
|
|
|
matrix_doc_dir=reduce(lambda acc,_: os.path.dirname(acc),
|
|
|
|
range(1, 5), os.path.abspath(__file__))
|
|
|
|
range(1, 5), os.path.abspath(__file__))
|
|
|
@ -147,7 +148,7 @@ def inherit_parents(obj):
|
|
|
|
# settings defined in the child take priority over the parents, so we
|
|
|
|
# settings defined in the child take priority over the parents, so we
|
|
|
|
# iterate through the parents first, and then overwrite with the settings
|
|
|
|
# iterate through the parents first, and then overwrite with the settings
|
|
|
|
# from the child.
|
|
|
|
# from the child.
|
|
|
|
for p in map(inherit_parents, parents) + [obj]:
|
|
|
|
for p in list(map(inherit_parents, parents)) + [obj]:
|
|
|
|
# child blats out type, title and description
|
|
|
|
# child blats out type, title and description
|
|
|
|
for key in ('type', 'title', 'description'):
|
|
|
|
for key in ('type', 'title', 'description'):
|
|
|
|
if p.get(key):
|
|
|
|
if p.get(key):
|
|
|
@ -250,12 +251,12 @@ def get_json_schema_object_fields(obj, enforce_title=False):
|
|
|
|
tables.extend(res["tables"])
|
|
|
|
tables.extend(res["tables"])
|
|
|
|
logger.debug("Done property %s" % key_name)
|
|
|
|
logger.debug("Done property %s" % key_name)
|
|
|
|
|
|
|
|
|
|
|
|
except Exception, e:
|
|
|
|
except Exception as e:
|
|
|
|
e2 = Exception("Error reading property %s.%s: %s" %
|
|
|
|
e2 = Exception("Error reading property %s.%s: %s" %
|
|
|
|
(obj_title, key_name, str(e)))
|
|
|
|
(obj_title, key_name, str(e)))
|
|
|
|
# throw the new exception with the old stack trace, so that
|
|
|
|
# throw the new exception with the old stack trace, so that
|
|
|
|
# we don't lose information about where the error occurred.
|
|
|
|
# we don't lose information about where the error occurred.
|
|
|
|
raise e2, None, sys.exc_info()[2]
|
|
|
|
raise e2.with_traceback(sys.exc_info()[2])
|
|
|
|
|
|
|
|
|
|
|
|
tables.insert(0, TypeTable(title=obj_title, rows=first_table_rows))
|
|
|
|
tables.insert(0, TypeTable(title=obj_title, rows=first_table_rows))
|
|
|
|
|
|
|
|
|
|
|
@ -380,7 +381,7 @@ def get_example_for_schema(schema):
|
|
|
|
if 'properties' not in schema:
|
|
|
|
if 'properties' not in schema:
|
|
|
|
raise Exception('"object" property has neither properties nor example')
|
|
|
|
raise Exception('"object" property has neither properties nor example')
|
|
|
|
res = OrderedDict()
|
|
|
|
res = OrderedDict()
|
|
|
|
for prop_name, prop in schema['properties'].iteritems():
|
|
|
|
for prop_name, prop in schema['properties'].items():
|
|
|
|
logger.debug("Parsing property %r" % prop_name)
|
|
|
|
logger.debug("Parsing property %r" % prop_name)
|
|
|
|
prop_example = get_example_for_schema(prop)
|
|
|
|
prop_example = get_example_for_schema(prop)
|
|
|
|
res[prop_name] = prop_example
|
|
|
|
res[prop_name] = prop_example
|
|
|
@ -523,7 +524,7 @@ class MatrixUnits(Units):
|
|
|
|
|
|
|
|
|
|
|
|
if param_loc == "path":
|
|
|
|
if param_loc == "path":
|
|
|
|
path_template = path_template.replace(
|
|
|
|
path_template = path_template.replace(
|
|
|
|
"{%s}" % param_name, urllib.quote(example)
|
|
|
|
"{%s}" % param_name, quote(example)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
elif param_loc == "query":
|
|
|
|
elif param_loc == "query":
|
|
|
|
if type(example) == list:
|
|
|
|
if type(example) == list:
|
|
|
@ -532,7 +533,7 @@ class MatrixUnits(Units):
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
example_query_params.append((param_name, example))
|
|
|
|
example_query_params.append((param_name, example))
|
|
|
|
|
|
|
|
|
|
|
|
except Exception, e:
|
|
|
|
except Exception as e:
|
|
|
|
raise Exception("Error handling parameter %s" % param_name, e)
|
|
|
|
raise Exception("Error handling parameter %s" % param_name, e)
|
|
|
|
# endfor[param]
|
|
|
|
# endfor[param]
|
|
|
|
good_response = None
|
|
|
|
good_response = None
|
|
|
@ -556,14 +557,14 @@ class MatrixUnits(Units):
|
|
|
|
)
|
|
|
|
)
|
|
|
|
if "headers" in good_response:
|
|
|
|
if "headers" in good_response:
|
|
|
|
headers = TypeTable()
|
|
|
|
headers = TypeTable()
|
|
|
|
for (header_name, header) in good_response["headers"].iteritems():
|
|
|
|
for (header_name, header) in good_response["headers"].items():
|
|
|
|
headers.add_row(
|
|
|
|
headers.add_row(
|
|
|
|
TypeTableRow(key=header_name, title=header["type"],
|
|
|
|
TypeTableRow(key=header_name, title=header["type"],
|
|
|
|
desc=header["description"]),
|
|
|
|
desc=header["description"]),
|
|
|
|
)
|
|
|
|
)
|
|
|
|
endpoint["res_headers"] = headers
|
|
|
|
endpoint["res_headers"] = headers
|
|
|
|
query_string = "" if len(
|
|
|
|
query_string = "" if len(
|
|
|
|
example_query_params) == 0 else "?" + urllib.urlencode(
|
|
|
|
example_query_params) == 0 else "?" + urlencode(
|
|
|
|
example_query_params)
|
|
|
|
example_query_params)
|
|
|
|
if example_body:
|
|
|
|
if example_body:
|
|
|
|
endpoint["example"][
|
|
|
|
endpoint["example"][
|
|
|
@ -605,12 +606,12 @@ class MatrixUnits(Units):
|
|
|
|
body_tables = req_body_tables[1:]
|
|
|
|
body_tables = req_body_tables[1:]
|
|
|
|
endpoint_data['req_body_tables'].extend(body_tables)
|
|
|
|
endpoint_data['req_body_tables'].extend(body_tables)
|
|
|
|
|
|
|
|
|
|
|
|
except Exception, e:
|
|
|
|
except Exception as e:
|
|
|
|
e2 = Exception(
|
|
|
|
e2 = Exception(
|
|
|
|
"Error decoding body of API endpoint %s %s: %s" %
|
|
|
|
"Error decoding body of API endpoint %s %s: %s" %
|
|
|
|
(endpoint_data["method"], endpoint_data["path"], e)
|
|
|
|
(endpoint_data["method"], endpoint_data["path"], e)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
raise e2, None, sys.exc_info()[2]
|
|
|
|
raise e2.with_traceback(sys.exc_info()[2])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def load_swagger_apis(self):
|
|
|
|
def load_swagger_apis(self):
|
|
|
@ -711,12 +712,12 @@ class MatrixUnits(Units):
|
|
|
|
if filename != event_name:
|
|
|
|
if filename != event_name:
|
|
|
|
examples[event_name] = examples.get(event_name, [])
|
|
|
|
examples[event_name] = examples.get(event_name, [])
|
|
|
|
examples[event_name].append(example)
|
|
|
|
examples[event_name].append(example)
|
|
|
|
except Exception, e:
|
|
|
|
except Exception as e:
|
|
|
|
e2 = Exception("Error reading event example "+filepath+": "+
|
|
|
|
e2 = Exception("Error reading event example "+filepath+": "+
|
|
|
|
str(e))
|
|
|
|
str(e))
|
|
|
|
# throw the new exception with the old stack trace, so that
|
|
|
|
# throw the new exception with the old stack trace, so that
|
|
|
|
# we don't lose information about where the error occurred.
|
|
|
|
# we don't lose information about where the error occurred.
|
|
|
|
raise e2, None, sys.exc_info()[2]
|
|
|
|
raise e2.with_traceback(sys.exc_info()[2])
|
|
|
|
|
|
|
|
|
|
|
|
return examples
|
|
|
|
return examples
|
|
|
|
|
|
|
|
|
|
|
@ -730,12 +731,12 @@ class MatrixUnits(Units):
|
|
|
|
filepath = os.path.join(path, filename)
|
|
|
|
filepath = os.path.join(path, filename)
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
schemata[filename] = self.read_event_schema(filepath)
|
|
|
|
schemata[filename] = self.read_event_schema(filepath)
|
|
|
|
except Exception, e:
|
|
|
|
except Exception as e:
|
|
|
|
e2 = Exception("Error reading event schema "+filepath+": "+
|
|
|
|
e2 = Exception("Error reading event schema "+filepath+": "+
|
|
|
|
str(e))
|
|
|
|
str(e))
|
|
|
|
# throw the new exception with the old stack trace, so that
|
|
|
|
# throw the new exception with the old stack trace, so that
|
|
|
|
# we don't lose information about where the error occurred.
|
|
|
|
# we don't lose information about where the error occurred.
|
|
|
|
raise e2, None, sys.exc_info()[2]
|
|
|
|
raise e2.with_traceback(sys.exc_info()[2])
|
|
|
|
|
|
|
|
|
|
|
|
return schemata
|
|
|
|
return schemata
|
|
|
|
|
|
|
|
|
|
|
@ -831,12 +832,42 @@ class MatrixUnits(Units):
|
|
|
|
path = os.path.join(CHANGELOG_DIR, f)
|
|
|
|
path = os.path.join(CHANGELOG_DIR, f)
|
|
|
|
name = f[:-4]
|
|
|
|
name = f[:-4]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# If there's a directory with the same name, we'll try to generate
|
|
|
|
|
|
|
|
# a towncrier changelog and prepend it to the general changelog.
|
|
|
|
|
|
|
|
tc_path = os.path.join(CHANGELOG_DIR, name)
|
|
|
|
|
|
|
|
tc_lines = []
|
|
|
|
|
|
|
|
if os.path.isdir(tc_path):
|
|
|
|
|
|
|
|
logger.info("Generating towncrier changelog for: %s" % name)
|
|
|
|
|
|
|
|
p = subprocess.Popen(
|
|
|
|
|
|
|
|
['towncrier', '--version', 'Unreleased Changes', '--name', name, '--draft'],
|
|
|
|
|
|
|
|
cwd=tc_path,
|
|
|
|
|
|
|
|
stderr=subprocess.PIPE,
|
|
|
|
|
|
|
|
stdout=subprocess.PIPE,
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
stdout, stderr = p.communicate()
|
|
|
|
|
|
|
|
if p.returncode != 0:
|
|
|
|
|
|
|
|
# Something broke - dump as much information as we can
|
|
|
|
|
|
|
|
logger.error("Towncrier exited with code %s" % p.returncode)
|
|
|
|
|
|
|
|
logger.error(stdout.decode('UTF-8'))
|
|
|
|
|
|
|
|
logger.error(stderr.decode('UTF-8'))
|
|
|
|
|
|
|
|
raw_log = ""
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
raw_log = stdout.decode('UTF-8')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# This is a bit of a hack, but it does mean that the log at least gets *something*
|
|
|
|
|
|
|
|
# to tell us it broke
|
|
|
|
|
|
|
|
if not raw_log.startswith("Unreleased Changes"):
|
|
|
|
|
|
|
|
logger.error("Towncrier appears to have failed to generate a changelog")
|
|
|
|
|
|
|
|
logger.error(raw_log)
|
|
|
|
|
|
|
|
raw_log = ""
|
|
|
|
|
|
|
|
tc_lines = raw_log.splitlines()
|
|
|
|
|
|
|
|
|
|
|
|
title_part = None
|
|
|
|
title_part = None
|
|
|
|
changelog_lines = []
|
|
|
|
changelog_lines = []
|
|
|
|
with open(path, "r") as f:
|
|
|
|
with open(path, "r") as f:
|
|
|
|
lines = f.readlines()
|
|
|
|
lines = f.readlines()
|
|
|
|
prev_line = None
|
|
|
|
prev_line = None
|
|
|
|
for line in lines:
|
|
|
|
for line in (tc_lines + lines):
|
|
|
|
if prev_line is None:
|
|
|
|
if prev_line is None:
|
|
|
|
prev_line = line
|
|
|
|
prev_line = line
|
|
|
|
continue
|
|
|
|
continue
|
|
|
@ -852,7 +883,10 @@ class MatrixUnits(Units):
|
|
|
|
# then bail out.
|
|
|
|
# then bail out.
|
|
|
|
changelog_lines.pop()
|
|
|
|
changelog_lines.pop()
|
|
|
|
break
|
|
|
|
break
|
|
|
|
changelog_lines.append(" " + line)
|
|
|
|
# Don't generate subheadings (we'll keep the title though)
|
|
|
|
|
|
|
|
if re.match("^[-]{3,}$", line.strip()):
|
|
|
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
changelog_lines.append(" " + line + '\n')
|
|
|
|
changelogs[name] = "".join(changelog_lines)
|
|
|
|
changelogs[name] = "".join(changelog_lines)
|
|
|
|
|
|
|
|
|
|
|
|
return changelogs
|
|
|
|
return changelogs
|
|
|
@ -871,7 +905,7 @@ class MatrixUnits(Units):
|
|
|
|
['git', 'rev-parse', '--abbrev-ref', 'HEAD'],
|
|
|
|
['git', 'rev-parse', '--abbrev-ref', 'HEAD'],
|
|
|
|
stderr=null,
|
|
|
|
stderr=null,
|
|
|
|
cwd=cwd,
|
|
|
|
cwd=cwd,
|
|
|
|
).strip()
|
|
|
|
).strip().decode('UTF-8')
|
|
|
|
except subprocess.CalledProcessError:
|
|
|
|
except subprocess.CalledProcessError:
|
|
|
|
git_branch = ""
|
|
|
|
git_branch = ""
|
|
|
|
try:
|
|
|
|
try:
|
|
|
@ -879,7 +913,7 @@ class MatrixUnits(Units):
|
|
|
|
['git', 'describe', '--exact-match'],
|
|
|
|
['git', 'describe', '--exact-match'],
|
|
|
|
stderr=null,
|
|
|
|
stderr=null,
|
|
|
|
cwd=cwd,
|
|
|
|
cwd=cwd,
|
|
|
|
).strip()
|
|
|
|
).strip().decode('UTF-8')
|
|
|
|
git_tag = "tag=" + git_tag
|
|
|
|
git_tag = "tag=" + git_tag
|
|
|
|
except subprocess.CalledProcessError:
|
|
|
|
except subprocess.CalledProcessError:
|
|
|
|
git_tag = ""
|
|
|
|
git_tag = ""
|
|
|
@ -888,7 +922,7 @@ class MatrixUnits(Units):
|
|
|
|
['git', 'rev-parse', '--short', 'HEAD'],
|
|
|
|
['git', 'rev-parse', '--short', 'HEAD'],
|
|
|
|
stderr=null,
|
|
|
|
stderr=null,
|
|
|
|
cwd=cwd,
|
|
|
|
cwd=cwd,
|
|
|
|
).strip()
|
|
|
|
).strip().decode('UTF-8')
|
|
|
|
except subprocess.CalledProcessError:
|
|
|
|
except subprocess.CalledProcessError:
|
|
|
|
git_commit = ""
|
|
|
|
git_commit = ""
|
|
|
|
try:
|
|
|
|
try:
|
|
|
@ -897,7 +931,7 @@ class MatrixUnits(Units):
|
|
|
|
['git', 'describe', '--dirty=' + dirty_string, "--all"],
|
|
|
|
['git', 'describe', '--dirty=' + dirty_string, "--all"],
|
|
|
|
stderr=null,
|
|
|
|
stderr=null,
|
|
|
|
cwd=cwd,
|
|
|
|
cwd=cwd,
|
|
|
|
).strip().endswith(dirty_string)
|
|
|
|
).strip().decode('UTF-8').endswith(dirty_string)
|
|
|
|
git_dirty = "dirty" if is_dirty else ""
|
|
|
|
git_dirty = "dirty" if is_dirty else ""
|
|
|
|
except subprocess.CalledProcessError:
|
|
|
|
except subprocess.CalledProcessError:
|
|
|
|
git_dirty = ""
|
|
|
|
git_dirty = ""
|
|
|
@ -908,7 +942,7 @@ class MatrixUnits(Units):
|
|
|
|
s for s in
|
|
|
|
s for s in
|
|
|
|
(git_branch, git_tag, git_commit, git_dirty,)
|
|
|
|
(git_branch, git_tag, git_commit, git_dirty,)
|
|
|
|
if s
|
|
|
|
if s
|
|
|
|
).encode("ascii")
|
|
|
|
).encode("ascii").decode('ascii')
|
|
|
|
return {
|
|
|
|
return {
|
|
|
|
"string": git_version,
|
|
|
|
"string": git_version,
|
|
|
|
"revision": git_commit
|
|
|
|
"revision": git_commit
|
|
|
|