def combine_platforms_and_since(annotated_obj): parent = annotated_obj.parent obj = annotated_obj.api_obj result = [] platforms = None since = DEFAULT_SINCE if dict_has_non_empty_member(obj, "platforms"): platforms = obj["platforms"] # Method/property/event can't have more platforms than the types they belong to. if (platforms is None or isinstance(annotated_obj, AnnotatedMethod) or isinstance(annotated_obj, AnnotatedProperty) or isinstance(annotated_obj, AnnotatedEvent)): if parent is not None: if dict_has_non_empty_member(parent.api_obj, "platforms"): if platforms is None or len(parent.api_obj["platforms"]) < len(platforms): platforms = parent.api_obj["platforms"] # Last resort is the default list of platforms if platforms is None: platforms = DEFAULT_PLATFORMS if "since" in obj and len(obj["since"]) > 0: since = obj["since"] else: # If a method/event/property we can check type's "since" if (isinstance(annotated_obj, AnnotatedMethod) or isinstance(annotated_obj, AnnotatedProperty) or isinstance(annotated_obj, AnnotatedEvent)): if (parent is not None and dict_has_non_empty_member(parent.api_obj, "since")): since = parent.api_obj["since"] since_is_dict = isinstance(since, dict) for name in platforms: one_platform = {"name": name, "pretty_name": pretty_platform_name(name)} min_since = first_version_for_platform(one_platform["name"]) if not since_is_dict: one_platform["since"] = since if min_since is not None: if StrictVersion(since) < StrictVersion(min_since): one_platform["since"] = min_since else: if name in since: one_platform["since"] = since[name] else: if min_since is not None: one_platform["since"] = min_since else: one_platform["since"] = DEFAULT_SINCE result.append(one_platform) # Be sure no "since" is _before_ a parent object since. if parent and parent.platforms: for entry in result: platform_name = entry["name"] version_parts = entry["since"].split(".") for parent_entry in parent.platforms: if parent_entry["name"] == platform_name: parent_version_parts = parent_entry["since"].split(".") if parent_version_parts > version_parts: entry["since"] = parent_entry["since"] break return result
def combine_platforms_and_since(annotated_obj): parent = annotated_obj.parent obj = annotated_obj.api_obj result = [] platforms = None since = DEFAULT_SINCE if dict_has_non_empty_member(obj, "platforms"): platforms = obj["platforms"] # Method/property/event can't have more platforms than the types they belong to. if (platforms is None or isinstance(annotated_obj, AnnotatedMethod) or isinstance(annotated_obj, AnnotatedProperty) or isinstance(annotated_obj, AnnotatedEvent)): if parent is not None: if dict_has_non_empty_member(parent.api_obj, "platforms"): if platforms is None or len( parent.api_obj["platforms"]) < len(platforms): platforms = parent.api_obj["platforms"] # Last resort is the default list of platforms if platforms is None: platforms = DEFAULT_PLATFORMS if "since" in obj and len(obj["since"]) > 0: since = obj["since"] else: # If a method/event/property we can check type's "since" if (isinstance(annotated_obj, AnnotatedMethod) or isinstance(annotated_obj, AnnotatedProperty) or isinstance(annotated_obj, AnnotatedEvent)): if (parent is not None and dict_has_non_empty_member(parent.api_obj, "since")): since = parent.api_obj["since"] since_is_dict = isinstance(since, dict) for name in platforms: one_platform = { "name": name, "pretty_name": pretty_platform_name(name) } min_since = first_version_for_platform(one_platform["name"]) if not since_is_dict: one_platform["since"] = since if min_since is not None: if StrictVersion(since) < StrictVersion(min_since): one_platform["since"] = min_since else: if name in since: one_platform["since"] = since[name] else: if min_since is not None: one_platform["since"] = min_since else: one_platform["since"] = DEFAULT_SINCE result.append(one_platform) # Be sure no "since" is _before_ a parent object since. if parent and parent.platforms: for entry in result: platform_name = entry["name"] version_parts = entry["since"].split(".") for parent_entry in parent.platforms: if parent_entry["name"] == platform_name: parent_version_parts = parent_entry["since"].split(".") if parent_version_parts > version_parts: entry["since"] = parent_entry["since"] break return result
def generate(raw_apis, annotated_apis, options): global all_annotated_apis, apis, platform_list all_annotated_apis = annotated_apis apis = raw_apis if options is not None and (not hasattr(options, "output") or options.output is None or len(options.output) == 0): log.error ("'output' option not provided") sys.exit(1) if options is not None and (not hasattr(options, "version") or options.version is None or len(options.version) == 0): log.error ("'version' option not provided") sys.exit(1) if options is not None and not os.path.exists(options.output): os.makedirs(options.output) version = normalize_version(options.version) outfile = "changes_%s.html" % ".".join(version) platform_list = [] for platform in DEFAULT_PLATFORMS: first_platform_version = first_version_for_platform(platform) if first_platform_version is not None: if version <= normalize_version(first_platform_version): print "Skipping new platform, " + platform continue platform_list.append(platform) print "Platform list is: " + str(platform_list) # Write the output files deprecated = [] removed = [] added = [] if options is not None: for name in annotated_apis: annotated_obj = annotated_apis[name] if annotated_obj.is_pseudotype: continue supertype = find_supertype(annotated_obj) list_names = [ "methods", "properties", "events" ] new_api = is_new_api(annotated_obj, version) if new_api is not None: notes = "" if new_api.has_key("notes"): notes = " (%s.)" % new_api["notes"] added.append({ "name": full_type_name(annotated_obj), "type": { "proxy": "object", "module":"module" }[annotated_obj.typestr], "summary": markdown_to_html(annotated_obj.api_obj["summary"] + notes) }) else: for list_name in list_names: if has_list_attr(annotated_obj, list_name): member_list = getattr(annotated_obj, list_name) for m in member_list: new_api = is_new_api(m, version) if new_api is not None: notes = "" if new_api.has_key("notes"): notes = " (%s.)" % new_api["notes"] added.append({ "name": full_type_name(m), "type": m.typestr, "summary": markdown_to_html(m.api_obj["summary"] + notes) }) elif list_name == "methods" or list_name == "events": sublist_name = { "methods": "parameters", "events": "properties" }[list_name] if has_list_attr(m, sublist_name): sublist = getattr(m, sublist_name) for p in sublist: new_api = is_new_api(p, version) if new_api is not None: notes = "" if new_api.has_key("notes"): notes = " (%s.)" % new_api["notes"] added.append({ "name": full_type_name(p), "type": { "methods": "parameter", "events": "event property" }[list_name], "summary": markdown_to_html(p.api_obj["summary"] + notes) }) removed_or_deprecated = is_removed_or_deprecated_api(annotated_obj, version) if removed_or_deprecated: notes = "" if annotated_obj.deprecated.has_key("notes"): notes = markdown_to_html(annotated_obj.deprecated["notes"]) deprecation = { "name": full_type_name(annotated_obj), "type": { "proxy": "object", "module":"module" }[annotated_obj.typestr], "notes": notes } if removed_or_deprecated == "deprecated": deprecated.append(deprecation) else: removed.append(deprecation) parent_removed_or_deprecated = removed_or_deprecated for list_name in list_names: if has_list_attr(annotated_obj, list_name): member_list = getattr(annotated_obj, list_name) for m in member_list: # Do not insert deprecation/removal records if the parent deprecation matches... But if we deprecate an object in the # same release that we remove one of its members, we must list both. m_removed_or_deprecated = is_removed_or_deprecated_api(m, version) if m_removed_or_deprecated and m_removed_or_deprecated != parent_removed_or_deprecated: # if inherited AND the parent has deprecated this property, omit it. if supertype is not None and is_deprecated_in_supertype(m, m_removed_or_deprecated): pass else: notes = "" if m.deprecated.has_key("notes"): notes = markdown_to_html(m.deprecated["notes"]) deprecation = { "name": full_type_name(m), "type": m.typestr, "notes": notes } if m_removed_or_deprecated == "deprecated": deprecated.append(deprecation) else: removed.append(deprecation) if list_name == "methods" or list_name == "events": sublist_name = { "methods": "parameters", "events": "properties" }[list_name] if has_list_attr(m, sublist_name): sublist = getattr(m, sublist_name) for p in sublist: # Omit the removal/deprecation if the containing method/event is similarly deprecated or removed. # Do we need to also check the parent object? p_removed_or_deprecated = is_removed_or_deprecated_api(p, version) if p_removed_or_deprecated and p_removed_or_deprecated != m_removed_or_deprecated and p_removed_or_deprecated != parent_removed_or_deprecated: if supertype is not None and is_deprecated_in_supertype(p, p_removed_or_deprecated): # supertype_member = find_supertype_member(m, getattr(supertype, list_name)) #supertype_member = find_supertype_member(m) #if has_list_attr(supertype_member, sublist_name): # if is_deprecated_in_supertype(p, getattr(supertype_member, sublist_name), p_removed_or_deprecated): continue notes = "" if p.deprecated.has_key("notes"): notes = markdown_to_html(p.deprecated["notes"]) deprecation = { "name": full_type_name(p), "type": { "events" : "event property", "methods" : "parameter" }[list_name], "notes": notes } if p_removed_or_deprecated == "deprecated": deprecated.append(deprecation) else: removed.append(deprecation) log.info("Creating %s in %s" % (outfile, options.output)) log.info("Found %d new APIs, %d deprecated, %d removed" % (len(added), len(deprecated), len(removed))) output = open(os.path.join(options.output, outfile), "w") if len(added) > 0: added.sort(key=lambda record: record["name"].split(".")) output.write(render_template(added, "new_summary", ".".join(version))); if len(deprecated) > 0: deprecated.sort(key=lambda record: record["name"].split(".")) output.write(render_template(deprecated, "deprecation_summary", ".".join(version))); if len(removed) > 0: removed.sort(key=lambda record: record["name"].split(".")) output.write(render_template(removed, "removed_summary", ".".join(version))); output.close()
def generate(raw_apis, annotated_apis, options): global all_annotated_apis, apis, platform_list all_annotated_apis = annotated_apis apis = raw_apis if options is not None and (not hasattr(options, "output") or options.output is None or len(options.output) == 0): log.error("'output' option not provided") sys.exit(1) if options is not None and (not hasattr(options, "version") or options.version is None or len(options.version) == 0): log.error("'version' option not provided") sys.exit(1) if options is not None and not os.path.exists(options.output): os.makedirs(options.output) version = normalize_version(options.version) outfile = "changes_%s.html" % ".".join(version) platform_list = [] for platform in DEFAULT_PLATFORMS: first_platform_version = first_version_for_platform(platform) if first_platform_version is not None: if version <= normalize_version(first_platform_version): print "Skipping new platform, " + platform continue platform_list.append(platform) print "Platform list is: " + str(platform_list) # Write the output files deprecated = [] removed = [] added = [] if options is not None: for name in annotated_apis: annotated_obj = annotated_apis[name] if annotated_obj.is_pseudotype: continue supertype = find_supertype(annotated_obj) list_names = ["methods", "properties", "events"] new_api = is_new_api(annotated_obj, version) if new_api is not None: notes = "" if new_api.has_key("notes"): notes = " (%s.)" % new_api["notes"] added.append({ "name": full_type_name(annotated_obj), "type": { "proxy": "object", "module": "module" }[annotated_obj.typestr], "summary": markdown_to_html(annotated_obj.api_obj["summary"] + notes) }) else: for list_name in list_names: if has_list_attr(annotated_obj, list_name): member_list = getattr(annotated_obj, list_name) for m in member_list: new_api = is_new_api(m, version) if new_api is not None: notes = "" if new_api.has_key("notes"): notes = " (%s.)" % new_api["notes"] added.append({ "name": full_type_name(m), "type": m.typestr, "summary": markdown_to_html(m.api_obj["summary"] + notes) }) elif list_name == "methods" or list_name == "events": sublist_name = { "methods": "parameters", "events": "properties" }[list_name] if has_list_attr(m, sublist_name): sublist = getattr(m, sublist_name) for p in sublist: new_api = is_new_api(p, version) if new_api is not None: notes = "" if new_api.has_key("notes"): notes = " (%s.)" % new_api[ "notes"] added.append({ "name": full_type_name(p), "type": { "methods": "parameter", "events": "event property" }[list_name], "summary": markdown_to_html( p.api_obj["summary"] + notes) }) removed_or_deprecated = is_removed_or_deprecated_api( annotated_obj, version) if removed_or_deprecated: notes = "" if annotated_obj.deprecated.has_key("notes"): notes = markdown_to_html(annotated_obj.deprecated["notes"]) deprecation = { "name": full_type_name(annotated_obj), "type": { "proxy": "object", "module": "module" }[annotated_obj.typestr], "notes": notes } if removed_or_deprecated == "deprecated": deprecated.append(deprecation) else: removed.append(deprecation) parent_removed_or_deprecated = removed_or_deprecated for list_name in list_names: if has_list_attr(annotated_obj, list_name): member_list = getattr(annotated_obj, list_name) for m in member_list: # Do not insert deprecation/removal records if the parent deprecation matches... But if we deprecate an object in the # same release that we remove one of its members, we must list both. m_removed_or_deprecated = is_removed_or_deprecated_api( m, version) if m_removed_or_deprecated and m_removed_or_deprecated != parent_removed_or_deprecated: # if inherited AND the parent has deprecated this property, omit it. if supertype is not None and is_deprecated_in_supertype( m, m_removed_or_deprecated): pass else: notes = "" if m.deprecated.has_key("notes"): notes = markdown_to_html( m.deprecated["notes"]) deprecation = { "name": full_type_name(m), "type": m.typestr, "notes": notes } if m_removed_or_deprecated == "deprecated": deprecated.append(deprecation) else: removed.append(deprecation) if list_name == "methods" or list_name == "events": sublist_name = { "methods": "parameters", "events": "properties" }[list_name] if has_list_attr(m, sublist_name): sublist = getattr(m, sublist_name) for p in sublist: # Omit the removal/deprecation if the containing method/event is similarly deprecated or removed. # Do we need to also check the parent object? p_removed_or_deprecated = is_removed_or_deprecated_api( p, version) if p_removed_or_deprecated and p_removed_or_deprecated != m_removed_or_deprecated and p_removed_or_deprecated != parent_removed_or_deprecated: if supertype is not None and is_deprecated_in_supertype( p, p_removed_or_deprecated): # supertype_member = find_supertype_member(m, getattr(supertype, list_name)) #supertype_member = find_supertype_member(m) #if has_list_attr(supertype_member, sublist_name): # if is_deprecated_in_supertype(p, getattr(supertype_member, sublist_name), p_removed_or_deprecated): continue notes = "" if p.deprecated.has_key("notes"): notes = markdown_to_html( p.deprecated["notes"]) deprecation = { "name": full_type_name(p), "type": { "events": "event property", "methods": "parameter" }[list_name], "notes": notes } if p_removed_or_deprecated == "deprecated": deprecated.append(deprecation) else: removed.append(deprecation) log.info("Creating %s in %s" % (outfile, options.output)) log.info("Found %d new APIs, %d deprecated, %d removed" % (len(added), len(deprecated), len(removed))) output = open(os.path.join(options.output, outfile), "w") if len(added) > 0: added.sort(key=lambda record: record["name"].split(".")) output.write( render_template(added, "new_summary", ".".join(version))) if len(deprecated) > 0: deprecated.sort(key=lambda record: record["name"].split(".")) output.write( render_template(deprecated, "deprecation_summary", ".".join(version))) if len(removed) > 0: removed.sort(key=lambda record: record["name"].split(".")) output.write( render_template(removed, "removed_summary", ".".join(version))) output.close()