Exemple #1
0
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
Exemple #2
0
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()