diff -Nru click-reviewers-tools-0.33/check-names.list click-reviewers-tools-0.34/check-names.list --- click-reviewers-tools-0.33/check-names.list 1970-01-01 00:00:00.000000000 +0000 +++ click-reviewers-tools-0.34/check-names.list 2015-09-16 14:16:24.000000000 +0000 @@ -0,0 +1,188 @@ +bin-path:package_yaml_description_empty| +bin-path:package_yaml_description_present| +bin-path:package_yaml_optional_key| +bin-path:package_yaml_unknown_key| +bin-path:path_executable| +content_hub:peer_hooks_disallowed| +content_hub:peer_hooks_required| +content_hub:unknown| +content_hub:valid| +content_hub:valid_value| +desktop:Exec| +desktop:Exec_webapp_args_minimal_chrome| +desktop:Exec_webapp_args_required| +desktop:Exec_webapp_container| +desktop:Exec_webapp_container_13.10| +desktop:Exec_webapp_container_webapp| +desktop:Exec_webbrowser| +desktop:Exec_webbrowser_13.10| +desktop:Exec_webbrowser_target_exists| +desktop:Exec_webbrowser_target_netloc_matches_patterns| +desktop:Exec_webbrowser_target_scheme_matches_patterns| +desktop:Exec_webbrowser_webapp| +desktop:Exec_webbrowser_webapp_manifest| +desktop:Exec_webbrowser_webapp_manifest_includes_present| +desktop:Exec_webbrowser_webapp_manifest_wellformed| +desktop:Exec_webbrowser_webappModelSearchPath_present| +desktop:Exec_webbrowser_webappUrlPatterns| +desktop:Exec_webbrowser_webapp_url_patterns_has_https| +desktop:Exec_webbrowser_webapp_url_patterns_uses_safe_glob| +desktop:Exec_webbrowser_webapp_url_patterns_uses_trailing_glob| +desktop:Exec_webbrowser_webapp_url_patterns_uses_unsafe_glob| +desktop:files_usable| +desktop:peer_hooks_disallowed| +desktop:peer_hooks_required| +desktop:required_fields_not_empty| +desktop:required_keys| +desktop:validates|http://askubuntu.com/questions/417377/what-does-desktop-validates-mean/417378 +desktop:X-Ubuntu-Gettext-Domain| +framework:dependency| +framework:obsolete_declaration| +framework:obsolete_framework_file| +framework:policies| +framework:policy| +framework:policy_metadata| +framework:policy_unknown| +framework:policy_valid_name| +lint:click_local_extensions| +lint:control_architecture_match| +lint:control_architecture_specified_needed| +lint:control_architecture_valid| +lint:control_architecture_valid_contents| +lint:control_click_version_up_to_date|http://askubuntu.com/questions/417366/what-does-lint-control-click-version-up-to-date-mean/417367 +lint:control_description_match| +lint:control_has_field| +lint:control_installed_size| +lint:control_maintainer_match| +lint:control_package_match| +lint:control_structure| +lint:control_version_match| +lint:exclusive_hooks| +lint:file_mode| +lint:framework|http://askubuntu.com/questions/460512/what-framework-should-i-use-in-my-manifest-file +lint:hashes_archive-sha512_present| +lint:hashes_archive-sha512_valid| +lint:hashes_extra_files| +lint:hashes_files_present| +lint:hooks| +lint:hooks_known| +lint:hooks_multiple_apps| +lint:hooks_redflag| +lint:hooks_valid| +lint:maintainer_format|http://askubuntu.com/questions/417351/what-does-lint-maintainer-format-mean/417352 +lint:maintainer_present| +lint:manifest_architecture_valid| +lint:manifest_icon_absolute_path| +lint:manifest_icon_empty| +lint:manifest_icon_present| +lint:package_filename_arch_match| +lint:package_filename_arch_valid| +lint:package_filename_format| +lint:package_filename_version_match|http://askubuntu.com/questions/417384/what-does-lint-package-filename-version-match-mean/417385 +lint:package yaml_architecture_valid| +lint:package_yaml_icon_absolute_path| +lint:package_yaml_icon_empty| +lint:package_yaml_icon_present| +lint:pkgname_valid| +lint:sdk_security_extension| +lint:sha512sums| +lint:snappy_config_hook_executable| +lint:snappy_in_binaries| +lint:snappy_in_services| +lint:snappy_name_valid| +lint:snappy_readme.md| +lint:snappy_readme.md_length| +lint:snappy_type_redflag|https://developer.ubuntu.com/en/snappy/guides/frameworks/ +lint:snappy_type_valid| +lint:snappy_unknown| +lint:snappy_vendor_valid| +lint:snappy_version_valid| +online_accounts:account-application_hook| +online_accounts:account-application_id| +online_accounts:account-application_root| +online_accounts:account-application_service| +online_accounts:account-application_services| +online_accounts:account-provider| +online_accounts:account-provider_id| +online_accounts:account-provider_root| +online_accounts:account-qml-plugin| +online_accounts:account-service_hook| +online_accounts:account-service_id| +online_accounts:account-service_name| +online_accounts:account-service_provider| +online_accounts:account-service_root| +online_accounts:accounts_plugin| +online_accounts:accounts_service| +online_accounts:accounts_services| +online_accounts:peer_hooks_disallowed|https://wiki.ubuntu.com/SecurityTeam/Specifications/OnlineAccountsConfinement +online_accounts:peer_hooks_required|https://wiki.ubuntu.com/SecurityTeam/Specifications/OnlineAccountsConfinement +push_helper:other_hooks| +push_helper:peer_hooks_disallowed| +push_helper:peer_hooks_required| +push_helper:unknown| +push_helper:valid| +push_helper:valid_required| +scope:ini_scope_required_fields| +scope:ini_scope_section| +scope:ini_scope_unknown_fields| +scope:peer_hooks_disallowed| +scope:peer_hooks_required| +security:apparmor_profile| +security:peer_hooks_disallowed| +security:peer_hooks_required| +security:policy_groups_duplicates| +security:policy_groups_exists| +security:policy_groups_push_helper| +security:policy_groups_safe| +security:policy_groups_scopes| +security:policy_groups_ubuntu_account_plugin| +security:policy_groups_valid| +security:policy_groups_webapp| +security:policy_groups_webapp_webview| +security:policy_vendor| +security:policy_vendor_matches_framework| +security:policy_version_exists| +security:policy_version_is_highest|http://askubuntu.com/q/562116/94326 +security:policy_version_matches_framework| +security:redflag_fields| +security:required_policy_groups_ubuntu_account_plugin| +security:template_account_provider| +security:template_account_qml_plugin| +security:template_exists| +security:template_push_helper| +security:template_valid| +security:template_with_policy_version| +security:yaml_and_click| +security:yaml_binaries| +security:yaml_binaries_entries| +security:yaml_caps| +security:yaml_combinations| +security:yaml_override_click| +security:yaml_override_format| +security:yaml_policy_format| +security:yaml_policy_present|https://developer.ubuntu.com/en/snappy/guides/security-policy/ +security:yaml_security-template| +security:yaml_services| +snappy-systemd:package_yaml_absolute_path| +snappy-systemd:package_yaml_bus-name_empty| +snappy-systemd:package_yaml_bus-name_format|http://dbus.freedesktop.org/doc/dbus-specification.html +snappy-systemd:package_yaml_bus-name_matches_name| +snappy-systemd:package_yaml_description_empty| +snappy-systemd:package_yaml_description_present| +snappy-systemd:package_yaml_empty| +snappy-systemd:package_yaml_optional_key| +snappy-systemd:package_yaml_ports| +snappy-systemd:package_yaml_ports_bad_key| +snappy-systemd:package_yaml_ports_empty| +snappy-systemd:package_yaml_ports_ext1_format| +snappy-systemd:package_yaml_ports_ext2_format| +snappy-systemd:package_yaml_ports_int1_format| +snappy-systemd:package_yaml_ports_invalid| +snappy-systemd:package_yaml_required_key| +snappy-systemd:package_yaml_stop_timeout| +snappy-systemd:package_yaml_unknown_key| +url_dispatcher:optional_entry| +url_dispatcher:peer_hooks_disallowed| +url_dispatcher:peer_hooks_required| +url_dispatcher:required_entry| +url_dispatcher:unknown_entry| diff -Nru click-reviewers-tools-0.33/clickreviews/cr_bin_path.py click-reviewers-tools-0.34/clickreviews/cr_bin_path.py --- click-reviewers-tools-0.33/clickreviews/cr_bin_path.py 2015-07-22 16:46:42.000000000 +0000 +++ click-reviewers-tools-0.34/clickreviews/cr_bin_path.py 2015-09-16 14:16:24.000000000 +0000 @@ -72,7 +72,8 @@ for r in self.required_keys: found = False t = 'info' - n = '%s_required_key_%s_%s' % (test_str, r, app) + n = self._get_check_name( + '%s_required_key' % test_str, app=app, extra=r) s = "OK" if r in my_dict[app]: if not isinstance(my_dict[app][r], str): @@ -102,7 +103,8 @@ continue # checked in cr_security.py found = False t = 'info' - n = '%s_optional_key_%s_%s' % (test_str, o, app) + n = self._get_check_name( + '%s_optional_key' % test_str, app=app, extra=o) s = "OK" if o in my_dict[app]: if not isinstance(my_dict[app][o], str): @@ -128,7 +130,8 @@ for app in sorted(my_dict): unknown = [] t = 'info' - n = '%s_unknown_key_%s' % (test_str, app) + n = self._get_check_name( + '%s_unknown_key' % test_str, app=app) s = "OK" for f in my_dict[app].keys(): @@ -154,12 +157,12 @@ def check_path(self): '''Check path exists''' t = 'info' - n = 'path exists' + n = self._get_check_name('path_exists') s = "OK" for app in sorted(self.bin_paths_files): t = 'info' - n = 'path executable' + n = self._get_check_name('path_executable') s = "OK" if not self._check_bin_path_executable(app): t = 'error' @@ -176,7 +179,8 @@ for app in sorted(my_dict): t = 'info' - n = 'package_yaml_description_present_%s' % (app) + n = self._get_check_name( + 'package_yaml_description_present', app=app) s = 'OK' if 'description' not in my_dict[app]: s = 'OK (skip missing)' @@ -185,7 +189,8 @@ self._add_result(t, n, s) t = 'info' - n = 'package_yaml_description_empty_%s' % (app) + n = self._get_check_name( + 'package_yaml_description_empty', app=app) s = 'OK' if len(my_dict[app]['description']) == 0: t = 'error' diff -Nru click-reviewers-tools-0.33/clickreviews/cr_common.py click-reviewers-tools-0.34/clickreviews/cr_common.py --- click-reviewers-tools-0.33/clickreviews/cr_common.py 2015-07-22 16:46:42.000000000 +0000 +++ click-reviewers-tools-0.34/clickreviews/cr_common.py 2015-09-16 14:16:24.000000000 +0000 @@ -15,11 +15,13 @@ # along with this program. If not, see . from __future__ import print_function +import atexit import codecs from debian.deb822 import Deb822 import glob import inspect import json +import logging import magic import os import pprint @@ -35,9 +37,6 @@ UNPACK_DIR = None RAW_UNPACK_DIR = None -# cleanup -import atexit - def cleanup_unpack(): global UNPACK_DIR @@ -67,6 +66,7 @@ # click service) app_allowed_peer_hooks = ["account-application", "account-service", + "accounts", "account-provider", "account-qml-plugin", "apparmor", @@ -77,6 +77,7 @@ ] scope_allowed_peer_hooks = ["account-application", "account-service", + "accounts", "apparmor", "scope", ] @@ -463,7 +464,7 @@ continue d = self._verify_peer_hooks(hook) t = 'info' - n = "peer_hooks_required_%s" % hook + n = self._get_check_name("peer_hooks_required", extra=hook) s = "OK" if 'missing' in d and len(d['missing'].keys()) > 0: @@ -477,7 +478,7 @@ self._add_result(t, n, s) t = 'info' - n = "peer_hooks_disallowed_with_%s" % hook + n = self._get_check_name("peer_hooks_disallowed", extra=hook) s = "OK" if 'disallowed' in d and len(d['disallowed'].keys()) > 0: @@ -494,6 +495,14 @@ '''Set review name''' self.review_type = name + def _get_check_name(self, name, app='', extra=''): + name = ':'.join([self.review_type, name]) + if app: + name += ':' + app + if extra: + name += ':' + extra + return name + # click_report[][] = # result_type: info, warn, error # review_name: name of the check (prefixed with self.review_type) @@ -504,16 +513,23 @@ if result_type not in self.result_types: error("Invalid result type '%s'" % result_type) - name = "%s_%s" % (self.review_type, review_name) - if name not in self.click_report[result_type]: - self.click_report[result_type][name] = dict() + if review_name not in self.click_report[result_type]: + # log info about check so it can be collected into the + # check-names.list file + # format should be + # CHECK|| + msg = 'CHECK|{}|{}' + name = ':'.join(review_name.split(':')[:2]) + link_text = link if link is not None else "" + logging.debug(msg.format(name, link_text)) + self.click_report[result_type][review_name] = dict() - self.click_report[result_type][name].update({ + self.click_report[result_type][review_name].update({ 'text': result, 'manual_review': manual_review, }) if link is not None: - self.click_report[result_type][name]["link"] = link + self.click_report[result_type][review_name]["link"] = link def do_report(self): '''Print report''' diff -Nru click-reviewers-tools-0.33/clickreviews/cr_content_hub.py click-reviewers-tools-0.34/clickreviews/cr_content_hub.py --- click-reviewers-tools-0.33/clickreviews/cr_content_hub.py 2015-07-22 16:46:42.000000000 +0000 +++ click-reviewers-tools-0.34/clickreviews/cr_content_hub.py 2015-09-16 14:16:24.000000000 +0000 @@ -78,7 +78,7 @@ for app in sorted(self.content_hub): for k in self.content_hub[app].keys(): t = "info" - n = "valid_%s_%s" % (app, k) + n = self._get_check_name('valid', app=app, extra=k) s = "OK" if not isinstance(self.content_hub[app][k], list): @@ -93,7 +93,7 @@ for v in self.content_hub[app][k]: t = "info" - n = "valid_%s_%s_value" % (app, k) + n = self._get_check_name('valid_value', app=app, extra=k) s = "OK" if not isinstance(v, str): t = "error" @@ -108,7 +108,7 @@ for app in sorted(self.content_hub): unknown = [] t = "info" - n = "unknown_%s" % app + n = self._get_check_name('unknown', app=app) s = "OK" for key in self.content_hub[app].keys(): if key not in self.valid_keys: diff -Nru click-reviewers-tools-0.33/clickreviews/cr_desktop.py click-reviewers-tools-0.34/clickreviews/cr_desktop.py --- click-reviewers-tools-0.33/clickreviews/cr_desktop.py 2015-07-22 16:46:42.000000000 +0000 +++ click-reviewers-tools-0.34/clickreviews/cr_desktop.py 2015-09-16 14:16:24.000000000 +0000 @@ -110,7 +110,7 @@ def check_desktop_file(self): '''Check desktop file''' t = 'info' - n = 'files_usable' + n = self._get_check_name('files_usable') s = 'OK' if len(self._get_desktop_files().keys()) != self.desktop_hook_entries: t = 'error' @@ -124,7 +124,7 @@ for app in sorted(self.desktop_entries): de = self._get_desktop_entry(app) t = 'info' - n = 'validates (%s)' % app + n = self._get_check_name('validates', app=app) s = 'OK' l = None try: @@ -140,7 +140,7 @@ for app in sorted(self.desktop_entries): de = self._get_desktop_entry(app) t = 'info' - n = 'required_keys (%s)' % app + n = self._get_check_name('required_keys', app=app) s = "OK" missing = [] for f in self.required_keys: @@ -152,7 +152,7 @@ self._add_result(t, n, s) t = 'info' - n = 'required_fields_not_empty (%s)' % app + n = self._get_check_name('required_fields_not_empty', app=app) s = "OK" empty = [] for f in self.required_keys: @@ -168,7 +168,7 @@ for app in sorted(self.desktop_entries): de = self._get_desktop_entry(app) t = 'info' - n = 'blacklisted_keys (%s)' % app + n = self._get_check_name('blacklisted_keys', app=app) s = "OK" found = [] for f in self.blacklisted_keys: @@ -184,7 +184,7 @@ for app in sorted(self.desktop_entries): de = self._get_desktop_entry(app) t = 'info' - n = 'Exec (%s)' % app + n = self._get_check_name('Exec', app=app) s = 'OK' l = None if not de.hasKey('Exec'): @@ -219,7 +219,7 @@ for app in sorted(self.desktop_entries): de = self._get_desktop_entry(app) t = 'info' - n = 'Exec_webapp_container (%s)' % app + n = self._get_check_name('Exec_webapp_container', app=app) s = 'OK' if not de.hasKey('Exec'): t = 'error' @@ -245,7 +245,7 @@ continue t = 'info' - n = 'Exec_webapp_container_webapp (%s)' % (app) + n = self._get_check_name('Exec_webapp_container_webapp', app=app) s = 'OK' if '--webapp' in de.getExec().split(): t = 'error' @@ -254,7 +254,7 @@ self._add_result(t, n, s) t = 'info' - n = 'Exec_webapp_container_13.10 (%s)' % (app) + n = self._get_check_name('Exec_webapp_container_13.10', app=app) s = 'OK' if self.manifest['framework'] == "ubuntu-sdk-13.10": t = 'info' @@ -268,7 +268,7 @@ for app in sorted(self.desktop_entries): de = self._get_desktop_entry(app) t = 'info' - n = 'Exec_webbrowser (%s)' % app + n = self._get_check_name('Exec_webbrowser', app=app) s = 'OK' if not de.hasKey('Exec'): t = 'error' @@ -281,7 +281,7 @@ continue t = 'info' - n = 'Exec_webbrowser_webapp (%s)' % (app) + n = self._get_check_name('Exec_webbrowser_webapp', app=app) s = 'OK' if '--webapp' not in de.getExec().split(): t = 'error' @@ -290,7 +290,7 @@ self._add_result(t, n, s) t = 'info' - n = 'Exec_webbrowser_13.10 (%s)' % (app) + n = self._get_check_name('Exec_webbrowser_13.10', app=app) s = 'OK' if self.manifest['framework'] != "ubuntu-sdk-13.10": t = 'error' @@ -303,7 +303,7 @@ for app in sorted(self.desktop_entries): de = self._get_desktop_entry(app) t = 'info' - n = 'Exec_webapp_args (%s)' % app + n = self._get_check_name('Exec_webapp_args', app=app) s = 'OK' if not de.hasKey('Exec'): t = 'error' @@ -317,7 +317,7 @@ continue t = 'info' - n = 'Exec_webapp_args_minimal_chrome (%s)' % (app) + n = self._get_check_name('Exec_webapp_args_minimal_chrome', app=app) s = 'OK' if '--enable-back-forward' not in de.getExec().split(): s = "could not find --enable-back-forward in '%s'" % \ @@ -327,7 +327,7 @@ # verify the presence of either webappUrlPatterns or # webappModelSearchPath t = 'info' - n = 'Exec_webapp_args_required (%s)' % (app) + n = self._get_check_name('Exec_webapp_args_required', app=app) s = 'OK' found_url_patterns = False found_model_search_path = False @@ -354,8 +354,8 @@ is_launching_local_app = False break if is_launching_local_app and \ - (found_url_patterns or found_model_search_path - or found_named_webapp): + (found_url_patterns or found_model_search_path or + found_named_webapp): t = 'error' s = "should not specify --webappUrlPatterns, " + \ "--webappModelSearchPath or --webapp= when " + \ @@ -376,8 +376,9 @@ urlp_t = urlsplit(target) t = 'info' - n = 'Exec_webbrowser_webapp_url_patterns_has_https? (%s, %s)' % \ - (app, pattern) + n = self._get_check_name( + 'Exec_webbrowser_webapp_url_patterns_has_https', app=app, + extra=pattern) s = 'OK' if not pattern.startswith('https?://'): t = 'warn' @@ -386,8 +387,9 @@ self._add_result(t, n, s) t = 'info' - n = 'Exec_webbrowser_webapp_url_patterns_uses_trailing_glob ' + \ - '(%s, %s)' % (app, pattern) + n = self._get_check_name( + 'Exec_webbrowser_webapp_url_patterns_uses_trailing_glob', + app=app, extra=pattern) s = 'OK' if not pattern.endswith('*'): t = 'warn' @@ -396,8 +398,9 @@ self._add_result(t, n, s) t = 'info' - n = 'Exec_webbrowser_webapp_url_patterns_uses_unsafe_glob ' + \ - '(%s, %s)' % (app, pattern) + n = self._get_check_name( + 'Exec_webbrowser_webapp_url_patterns_uses_unsafe_glob', + app=app, extra=pattern) s = 'OK' if len(urlp_p.path) == 0 and pattern.endswith('*'): t = 'error' @@ -405,8 +408,9 @@ self._add_result(t, n, s) t = 'info' - n = 'Exec_webbrowser_webapp_url_patterns_uses_safe_glob ' + \ - '(%s, %s)' % (app, pattern) + n = self._get_check_name( + 'Exec_webbrowser_webapp_url_patterns_uses_safe_glob', + app=app, extra=pattern) s = 'OK' if '*' in pattern[:-1] and \ (pattern[:-1].count('*') != 1 or @@ -417,7 +421,7 @@ self._add_result(t, n, s) t = 'info' - n = 'Exec_webbrowser_target_exists (%s)' % (app) + n = self._get_check_name('Exec_webbrowser_target_exists', app=app) s = 'OK' if urlp_t.scheme == "": t = 'error' @@ -427,8 +431,9 @@ self._add_result(t, n, s) t = 'info' - n = 'Exec_webbrowser_target_scheme_matches_patterns ' + \ - '(%s, %s)' % (app, pattern) + n = self._get_check_name( + 'Exec_webbrowser_target_scheme_matches_patterns', + app=app, extra=pattern) s = 'OK' if not re.match(r'^%s$' % urlp_scheme_pat, urlp_t.scheme): t = 'error' @@ -438,8 +443,9 @@ self._add_result(t, n, s) t = 'info' - n = 'Exec_webbrowser_target_netloc_matches_patterns ' + \ - '(%s, %s)' % (app, pattern) + n = self._get_check_name( + 'Exec_webbrowser_target_netloc_matches_patterns', + app=app, extra=pattern) s = 'OK' # TODO: this is admittedly simple, but matches Canonical # webapps currently, so ok for now @@ -474,7 +480,8 @@ args = execline[1:] t = 'info' - n = 'Exec_webbrowser_webappUrlPatterns (%s)' % app + n = self._get_check_name( + 'Exec_webbrowser_webappUrlPatterns', app=app) s = 'OK' pats = "" count = 0 @@ -530,7 +537,8 @@ args = execline[1:] t = 'info' - n = 'Exec_webbrowser_webappModelSearchPath present (%s)' % app + n = self._get_check_name( + 'Exec_webbrowser_webappModelSearchPath_present', app=app) s = 'OK' path = "" count = 0 @@ -566,7 +574,8 @@ # ubuntu-webapps-*/ manifests = self._extract_webapp_manifests() t = 'info' - n = 'Exec_webbrowser_webapp_manifest (%s)' % app + n = self._get_check_name( + 'Exec_webbrowser_webapp_manifest', app=app) s = 'OK' if len(manifests) == 0: t = 'error' @@ -589,8 +598,9 @@ m = manifests[k] t = 'info' - n = 'Exec_webbrowser_webapp_manifest_wellformed (%s, %s)' % \ - (app, k) + n = self._get_check_name( + 'Exec_webbrowser_webapp_manifest_wellformed', app=app, + extra=k) s = 'OK' if m is None or m == 'null': # 'null' is for testsuite t = 'error' @@ -602,8 +612,9 @@ # 'includes' contains the patterns t = 'info' - n = 'Exec_webbrowser_webapp_manifest_includes_present ' + \ - '(%s, %s)' % (app, k) + n = self._get_check_name( + 'Exec_webbrowser_webapp_manifest_includes_present', + app=app, extra=k) s = 'OK' if 'includes' not in m: t = 'error' @@ -622,7 +633,7 @@ for app in sorted(self.desktop_entries): de = self._get_desktop_entry(app) t = 'info' - n = 'groups (%s)' % app + n = self._get_check_name('groups', app=app) s = "OK" if len(de.groups()) != 1: t = 'error' @@ -637,7 +648,7 @@ for app in sorted(self.desktop_entries): de = self._get_desktop_entry(app) t = 'info' - n = 'Type (%s)' % app + n = self._get_check_name('Type', app=app) s = "OK" if not de.hasKey('Type'): t = 'error' @@ -652,7 +663,7 @@ for app in sorted(self.desktop_entries): de = self._get_desktop_entry(app) t = 'info' - n = 'X-Ubuntu-Touch (%s)' % app + n = self._get_check_name('X-Ubuntu-Touch', app=app) s = "OK" if not de.hasKey('X-Ubuntu-Touch'): t = 'error' @@ -668,7 +679,7 @@ for app in sorted(self.desktop_entries): de = self._get_desktop_entry(app) t = 'info' - n = 'X-Ubuntu-StageHint (%s)' % app + n = self._get_check_name('X-Ubuntu-StageHint', app=app) s = "OK" if not de.hasKey('X-Ubuntu-StageHint'): t = 'info' @@ -685,7 +696,7 @@ for app in sorted(self.desktop_entries): de = self._get_desktop_entry(app) t = 'info' - n = 'X-Ubuntu-Gettext-Domain (%s)' % app + n = self._get_check_name('X-Ubuntu-Gettext-Domain', app=app) s = "OK" if not de.hasKey('X-Ubuntu-Gettext-Domain'): t = 'info' @@ -707,7 +718,7 @@ for app in sorted(self.desktop_entries): de = self._get_desktop_entry(app) t = 'info' - n = 'Terminal (%s)' % app + n = self._get_check_name('Terminal', app=app) s = "OK" if not de.hasKey('Terminal'): s = "OK (not specified)" @@ -721,7 +732,7 @@ for app in sorted(self.desktop_entries): de = self._get_desktop_entry(app) t = 'info' - n = 'Version (%s)' % app + n = self._get_check_name('Version', app=app) s = "OK" l = None if not de.hasKey('Version'): @@ -739,7 +750,7 @@ for app in sorted(self.desktop_entries): de = self._get_desktop_entry(app) t = 'info' - n = 'Comment_boilerplate (%s)' % app + n = self._get_check_name('Comment_boilerplate', app=app) s = "OK" l = None if de.hasKey('Comment') and \ @@ -759,7 +770,7 @@ for app in sorted(self.desktop_entries): de = self._get_desktop_entry(app) t = 'info' - n = 'Icon (%s)' % app + n = self._get_check_name('Icon', app=app) s = 'OK' l = None if not de.hasKey('Icon'): @@ -791,7 +802,7 @@ found = [] dupes = [] t = 'info' - n = 'duplicate_keys (%s)' % app + n = self._get_check_name('duplicate_keys', app=app) s = 'OK' fn = self._get_desktop_filename(app) content = open_file_read(fn).readlines() diff -Nru click-reviewers-tools-0.33/clickreviews/cr_framework.py click-reviewers-tools-0.34/clickreviews/cr_framework.py --- click-reviewers-tools-0.33/clickreviews/cr_framework.py 2015-07-22 16:46:42.000000000 +0000 +++ click-reviewers-tools-0.34/clickreviews/cr_framework.py 2015-09-16 14:16:24.000000000 +0000 @@ -106,7 +106,7 @@ def check_framework_hook_obsolete(self): '''Check manifest doesn't specify 'framework' hook''' t = 'info' - n = "obsolete_declaration" + n = self._get_check_name("obsolete_declaration") s = "OK" if len(self.frameworks) > 0: t = 'error' @@ -119,7 +119,7 @@ if not self.is_snap or self.pkg_yaml['type'] != 'framework': return t = 'info' - n = "obsolete_framework_file" + n = self._get_check_name("obsolete_framework_file") s = "OK" if self._has_framework_in_metadir(): t = 'warn' @@ -131,7 +131,7 @@ if not self.is_snap or self.pkg_yaml['type'] != 'framework': return t = 'info' - n = "framework_dependency" + n = self._get_check_name("dependency") s = "OK" if "frameworks" in self.pkg_yaml: t = 'error' @@ -144,7 +144,7 @@ return t = 'info' - n = "framework_policies" + n = self._get_check_name("policies") s = "OK" found = False for i in self.framework_policy_dirs: @@ -161,7 +161,7 @@ self._add_result(t, n, s) t = 'info' - n = "framework_policy_unknown" + n = self._get_check_name("policy_unknown") s = "OK" if len(self.framework_policy_unknown) > 0: t = 'warn' @@ -175,7 +175,7 @@ return t = 'info' - n = "framework_policy_metadata" + n = self._get_check_name("policy_metadata") s = "OK" msgs = [] for term in ["# Description: ", "# Usage: "]: @@ -203,7 +203,7 @@ return t = 'info' - n = "framework_has_all_policy" + n = self._get_check_name("has_all_policy") s = "OK" if len(self.framework_policy.keys()) == 0: s = "OK (skipped missing policy)" @@ -217,7 +217,8 @@ if t == i: continue t = 'info' - n = "framework_policy_%s/%s/%s" % (i, j, k) + n = self._get_check_name( + "policy", extra="%s/%s/%s" % (i, j, k)) s = "OK" if j not in self.framework_policy[other] or \ k not in self.framework_policy[other][j]: @@ -236,7 +237,8 @@ for k in self.framework_policy[i][j]: f = "%s/%s/%s" % (i, j, k) t = 'info' - n = "framework_policy_valid_name_%s" % f + n = self._get_check_name( + "policy_valid_name", extra=f) s = "OK" if not re.search(r'^[a-z0-9][a-z0-9+\.-]+$', k): t = 'error' diff -Nru click-reviewers-tools-0.33/clickreviews/cr_functional.py click-reviewers-tools-0.34/clickreviews/cr_functional.py --- click-reviewers-tools-0.33/clickreviews/cr_functional.py 2015-07-22 16:46:42.000000000 +0000 +++ click-reviewers-tools-0.34/clickreviews/cr_functional.py 2015-09-16 14:16:24.000000000 +0000 @@ -40,7 +40,7 @@ def check_applicationName(self): '''Check applicationName matches click manifest''' t = 'info' - n = 'qml_applicationName_matches_manifest' + n = self._get_check_name('qml_applicationName_matches_manifest') s = "OK" l = None @@ -123,7 +123,7 @@ def check_qtwebkit(self): '''Check that QML applications don't use QtWebKit''' t = 'info' - n = 'qml_application_uses_QtWebKit' + n = self._get_check_name('qml_application_uses_QtWebKit') s = "OK" l = None @@ -144,7 +144,7 @@ self._add_result(t, n, s, l) t = 'info' - n = 'qml_application_uses_UbuntuWebView_0.2' + n = self._get_check_name('qml_application_uses_UbuntuWebView_0.2') s = "OK" l = None @@ -171,7 +171,7 @@ def check_friends(self): '''Check that QML applications don't use deprecated Friends API''' t = 'info' - n = 'qml_application_uses_friends' + n = self._get_check_name('qml_application_uses_friends') s = "OK" l = None diff -Nru click-reviewers-tools-0.33/clickreviews/cr_lint.py click-reviewers-tools-0.34/clickreviews/cr_lint.py --- click-reviewers-tools-0.33/clickreviews/cr_lint.py 2015-07-22 16:46:42.000000000 +0000 +++ click-reviewers-tools-0.34/clickreviews/cr_lint.py 2015-09-16 14:16:24.000000000 +0000 @@ -63,25 +63,22 @@ if 'maintainer' in self.manifest: maintainer = self.manifest['maintainer'] self.email = maintainer.partition('<')[2].rstrip('>') - self.is_core_app = (self.click_pkgname.startswith('com.ubuntu.') - and not self.click_pkgname.startswith( - 'com.ubuntu.developer.') - and (self.email == - 'ubuntu-touch-coreapps@lists.launchpad.net' or - self.email == - 'ubuntu-devel-discuss@lists.ubuntu.com')) + self.is_core_app = \ + (self.click_pkgname.startswith('com.ubuntu.') and + not self.click_pkgname.startswith('com.ubuntu.developer.') and + (self.email == 'ubuntu-touch-coreapps@lists.launchpad.net' or + self.email == 'ubuntu-devel-discuss@lists.ubuntu.com')) # "core scope" is not necessarily a word we use right now, but # we want to special case scopes which are written through our # vetted development process. - self.is_core_scope = (self.click_pkgname.startswith('com.ubuntu.scopes.') - and self.email == - 'ubuntu-devel-discuss@lists.ubuntu.com') + self.is_core_scope = (self.click_pkgname.startswith('com.ubuntu.scopes.') and + self.email == 'ubuntu-devel-discuss@lists.ubuntu.com') # "core snappy" is not necessarily a word we use right now, but # we want to special case scopes which are written through our # vetted development process. - self.is_core_snappy = (self.click_pkgname.startswith('com.ubuntu.snappy.') - and self.email == - 'ubuntu-devel-discuss@lists.ubuntu.com') + self.is_core_snappy = \ + (self.click_pkgname.startswith('com.ubuntu.snappy.') and + self.email == 'ubuntu-devel-discuss@lists.ubuntu.com') else: self.email = None self.is_core_app = False @@ -131,7 +128,8 @@ '''Check DEBIAN/* files''' for f in self.control_files: t = 'info' - n = 'DEBIAN_has_%s' % os.path.basename(f) + n = self._get_check_name( + 'DEBIAN_has_files', extra=os.path.basename(f)) s = "OK" if not os.path.isfile(self.control_files[os.path.basename(f)]): if self.is_snap and os.path.basename(f) == 'md5sums': @@ -146,7 +144,7 @@ if os.path.basename(f) not in self.control_files: found.append(os.path.basename(f)) t = 'info' - n = 'DEBIAN_extra_files' + n = self._get_check_name('DEBIAN_extra_files') s = 'OK' if len(found) > 0: t = 'warn' @@ -158,7 +156,7 @@ fh = self._extract_control_file() tmp = list(Deb822.iter_paragraphs(fh)) t = 'info' - n = 'control_structure' + n = self._get_check_name('control_structure') s = 'OK' if len(tmp) != 1: self._add_result('error', n, @@ -178,7 +176,7 @@ error = False for f in sorted(fields): t = 'info' - n = 'control_has_%s' % f + n = self._get_check_name('control_has_field', extra=f) s = 'OK' if f not in control: t = 'error' @@ -189,7 +187,7 @@ return t = 'info' - n = 'control_extra_fields' + n = self._get_check_name('control_extra_fields') s = 'OK' found = [] for k in sorted(control.keys()): @@ -200,7 +198,7 @@ "found extra fields: '%s'" % (", ".join(found))) t = 'info' - n = 'control_package_match' + n = self._get_check_name('control_package_match') s = "OK" if self.manifest['name'] != self.click_pkgname: t = 'error' @@ -209,7 +207,7 @@ self._add_result(t, n, s) t = 'info' - n = 'control_version_match' + n = self._get_check_name('control_version_match') s = "OK" if self.manifest['version'] != self.click_version: t = 'error' @@ -218,7 +216,7 @@ self._add_result(t, n, s) t = 'info' - n = 'control_architecture_match' + n = self._get_check_name('control_architecture_match') s = 'OK' if 'architecture' in self.manifest: if control['Architecture'] == "multi": @@ -245,7 +243,7 @@ self._add_result(t, n, s) t = 'info' - n = 'control_maintainer_match' + n = self._get_check_name('control_maintainer_match') s = 'OK' if 'maintainer' in self.manifest: if control['Maintainer'] != self.manifest['maintainer']: @@ -259,7 +257,7 @@ # TODO: click currently sets the Description to be the manifest title. # Is this intended behavior? t = 'info' - n = 'control_description_match' + n = self._get_check_name('control_description_match') s = 'OK' if 'title' in self.manifest: if control['Description'].strip() != \ @@ -273,7 +271,7 @@ self._add_result(t, n, s) t = 'info' - n = 'control_click_version_up_to_date' + n = self._get_check_name('control_click_version_up_to_date') s = 'OK' l = None @@ -286,7 +284,7 @@ self._add_result(t, n, s, l) t = 'info' - n = 'control_installed_size' + n = self._get_check_name('control_installed_size') s = 'OK' try: int(control['Installed-Size']) @@ -313,7 +311,7 @@ os.chdir(curdir) t = 'info' - n = 'md5sums' + n = self._get_check_name('md5sums') s = 'OK' if len(badsums) > 0: t = 'error' @@ -334,7 +332,7 @@ fh.close() t = 'info' - n = 'preinst' + n = self._get_check_name('preinst') s = "OK" if contents != expected: t = 'error' @@ -350,25 +348,24 @@ # Some checks are already handled in # cr_common.py:_verify_manifest_structure() - # While we support multiple apps in the hooks db, we don't support - # multiple apps specifying desktop hooks. Eg, it is ok to specify a - # scope, an app and a push-helper, but it isn't ok to specify two apps t = 'info' - n = 'hooks_multiple_apps' + n = self._get_check_name('hooks_multiple_apps') s = 'OK' count = 0 for app in self.manifest['hooks']: if "desktop" in self.manifest['hooks'][app]: count += 1 if count > 1: - t = 'error' + # 'info' for now but this might be removed in a future version + # (see https://launchpad.net/bugs/1496402) + t = 'info' s = 'more than one desktop app specified in hooks' self._add_result(t, n, s) # Verify keys are well-formatted for app in self.manifest['hooks']: t = 'info' - n = 'hooks_%s_valid' % app + n = self._get_check_name('hooks_valid', app=app) s = "OK" if not re.search(r'^[A-Za-z0-9+-.:~-]+$', app): t = 'error' @@ -380,7 +377,7 @@ for f in required: for app in self.manifest['hooks']: t = 'info' - n = 'hooks_%s_%s' % (app, f) + n = self._get_check_name('hooks', app=app, extra=f) s = "OK" if f in list(filter(lambda a: a.startswith('account-'), self.known_hooks)): @@ -416,7 +413,7 @@ mutually_exclusive = ['scope', 'desktop'] for app in self.manifest['hooks']: t = 'info' - n = 'exclusive_hooks_%s' % (app) + n = self._get_check_name('exclusive_hooks', app=app) s = "OK" found = [] for i in mutually_exclusive: @@ -430,7 +427,7 @@ for app in self.manifest['hooks']: if "apparmor" in self.manifest['hooks'][app]: t = 'info' - n = 'sdk_security_extension_%s' % (app) + n = self._get_check_name('sdk_security_extension', app=app) s = "OK" fn = self.manifest['hooks'][app]['apparmor'] if not fn.endswith(".apparmor"): @@ -445,14 +442,14 @@ return t = 'info' - n = 'unknown hooks' + n = self._get_check_name('unknown_hooks') s = 'OK' # Verify keys are well-formatted for app in self.manifest['hooks']: for hook in self.manifest['hooks'][app]: t = 'info' - n = 'hooks_%s_%s_known' % (app, hook) + n = self._get_check_name('hooks_known', app=app, extra=hook) s = "OK" if hook not in self.known_hooks: t = 'warn' @@ -462,13 +459,13 @@ def check_hooks_redflagged(self): '''Check if have any redflagged hooks''' t = 'info' - n = 'redflagged hooks' + n = self._get_check_name('redflagged_hooks') s = 'OK' for app in self.manifest['hooks']: found = [] t = 'info' - n = 'hooks_redflag_%s' % (app) + n = self._get_check_name('hooks_redflag', app=app) s = "OK" manual_review = False for hook in self.manifest['hooks'][app]: @@ -486,7 +483,7 @@ def check_external_symlinks(self): '''Check if symlinks in the click package go out to the system.''' t = 'info' - n = 'external_symlinks' + n = self._get_check_name('external_symlinks') s = 'OK' external_symlinks = list(filter(lambda link: not @@ -505,7 +502,7 @@ p = self.manifest['name'] # http://www.debian.org/doc/debian-policy/ch-controlfields.html t = 'info' - n = 'pkgname_valid' + n = self._get_check_name('pkgname_valid') s = "OK" if not self._verify_pkgname(p): t = 'error' @@ -516,7 +513,7 @@ '''Check package version is valid''' # deb-version(5) t = 'info' - n = 'version_valid' + n = self._get_check_name('version_valid') s = "OK" # From debian_support.py re_valid_version = re.compile(r'^((\d+):)?' # epoch @@ -530,7 +527,7 @@ def check_architecture(self): '''Check package architecture in DEBIAN/control is valid''' t = 'info' - n = 'control_architecture_valid' + n = self._get_check_name('control_architecture_valid') s = 'OK' if self.click_arch not in self.valid_control_architectures: t = 'error' @@ -540,7 +537,7 @@ def check_architecture_all(self): '''Check if actually architecture all''' t = 'info' - n = 'control_architecture_valid_contents' + n = self._get_check_name('control_architecture_valid_contents') s = 'OK' if self.click_arch != "all": self._add_result(t, n, s) @@ -559,7 +556,7 @@ def check_architecture_specified_needed(self): '''Check if the specified architecture is actually needed''' t = 'info' - n = 'control_architecture_specified_needed' + n = self._get_check_name('control_architecture_specified_needed') s = 'OK' if self.click_arch == "all": s = "SKIPPED: architecture is 'all'" @@ -575,7 +572,7 @@ def check_maintainer(self): '''Check maintainer()''' t = 'info' - n = 'maintainer_present' + n = self._get_check_name('maintainer_present') s = 'OK' if 'maintainer' not in self.manifest: if self.is_snap: @@ -591,7 +588,7 @@ # Simple regex as used by python3-debian. If we wanted to be more # thorough we could use email_re from django.core.validators t = 'info' - n = 'maintainer_format' + n = self._get_check_name('maintainer_format') s = 'OK' if self.manifest['maintainer'] == "": self._add_result('error', n, 'invalid maintainer (empty), (should be ' @@ -610,7 +607,7 @@ def check_title(self): '''Check title()''' t = 'info' - n = 'title_present' + n = self._get_check_name('title_present') s = 'OK' if 'title' not in self.manifest: s = 'required title field not specified in manifest' @@ -619,7 +616,7 @@ self._add_result(t, n, s) t = 'info' - n = 'title' + n = self._get_check_name('title') s = 'OK' pkgname_base = self.click_pkgname.split('.')[-1] if len(self.manifest['title']) < len(pkgname_base): @@ -630,7 +627,7 @@ def check_description(self): '''Check description()''' t = 'info' - n = 'description_present' + n = self._get_check_name('description_present') s = 'OK' if 'description' not in self.manifest: s = 'required description field not specified in manifest' @@ -639,7 +636,7 @@ self._add_result(t, n, s) t = 'info' - n = 'description' + n = self._get_check_name('description') s = 'OK' pkgname_base = self.click_pkgname.split('.')[-1] if len(self.manifest['description']) < len(pkgname_base): @@ -655,7 +652,7 @@ def check_framework(self): '''Check framework()''' - n = 'framework' + n = self._get_check_name('framework') l = "http://askubuntu.com/questions/460512/what-framework-should-i-use-in-my-manifest-file" framework_overrides = self.overrides.get('framework', {}) frameworks = Frameworks(overrides=framework_overrides) @@ -697,7 +694,7 @@ def check_click_local_extensions(self): '''Report any click local extensions''' t = 'info' - n = 'click_local_extensions' + n = self._get_check_name('click_local_extensions') s = 'OK' found = [] for k in sorted(self.manifest): @@ -723,7 +720,7 @@ tmp = os.path.basename(self.click_package).split('_') click_package_bn = os.path.basename(self.click_package) t = 'info' - n = 'package_filename_format' + n = self._get_check_name('package_filename_format') s = 'OK' if len(tmp) != 3: t = 'warn' @@ -732,7 +729,7 @@ self._add_result(t, n, s) t = 'info' - n = 'package_filename_version_match' + n = self._get_check_name('package_filename_version_match') s = 'OK' l = None if len(tmp) >= 2: @@ -753,7 +750,7 @@ self._add_result(t, n, s, l) t = 'info' - n = 'package_filename_arch_valid' + n = self._get_check_name('package_filename_arch_valid') s = 'OK' if len(tmp) >= 3: if self.click_package.endswith('.snap'): @@ -777,7 +774,7 @@ self._add_result(t, n, s) t = 'info' - n = 'package_filename_arch_match' + n = self._get_check_name('package_filename_arch_match') s = 'OK' if len(tmp) >= 3: if self.click_package.endswith('.snap'): @@ -801,7 +798,7 @@ def check_vcs(self): '''Check for VCS files in the click package''' t = 'info' - n = 'vcs_files' + n = self._get_check_name('vcs_files') s = 'OK' found = [] for d in self.vcs_dirs: @@ -817,7 +814,7 @@ def check_click_in_package(self): '''Check for *.click files in the toplevel click package''' t = 'info' - n = 'click_files' + n = self._get_check_name('click_files') s = 'OK' found = [] entries = glob.glob("%s/*.click" % self.unpack_dir) @@ -833,7 +830,7 @@ '''Check for known hardcoded paths.''' PATH_BLACKLIST = ["/opt/click.ubuntu.com/"] t = 'info' - n = 'hardcoded_paths' + n = self._get_check_name('hardcoded_paths') s = 'OK' for dirpath, dirnames, filenames in os.walk(self.unpack_dir): for filename in filenames: @@ -854,7 +851,7 @@ def _verify_architecture(self, my_dict, test_str): t = 'info' - n = '%s_architecture_valid' % test_str + n = self._get_check_name('%s_architecture_valid' % test_str) s = 'OK' if 'architecture' not in my_dict: s = 'OK (architecture not specified)' @@ -887,7 +884,7 @@ def _verify_icon(self, my_dict, test_str): t = 'info' - n = '%s_icon_present' % test_str + n = self._get_check_name('%s_icon_present' % test_str) s = 'OK' if 'icon' not in my_dict: s = 'Skipped, optional icon not present' @@ -896,7 +893,7 @@ self._add_result(t, n, s) t = 'info' - n = '%s_icon_empty' % test_str + n = self._get_check_name('%s_icon_empty' % test_str) s = 'OK' if len(my_dict['icon']) == 0: t = 'error' @@ -905,7 +902,7 @@ self._add_result(t, n, s) t = 'info' - n = '%s_icon_absolute_path' % test_str + n = self._get_check_name('%s_icon_absolute_path' % test_str) s = 'OK' if my_dict['icon'].startswith('/'): t = 'error' @@ -923,7 +920,7 @@ return t = 'info' - n = 'snappy_name_valid' + n = self._get_check_name('snappy_name_valid') s = 'OK' if 'name' not in self.pkg_yaml: t = 'error' @@ -939,7 +936,7 @@ return t = 'info' - n = 'snappy_version_valid' + n = self._get_check_name('snappy_version_valid') s = 'OK' if 'version' not in self.pkg_yaml: t = 'error' @@ -955,7 +952,7 @@ return t = 'info' - n = 'snappy_type_valid' + n = self._get_check_name('snappy_type_valid') s = 'OK' if 'type' not in self.pkg_yaml: s = 'OK (skip missing)' @@ -970,7 +967,7 @@ return t = 'info' - n = 'snappy_type_redflag' + n = self._get_check_name('snappy_type_redflag') s = "OK" l = None manual_review = False @@ -990,7 +987,7 @@ return t = 'info' - n = 'snappy_vendor_valid' + n = self._get_check_name('snappy_vendor_valid') s = 'OK' if 'vendor' not in self.pkg_yaml: s = "OK (skip missing)" @@ -1019,7 +1016,7 @@ return t = 'info' - n = 'snappy_unknown' + n = self._get_check_name('snappy_unknown') s = 'OK' unknown = [] for f in self.pkg_yaml: @@ -1052,7 +1049,7 @@ contents = self._extract_readme_md() t = 'info' - n = 'snappy_readme.md' + n = self._get_check_name('snappy_readme.md') s = 'OK' if contents is None: t = 'error' @@ -1062,7 +1059,7 @@ self._add_result(t, n, s) t = 'info' - n = 'snappy_readme.md_length' + n = self._get_check_name('snappy_readme.md_length') s = 'OK' pkgname_base = self.pkg_yaml['name'].split('.')[0] if len(contents) < len(pkgname_base): @@ -1084,7 +1081,7 @@ return t = 'info' - n = 'snappy_config_hook_executable' + n = self._get_check_name('snappy_config_hook_executable') s = 'OK' if not self._check_innerpath_executable(fn): t = 'error' @@ -1113,7 +1110,8 @@ app = os.path.basename(a['name']) t = 'info' - n = 'snappy_%s_in_%s' % (app, other_exe_t) + n = self._get_check_name( + 'snappy_in_%s' % other_exe_t, app=app) s = 'OK' for other_a in self.pkg_yaml[other_exe_t]: other_app = os.path.basename(other_a['name']) @@ -1142,14 +1140,14 @@ if 'archive-sha512' not in hashes_yaml: t = 'error' - n = 'hashes_archive-sha512_present' + n = self._get_check_name('hashes_archive-sha512_present') s = "'archive-sha512' not found in hashes.yaml" self._add_result(t, n, s) return # verify the ar file t = 'info' - n = 'hashes_archive-sha512_valid' + n = self._get_check_name('hashes_archive-sha512_valid') s = 'OK' fn = self._path_join(self.raw_unpack_dir, 'data.tar.gz') sum = self._get_sha512sum(fn) @@ -1163,7 +1161,7 @@ if 'files' not in hashes_yaml: t = 'error' - n = 'hashes_files_present' + n = self._get_check_name('hashes_files_present') s = "'files' not found in hashes.yaml" self._add_result(t, n, s) return @@ -1254,7 +1252,7 @@ entry['name'])) t = 'info' - n = 'sha512sums' + n = self._get_check_name('sha512sums') s = 'OK' if len(badsums) > 0: t = 'error' @@ -1262,7 +1260,7 @@ self._add_result(t, n, s) t = 'info' - n = 'file_mode' + n = self._get_check_name('file_mode') s = 'OK' if len(errors) > 0: t = 'error' @@ -1271,7 +1269,7 @@ # Now check for extra files t = 'info' - n = 'hashes_extra_files' + n = self._get_check_name('hashes_extra_files') s = 'OK' self._add_result(t, n, s) extra = [] diff -Nru click-reviewers-tools-0.33/clickreviews/cr_online_accounts.py click-reviewers-tools-0.34/clickreviews/cr_online_accounts.py --- click-reviewers-tools-0.33/clickreviews/cr_online_accounts.py 2015-07-22 16:46:42.000000000 +0000 +++ click-reviewers-tools-0.34/clickreviews/cr_online_accounts.py 2015-09-16 14:16:24.000000000 +0000 @@ -16,8 +16,10 @@ from __future__ import print_function -from clickreviews.cr_common import ClickReview, error +from clickreviews.cr_common import ClickReview, error, open_file_read +import json import os +import re # http://lxml.de/tutorial.html import lxml.etree as etree @@ -40,6 +42,13 @@ ClickReview.app_allowed_peer_hooks + \ ClickReview.scope_allowed_peer_hooks + peer_hooks['accounts'] = dict() + peer_hooks['accounts']['allowed'] = \ + [h for h in (ClickReview.app_allowed_peer_hooks + + ClickReview.scope_allowed_peer_hooks) + if not h.startswith('account-')] + peer_hooks['accounts']['required'] = ['apparmor'] + peer_hooks['account-provider'] = dict() peer_hooks['account-provider']['required'] = ['account-qml-plugin', 'apparmor' @@ -64,7 +73,8 @@ self.accounts_files = dict() self.accounts = dict() - self.account_hooks = ['account-application', + self.account_hooks = ['accounts', + 'account-application', 'account-provider', 'account-qml-plugin', 'account-service'] @@ -77,7 +87,7 @@ error("manifest malformed: hooks/%s/%s is not a str" % ( app, h)) - (full_fn, xml) = self._extract_account(app, h) + (full_fn, parsed) = self._extract_account(app, h) if app not in self.accounts_files: self.accounts_files[app] = dict() @@ -85,7 +95,28 @@ if app not in self.accounts: self.accounts[app] = dict() - self.accounts[app][h] = xml + self.accounts[app][h] = parsed + + self.required_keys = dict() + self.allowed_keys = dict() + self.required_keys["service"] = [ + ('provider', str), + ] + self.allowed_keys["service"] = [ + ('auth', dict), + ('name', str), + ('description', str), + ] + self.required_keys["plugin"] = [ + ('provider', str), + ('name', str), + ('icon', str), + ('qml', str), + ] + self.allowed_keys["plugin"] = [ + ('auth', dict), + ] + self.provider_re = re.compile('^[a-zA-Z0-9_.-]+$') def _extract_account(self, app, account_type): '''Extract accounts''' @@ -100,6 +131,23 @@ # the hook present for now if account_type == "account-qml-plugin": return (fn, True) + elif account_type == "accounts": + fh = open_file_read(fn) + contents = "" + for line in fh.readlines(): + contents += line + fh.close() + + try: + jd = json.loads(contents) + except Exception as e: + error("accounts json unparseable: %s (%s):\n%s" % (bn, + str(e), contents)) + + if not isinstance(jd, dict): + error("accounts json is malformed: %s:\n%s" % (bn, contents)) + + return (fn, jd) else: try: tree = etree.parse(fn) @@ -108,13 +156,120 @@ error("accounts xml unparseable: %s (%s)" % (bn, str(e))) return (fn, xml) + def check_hooks_versions(self): + '''Check hooks versions''' + framework = self.manifest['framework'] + if not framework.startswith("ubuntu-sdk"): + return + t = "error" + if framework < "ubuntu-sdk-15.10": + for app in sorted(self.accounts.keys()): + for hook in self.accounts[app].keys(): + if hook == "accounts": + n = self._get_check_name('%s_hook' % hook, app=app) + s = "'accounts' hook is not available in '%s' (must be 15.10 or later)" % \ + (framework) + self._add_result(t, n, s) + return + hook_state = "disallowed" + if framework < "ubuntu-sdk-16.04": + t = "warn" + hook_state = "deprecated" + for app in sorted(self.accounts.keys()): + for hook in self.accounts[app].keys(): + if hook.startswith("account-"): + n = self._get_check_name('%s_hook' % hook, app=app) + s = "'%s' is %s in %s: use 'accounts' hook instead" % \ + (hook, hook_state, framework) + self._add_result(t, n, s) + + def _check_object(self, obj_type, obj, n): + t = "info" + s = "OK" + if not isinstance(obj, dict): + t = "error" + s = "%s is not an object" % obj_type + self._add_result(t, n, s) + return + + for (k, vt) in self.required_keys[obj_type]: + if k not in obj.keys(): + t = "error" + s = "required key '%s' is missing" % k + self._add_result(t, n, s) + if t == "error": + return + + known_keys = self.required_keys[obj_type] + self.allowed_keys[obj_type] + for (k, v) in obj.items(): + type_list = [kk[1] for kk in known_keys if kk[0] == k] + if len(type_list) < 1: + t = "error" + s = "unrecognized key '%s'" % k + self._add_result(t, n, s) + continue + if not isinstance(v, type_list[0]): + t = "error" + s = "value for '%s' must be of type %s" % (k, type_list[0]) + self._add_result(t, n, s) + continue + if k == 'provider' and not self.provider_re.match(v): + t = "error" + s = "'provider' must only consist of alphanumeric characters" + self._add_result(t, n, s) + self._add_result(t, n, s) + + def _check_object_list(self, app, key, obj_type, obj_list): + t = 'info' + n = self._get_check_name('accounts_%s' % key, app=app) + if not isinstance(obj_list, list): + t = "error" + s = "'%s' is not a list" % key + elif len(obj_list) < 1: + t = "error" + s = "'%s' is empty" % key + if t == "error": + self._add_result(t, n, s) + return + + for (i, obj) in enumerate(obj_list): + n = self._get_check_name('accounts_%s' % (obj_type), app=app, extra=str(i)) + self._check_object(obj_type, obj, n) + + def check_manifest(self): + '''Check manifest''' + for app in sorted(self.accounts.keys()): + account_type = "accounts" + + t = 'info' + n = self._get_check_name('%s_root' % account_type, app=app) + s = "OK" + if account_type not in self.accounts[app]: + s = "OK (missing)" + self._add_result(t, n, s) + continue + + n = self._get_check_name('%s_services' % account_type, app=app) + if 'services' not in self.accounts[app][account_type]: + t = "error" + s = "'services' key is missing" + self._add_result(t, n, s) + continue + services = self.accounts[app][account_type]['services'] + self._check_object_list(app, "services", "service", services) + + n = self._get_check_name('%s_plugins' % account_type, app=app) + if 'plugins' in self.accounts[app][account_type]: + plugins = self.accounts[app][account_type]['plugins'] + self._check_object_list(app, "plugins", "plugin", plugins) + def check_application(self): '''Check application''' for app in sorted(self.accounts.keys()): account_type = "account-application" t = 'info' - n = '%s_%s_root' % (app, account_type) + n = self._get_check_name('%s_root' % account_type, app=app) s = "OK" if account_type not in self.accounts[app]: s = "OK (missing)" @@ -128,7 +283,7 @@ self._add_result(t, n, s) t = 'info' - n = '%s_%s_id' % (app, account_type) + n = self._get_check_name('%s_id' % account_type, app=app) s = "OK" if "id" in self.accounts[app][account_type].keys(): t = 'warn' @@ -136,7 +291,7 @@ self._add_result(t, n, s) t = 'info' - n = '%s_%s_services' % (app, account_type) + n = self._get_check_name('%s_services' % account_type, app=app) s = "OK" if self.accounts[app][account_type].find("services") is None: t = 'error' @@ -147,7 +302,7 @@ continue t = 'info' - n = '%s_%s_service' % (app, account_type) + n = self._get_check_name('%s_service' % account_type, app=app) s = "OK" if self.accounts[app][account_type].find("./services/service") \ is None: @@ -161,7 +316,7 @@ account_type = "account-service" t = 'info' - n = '%s_%s_root' % (app, account_type) + n = self._get_check_name('%s_root' % account_type, app=app) s = "OK" if account_type not in self.accounts[app]: s = "OK (missing)" @@ -175,7 +330,7 @@ self._add_result(t, n, s) t = 'info' - n = '%s_%s_id' % (app, account_type) + n = self._get_check_name('%s_id' % account_type, app=app) s = "OK" if "id" in self.accounts[app][account_type].keys(): t = 'warn' @@ -187,7 +342,8 @@ for tag in ['name', 'provider']: t = 'info' - n = '%s_%s_%s' % (app, account_type, tag) + n = self._get_check_name( + '%s_%s' % (account_type, tag), app=app) s = "OK" if self.accounts[app][account_type].find(tag) is None: t = 'error' @@ -200,7 +356,7 @@ account_type = "account-provider" t = 'info' - n = '%s_%s' % (app, account_type) + n = self._get_check_name(account_type, app=app) s = "OK" manual_review = False if account_type not in self.accounts[app]: @@ -210,7 +366,7 @@ self._add_result(t, n, s, manual_review=manual_review) t = 'info' - n = '%s_%s_root' % (app, account_type) + n = self._get_check_name('%s_root' % account_type, app=app) s = "OK" root_tag = self.accounts[app][account_type].tag.lower() if root_tag != "provider": @@ -219,7 +375,7 @@ self._add_result(t, n, s) t = 'info' - n = '%s_%s_id' % (app, account_type) + n = self._get_check_name('%s_id' % account_type, app=app) s = "OK" if "id" in self.accounts[app][account_type].keys(): t = 'warn' @@ -232,7 +388,7 @@ account_type = "account-qml-plugin" t = 'info' - n = '%s_%s' % (app, account_type) + n = self._get_check_name(account_type, app=app) s = "OK" manual_review = False if account_type not in self.accounts[app]: diff -Nru click-reviewers-tools-0.33/clickreviews/cr_push_helper.py click-reviewers-tools-0.34/clickreviews/cr_push_helper.py --- click-reviewers-tools-0.33/clickreviews/cr_push_helper.py 2015-07-22 16:46:42.000000000 +0000 +++ click-reviewers-tools-0.34/clickreviews/cr_push_helper.py 2015-09-16 14:16:24.000000000 +0000 @@ -80,7 +80,7 @@ for app in sorted(self.push_helper): for k in self.push_helper[app].keys(): t = "info" - n = "valid_%s_%s" % (app, k) + n = self._get_check_name("valid", app=app, extra=k) s = "OK" if not isinstance(self.push_helper[app][k], str): @@ -93,7 +93,7 @@ for k in self.required_keys: t = "info" - n = "valid_%s_required_%s" % (app, k) + n = self._get_check_name("valid_required", app=app, extra=k) s = "OK" if k not in self.push_helper[app]: t = "error" @@ -105,7 +105,7 @@ for app in sorted(self.push_helper): unknown = [] t = "info" - n = "unknown_%s" % app + n = self._get_check_name("unknown", app=app) s = "OK" for key in self.push_helper[app].keys(): if key not in self.required_keys and \ @@ -126,7 +126,7 @@ continue t = "info" - n = "other_hooks_%s" % app + n = self._get_check_name("other_hooks", app=app) s = "OK" bad = [] diff -Nru click-reviewers-tools-0.33/clickreviews/cr_scope.py click-reviewers-tools-0.34/clickreviews/cr_scope.py --- click-reviewers-tools-0.33/clickreviews/cr_scope.py 2015-07-22 16:46:42.000000000 +0000 +++ click-reviewers-tools-0.34/clickreviews/cr_scope.py 2015-09-16 14:16:24.000000000 +0000 @@ -83,7 +83,7 @@ '''Check scope .ini file''' for app in sorted(self.scopes.keys()): t = 'info' - n = 'ini_%s_scope_section' % app + n = self._get_check_name('ini_scope_section', app=app) s = "OK" sections = set(self.scopes[app]["scope_config"].sections()) @@ -123,7 +123,7 @@ missing = [] t = 'info' - n = 'ini_%s_scope_required_fields' % (app) + n = self._get_check_name('ini_scope_required_fields', app=app) s = "OK" for r in required: if r not in self.scopes[app]["scope_config"]['ScopeConfig']: @@ -141,7 +141,7 @@ self._add_result(t, n, s) t = 'info' - n = 'ini_%s_scope_unknown_fields' % (app) + n = self._get_check_name('ini_scope_unknown_fields', app=app) s = 'OK' unknown = [] for i in self.scopes[app]["scope_config"]['ScopeConfig'].keys(): diff -Nru click-reviewers-tools-0.33/clickreviews/cr_security.py click-reviewers-tools-0.34/clickreviews/cr_security.py --- click-reviewers-tools-0.33/clickreviews/cr_security.py 2015-07-22 16:46:42.000000000 +0000 +++ click-reviewers-tools-0.34/clickreviews/cr_security.py 2015-09-16 14:16:24.000000000 +0000 @@ -335,7 +335,7 @@ for app in sorted(self.security_apps): (f, m) = self._get_security_manifest(app) t = 'info' - n = 'policy_vendor (%s)' % f + n = self._get_check_name('policy_vendor', extra=f) s = "OK" if 'policy_vendor' in m and \ m['policy_vendor'] not in self.aa_policy: @@ -344,7 +344,7 @@ self._add_result(t, n, s) t = 'info' - n = 'policy_vendor_matches_framework (%s)' % (f) + n = self._get_check_name('policy_vendor_matches_framework', extra=f) s = "OK" if 'policy_vendor' in m: # policy_vendor is optional found_major = False @@ -377,7 +377,7 @@ for app in sorted(self.security_apps): (f, m) = self._get_security_manifest(app) - n = 'policy_version_exists (%s)' % f + n = self._get_check_name('policy_version_exists', extra=f) if 'policy_version' not in m: self._add_result('error', n, 'could not find policy_version in manifest') @@ -397,7 +397,9 @@ highest = self._get_highest_policy_version(vendor) t = 'info' - n = 'policy_version_is_highest (%s, %s)' % (str(highest), f) + n = self._get_check_name( + 'policy_version_is_highest', + extra='(%s, %s)' % (str(highest), f)) s = "OK" l = None if float(m['policy_version']) != highest: @@ -407,7 +409,7 @@ self._add_result(t, n, s, l) t = 'info' - n = 'policy_version_matches_framework (%s)' % (f) + n = self._get_check_name('policy_version_matches_framework', extra=f) s = "OK" found_major = False for name, data in self.major_framework_policy.items(): @@ -437,7 +439,7 @@ (f, m) = self._get_security_manifest(app) t = 'info' - n = 'template_with_policy_version (%s)' % f + n = self._get_check_name('template_with_policy_version', extra=f) s = "OK" if 'policy_version' not in m: self._add_result('error', n, @@ -446,7 +448,7 @@ self._add_result(t, n, s) t = 'info' - n = 'template_valid (%s)' % f + n = self._get_check_name('template_valid', extra=f) s = "OK" manual_review = False if 'template' not in m: @@ -464,7 +466,7 @@ self._add_result(t, n, s, manual_review=manual_review) t = 'info' - n = 'template_exists (%s)' % f + n = self._get_check_name('template_exists', extra=f) s = "OK" vendor = "ubuntu" if 'policy_vendor' in m: @@ -510,7 +512,7 @@ for app in sorted(self.security_apps): (f, m) = self._get_security_manifest(app) t = 'info' - n = 'policy_groups_webapp (%s)' % f + n = self._get_check_name('policy_groups_webapp', extra=f) s = "OK" webapp_template = "ubuntu-webapp" if 'template' not in m or m['template'] != webapp_template: @@ -531,7 +533,7 @@ self._add_result(t, n, s) t = 'info' - n = 'policy_groups_webapp_webview (%s)' % f + n = self._get_check_name('policy_groups_webapp_webview', extra=f) s = "OK" if self.manifest['framework'] == "ubuntu-sdk-13.10": s = "SKIPPED (webview not available in 13.10)" @@ -546,7 +548,7 @@ for app in sorted(self.security_apps): (f, m) = self._get_security_manifest(app) t = 'info' - n = 'template_push_helper(%s)' % f + n = self._get_check_name('template_push_helper', extra=f) s = "OK" if 'push-helper' not in self.manifest['hooks'][app]: continue @@ -560,7 +562,7 @@ for app in sorted(self.security_apps): (f, m) = self._get_security_manifest(app) t = 'info' - n = 'policy_groups_push_helper(%s)' % f + n = self._get_check_name('policy_groups_push_helper', extra=f) s = "OK" if 'push-helper' not in self.manifest['hooks'][app]: continue @@ -588,7 +590,7 @@ for app in sorted(self.security_apps): (f, m) = self._get_security_manifest(app) t = 'info' - n = 'policy_groups_scopes (%s)' % f + n = self._get_check_name('policy_groups_scopes', extra=f) s = "OK" # jdstrand, 2014-06-05: ubuntu-scope-local-content is no longer available # scope_templates = ['ubuntu-scope-network', @@ -624,7 +626,8 @@ continue t = 'info' - n = 'required_policy_groups_ubuntu_account_plugin(%s)' % f + n = self._get_check_name( + 'required_policy_groups_ubuntu_account_plugin', extra=f) s = "OK" if 'policy_groups' not in m: self._add_result('error', n, @@ -641,7 +644,8 @@ self._add_result(t, n, s) t = 'info' - n = 'policy_groups_ubuntu_account_plugin(%s)' % f + n = self._get_check_name( + 'policy_groups_ubuntu_account_plugin', extra=f) s = "OK" bad = [] for p in m['policy_groups']: @@ -658,7 +662,7 @@ (f, m) = self._get_security_manifest(app) t = 'info' - n = 'policy_groups_exists_%s (%s)' % (app, f) + n = self._get_check_name('policy_groups_exists', app=app, extra=f) if 'policy_groups' not in m: # If template not specified, we just use the default self._add_result('info', n, 'no policy groups specified') @@ -684,7 +688,7 @@ # Check for duplicates t = 'info' - n = 'policy_groups_duplicates_%s (%s)' % (app, f) + n = self._get_check_name('policy_groups_duplicates', app=app, extra=f) s = 'OK' tmp = [] for p in m['policy_groups']: @@ -711,7 +715,7 @@ # If we got here, we can see if valid policy groups were specified for i in m['policy_groups']: t = 'info' - n = 'policy_groups_valid_%s (%s)' % (app, i) + n = self._get_check_name('policy_groups_valid', app=app, extra=i) s = 'OK' # SDK will leave and empty policy group, report but don't @@ -744,7 +748,8 @@ if found: t = 'info' - n = 'policy_groups_safe_%s (%s)' % (app, i) + n = self._get_check_name( + 'policy_groups_safe', app=app, extra=i) s = 'OK' l = None manual_review = False @@ -779,7 +784,7 @@ (f, m) = self._get_security_manifest(app) t = 'info' - n = 'ignored_fields (%s)' % f + n = self._get_check_name('ignored_fields', extra=f) s = "OK" found = [] for i in self.ignored_fields: @@ -797,7 +802,7 @@ (f, m) = self._get_security_manifest(app) t = 'info' - n = 'redflag_fields (%s)' % f + n = self._get_check_name('redflag_fields', extra=f) s = "OK" found = [] for i in self.redflag_fields: @@ -819,7 +824,7 @@ (f, m) = self._get_security_manifest(app) t = 'info' - n = 'required_fields (%s)' % f + n = self._get_check_name('required_fields', extra=f) s = "OK" not_found = [] for i in self.required_fields: @@ -843,7 +848,8 @@ '@{APP_VERSION}', ]: t = 'info' - n = 'apparmor_profile_%s (%s)' % (v, f) + n = self._get_check_name( + 'apparmor_profile', extra='%s (%s)' % (v, f)) s = "OK" if v not in p: self._add_result('warn', n, @@ -872,7 +878,7 @@ second_m = "package.yaml" for exe_t in ['binaries', 'services']: t = 'info' - n = 'yaml_%s' % exe_t + n = self._get_check_name('yaml_%s' % exe_t) s = 'OK' if exe_t in first and exe_t not in second: t = 'error' @@ -888,7 +894,7 @@ continue t = 'info' - n = 'yaml_%s_entries' % exe_t + n = self._get_check_name('yaml_%s_entries' % exe_t) s = 'OK' if len(first[exe_t]) < len(second[exe_t]): t = 'error' @@ -897,7 +903,8 @@ for fapp in first[exe_t]: t = 'info' - n = 'yaml_%s_%s' % (exe_t, fapp['name']) + n = self._get_check_name( + 'yaml_%s' % exe_t, app=fapp['name']) s = 'OK' sapp = None for tmp in second[exe_t]: @@ -931,7 +938,8 @@ for key in ['security-template', 'caps']: t = 'info' - n = 'yaml_%s_%s' % (exe_t, second_m) + n = self._get_check_name( + 'yaml_%s' % exe_t, extra=second_m) s = 'OK' if key not in fapp: @@ -1016,7 +1024,7 @@ key = 'binaries' else: t = 'error' - n = 'yaml_and_click_%s' % app + n = self._get_check_name('yaml_and_click', app=app) s = "'%s' in click manifest missing from package.yaml" % app self._add_result(t, n, s) continue @@ -1042,7 +1050,7 @@ key = 'binaries' else: t = 'error' - n = 'yaml_and_click_%s' % app + n = self._get_check_name('yaml_and_click', app=app) s = "'%s' in click manifest missing from package.yaml" % app self._add_result(t, n, s) continue @@ -1094,7 +1102,7 @@ continue if error: t = 'info' - n = 'yaml_and_click' + n = self._get_check_name('yaml_and_click') s = "SKIPPED (yaml errors)" self._add_result(t, n, s) return @@ -1113,7 +1121,7 @@ for item in self.pkg_yaml[exe_t]: if 'name' not in item: t = 'error' - n = 'yaml_override_click_name' + n = self._get_check_name('yaml_override_click_name') s = "package.yaml malformed. Could not find 'name' " + \ "for entry in '%s'" % item self._add_result(t, n, s) @@ -1121,7 +1129,7 @@ app = item['name'] t = 'info' - n = 'yaml_override_click_%s' % app + n = self._get_check_name('yaml_override_click', app=app) s = "OK" if 'security-override' not in item: s = "OK (skipping unspecified override)" @@ -1150,7 +1158,7 @@ for item in self.pkg_yaml[exe_t]: if 'name' not in item: t = 'error' - n = 'yaml_override_name' + n = self._get_check_name('yaml_override_name') s = "package.yaml malformed. Could not find 'name' " + \ "for entry in '%s'" % item self._add_result(t, n, s) @@ -1158,7 +1166,7 @@ app = item['name'] t = 'info' - n = 'yaml_override_format_%s' % app + n = self._get_check_name('yaml_override_format', app=app) s = "OK" if 'security-override' not in item: s = "OK (skipping unspecified override)" @@ -1184,7 +1192,7 @@ for item in self.pkg_yaml[exe_t]: if 'name' not in item: t = 'error' - n = 'yaml_policy_name' + n = self._get_check_name('yaml_policy_name') s = "package.yaml malformed. Could not find 'name' " + \ "for entry in '%s'" % item self._add_result(t, n, s) @@ -1192,7 +1200,7 @@ app = item['name'] t = 'info' - n = 'yaml_policy_format_%s' % app + n = self._get_check_name('yaml_policy_format', app=app) s = "OK" if 'security-policy' not in item: s = "OK (skipping unspecified policy)" @@ -1208,7 +1216,7 @@ if 'security-policy' in item: t = 'error' - n = 'yaml_policy_present' + n = self._get_check_name('yaml_policy_present') s = "(MANUAL REVIEW) 'security-policy' not allowed" l = 'https://developer.ubuntu.com/en/snappy/guides/security-policy/' m = True @@ -1225,7 +1233,7 @@ for item in self.pkg_yaml[exe_t]: if 'name' not in item: t = 'error' - n = 'yaml_combinations_name' + n = self._get_check_name('yaml_combinations_name') s = "package.yaml malformed. Could not find 'name' " + \ "for entry in '%s'" % item self._add_result(t, n, s) @@ -1234,7 +1242,7 @@ app = item['name'] t = 'info' - n = 'yaml_combinations_%s' % app + n = self._get_check_name('yaml_combinations', app=app) s = "OK" if "security-policy" in item: for i in ['security-override', 'security-template', @@ -1267,7 +1275,7 @@ if 'name' not in item: t = 'error' - n = 'yaml_security-template_name' + n = self._get_check_name('yaml_security-template_name') s = "package.yaml malformed. Could not find 'name' " + \ "for entry in '%s'" % item self._add_result(t, n, s) @@ -1277,7 +1285,7 @@ app = os.path.basename(item['name']) t = 'info' - n = 'yaml_security-template_%s' % app + n = self._get_check_name('yaml_security-template', app=app) s = "OK" if not isinstance(tmpl, str): t = 'error' @@ -1288,7 +1296,7 @@ self._add_result(t, n, s) t = 'info' - n = 'yaml_security-template_in_manifest_%s' % app + n = self._get_check_name('yaml_security-template_in_manifest', app=app) s = "OK" if app not in self.manifest['hooks']: t = 'error' @@ -1320,7 +1328,7 @@ if 'name' not in item: t = 'error' - n = 'yaml_caps_name' + n = self._get_check_name('yaml_caps_name') s = "package.yaml malformed. Could not find 'name' " + \ "for entry in '%s'" % item self._add_result(t, n, s) @@ -1330,7 +1338,7 @@ app = os.path.basename(item['name']) t = 'info' - n = 'yaml_caps_%s' % app + n = self._get_check_name('yaml_caps', app=app) s = "OK" if not isinstance(tmpl, list): t = 'error' @@ -1341,7 +1349,7 @@ self._add_result(t, n, s) t = 'info' - n = 'yaml_caps_in_manifest_%s' % app + n = self._get_check_name('yaml_caps_in_manifest', app=app) s = "OK" if app not in self.manifest['hooks']: t = 'error' @@ -1362,7 +1370,7 @@ for app in sorted(self.security_apps): (f, m) = self._get_security_manifest(app) t = 'info' - n = 'template_account_provider(%s)' % f + n = self._get_check_name('template_account_provider', extra=f) s = "OK" if 'account-provider' not in self.manifest['hooks'][app]: continue @@ -1376,7 +1384,7 @@ for app in sorted(self.security_apps): (f, m) = self._get_security_manifest(app) t = 'info' - n = 'template_account_qml_plugin(%s)' % f + n = self._get_check_name('template_account_qml_plugin', extra=f) s = "OK" if 'account-qml-plugin' not in self.manifest['hooks'][app]: continue diff -Nru click-reviewers-tools-0.33/clickreviews/cr_skeleton.py click-reviewers-tools-0.34/clickreviews/cr_skeleton.py --- click-reviewers-tools-0.33/clickreviews/cr_skeleton.py 2015-07-22 16:46:42.000000000 +0000 +++ click-reviewers-tools-0.34/clickreviews/cr_skeleton.py 2015-09-16 14:16:24.000000000 +0000 @@ -40,7 +40,7 @@ def check_foo(self): '''Check foo''' t = 'info' - n = 'foo' + n = self._get_check_name('foo') s = "OK" if False: t = 'error' @@ -50,7 +50,7 @@ def check_bar(self): '''Check bar''' t = 'info' - n = 'bar' + n = self._get_check_name('bar') s = "OK" if True: t = 'error' @@ -59,7 +59,8 @@ def check_baz(self): '''Check baz''' - self._add_result('warn', 'baz', 'TODO', link="http://example.com") + n = self._get_check_name('baz') + self._add_result('warn', n, 'TODO', link="http://example.com") # Spawn a shell to pause the script (run 'exit' to continue) # import subprocess diff -Nru click-reviewers-tools-0.33/clickreviews/cr_systemd.py click-reviewers-tools-0.34/clickreviews/cr_systemd.py --- click-reviewers-tools-0.33/clickreviews/cr_systemd.py 2015-07-22 16:46:42.000000000 +0000 +++ click-reviewers-tools-0.34/clickreviews/cr_systemd.py 2015-09-16 14:16:24.000000000 +0000 @@ -68,7 +68,8 @@ for r in self.required_keys: found = False t = 'info' - n = '%s_required_key_%s_%s' % (test_str, r, app) + n = self._get_check_name( + '%s_required_key' % test_str, extra=r, app=app) s = "OK" if r in my_dict[app]: if not isinstance(my_dict[app][r], str): @@ -98,7 +99,8 @@ continue # checked in cr_security.py found = False t = 'info' - n = '%s_optional_key_%s_%s' % (test_str, o, app) + n = self._get_check_name( + '%s_optional_key' % test_str, extra=o, app=app) s = "OK" if o in my_dict[app]: if o == 'stop-timeout': @@ -140,7 +142,7 @@ for app in sorted(my_dict): unknown = [] t = 'info' - n = '%s_unknown_key_%s' % (test_str, app) + n = self._get_check_name('%s_unknown_key' % test_str, app=app) s = "OK" for f in my_dict[app].keys(): @@ -167,7 +169,7 @@ '''Check snappy systemd description''' for app in sorted(my_dict): t = 'info' - n = '%s_description_present_%s' % (test_str, app) + n = self._get_check_name('%s_description_present' % test_str, app=app) s = 'OK' if 'description' not in my_dict[app]: s = 'required description field not specified' @@ -176,7 +178,7 @@ self._add_result(t, n, s) t = 'info' - n = '%s_description_empty_%s' % (test_str, app) + n = self._get_check_name('%s_description_empty' % test_str, app=app) s = 'OK' if len(my_dict[app]['description']) == 0: t = 'error' @@ -197,7 +199,7 @@ continue t = 'info' - n = '%s_%s_empty_%s' % (test_str, d, app) + n = self._get_check_name('%s_empty' % test_str, extra=d, app=app) s = 'OK' if len(my_dict[app][d]) == 0: t = 'error' @@ -207,7 +209,7 @@ self._add_result(t, n, s) t = 'info' - n = '%s_%s_absolute_path_%s' % (test_str, d, app) + n = self._get_check_name('%s_absolute_path' % test_str, extra=d, app=app) s = 'OK' if my_dict[app][d].startswith('/'): t = 'error' @@ -238,7 +240,7 @@ def _verify_service_stop_timeout(self, my_dict, test_str): for app in sorted(my_dict): t = 'info' - n = '%s_stop_timeout_%s' % (test_str, app) + n = self._get_check_name('%s_stop_timeout' % test_str, app=app) s = "OK" if 'stop-timeout' not in my_dict[app]: @@ -284,7 +286,7 @@ continue t = 'info' - n = '%s_bus-name_empty_%s' % (test_str, app) + n = self._get_check_name('%s_bus-name_empty' % test_str, app=app) s = 'OK' if len(my_dict[app]['bus-name']) == 0: t = 'error' @@ -294,7 +296,7 @@ self._add_result(t, n, s) t = 'info' - n = '%s_bus-name_format_%s' % (test_str, app) + n = self._get_check_name('%s_bus-name_format' % test_str, app=app) l = None s = 'OK' if not re.search(r'^[A-Za-z0-9][A-Za-z0-9_-]*(\.[A-Za-z0-9][A-Za-z0-9_-]*)+$', @@ -306,7 +308,7 @@ self._add_result(t, n, s, l) t = 'info' - n = '%s_bus-name_matches_name_%s' % (test_str, app) + n = self._get_check_name('%s_bus-name_matches_name' % test_str, app=app) s = 'OK' suggested = [pkgname, "%s.%s" % (pkgname, app) @@ -347,7 +349,7 @@ continue t = 'info' - n = '%s_ports_empty_%s' % (test_str, app) + n = self._get_check_name('%s_ports_empty' % test_str, app=app) s = 'OK' if len(my_dict[app]['ports'].keys()) == 0: t = 'error' @@ -357,7 +359,7 @@ self._add_result(t, n, s) t = 'info' - n = '%s_ports_bad_key_%s' % (test_str, app) + n = self._get_check_name('%s_ports_bad_key' % test_str, app=app) s = 'OK' badkeys = [] for i in my_dict[app]['ports'].keys(): @@ -375,7 +377,7 @@ if len(my_dict[app]['ports'][key].keys()) < 1: t = 'error' - n = '%s_ports_%s_%s' % (test_str, key, app) + n = self._get_check_name('%s_ports' % test_str, extra=key, app=app) s = 'Could not find any %s ports' % key self._add_result(t, n, s) continue @@ -384,7 +386,7 @@ entry = my_dict[app]['ports'][key][tagname] if len(entry.keys()) < 1: t = 'error' - n = '%s_ports_%s_%s' % (test_str, key, app) + n = self._get_check_name('%s_ports' % test_str, extra=key, app=app) s = 'Could not find any subkeys for %s' % tagname self._add_result(t, n, s) continue @@ -398,7 +400,7 @@ 'Negotiable' not in entry and 'Port' not in entry): t = 'error' - n = '%s_ports_%s_invalid_%s' % (test_str, key, app) + n = self._get_check_name('%s_ports_invalid' % test_str, extra=key, app=app) s = "Must specify specify at least 'port' or " + \ "'negotiable'" self._add_result(t, n, s) @@ -409,7 +411,7 @@ if test_str == 'hook': subkey = 'Port' t = 'info' - n = '%s_ports_%s_%s_format' % (test_str, tagname, subkey) + n = self._get_check_name('%s_ports_%s_format' % (test_str, tagname), extra=subkey) s = 'OK' if subkey not in entry: s = 'OK (skipped, not found)' @@ -429,7 +431,7 @@ if test_str == 'hook': subkey = 'Negotiable' t = 'info' - n = '%s_ports_%s_%s_format' % (test_str, tagname, subkey) + n = self._get_check_name('%s_ports_%s_format' % (test_str, tagname), extra=subkey) s = 'OK' if subkey not in entry: s = 'OK (skipped, not found)' diff -Nru click-reviewers-tools-0.33/clickreviews/cr_tests.py click-reviewers-tools-0.34/clickreviews/cr_tests.py --- click-reviewers-tools-0.33/clickreviews/cr_tests.py 2015-07-22 16:46:42.000000000 +0000 +++ click-reviewers-tools-0.34/clickreviews/cr_tests.py 2015-09-16 14:16:24.000000000 +0000 @@ -40,6 +40,7 @@ TEST_URLS = dict() TEST_SCOPES = dict() TEST_CONTENT_HUB = dict() +TEST_ACCOUNTS_MANIFEST = dict() TEST_ACCOUNTS_APPLICATION = dict() TEST_ACCOUNTS_PROVIDER = dict() TEST_ACCOUNTS_QML_PLUGIN = dict() @@ -190,7 +191,10 @@ '''Pretend we read the accounts file''' f = app val = None - if account_type == "account-application": + if account_type == "accounts": + f += ".accounts" + val = TEST_ACCOUNTS_MANIFEST[app] + elif account_type == "account-application": f += ".application" val = TEST_ACCOUNTS_APPLICATION[app] elif account_type == "account-provider": @@ -449,6 +453,7 @@ self.test_url_dispatcher = dict() self.test_scopes = dict() self.test_content_hub = dict() + self.test_accounts_manifest = dict() self.test_accounts_application = dict() self.test_accounts_provider = dict() self.test_accounts_qml_plugin = dict() @@ -488,6 +493,7 @@ self.set_test_content_hub(app, None, None) # Reset to no accounts entries in manifest + self.set_test_account(app, "accounts", None) self.set_test_account(app, "account-application", None) self.set_test_account(app, "account-provider", None) self.set_test_account(app, "account-qml-plugin", None) @@ -515,6 +521,7 @@ self._update_test_url_dispatcher() self._update_test_scopes() self._update_test_content_hub() + self._update_test_accounts_manifest() self._update_test_accounts_application() self._update_test_accounts_provider() self._update_test_accounts_qml_plugin() @@ -618,6 +625,15 @@ "%s.content.json" % app self._update_test_manifest() + def _update_test_accounts_manifest(self): + global TEST_ACCOUNTS_MANIFEST + TEST_ACCOUNTS_MANIFEST = dict() + for app in self.test_accounts_manifest.keys(): + TEST_ACCOUNTS_MANIFEST[app] = self.test_accounts_manifest[app] + self.test_manifest["hooks"][app]["accounts"] = \ + "%s.accounts" % app + self._update_test_manifest() + def _update_test_accounts_application(self): global TEST_ACCOUNTS_APPLICATION TEST_ACCOUNTS_APPLICATION = dict() @@ -923,7 +939,9 @@ def set_test_account(self, app, account_type, value): '''Set accounts XML. If value is None, remove from manifest''' - if account_type == "account-application": + if account_type == "accounts": + d = self.test_accounts_manifest + elif account_type == "account-application": d = self.test_accounts_application elif account_type == "account-provider": d = self.test_accounts_provider @@ -940,7 +958,9 @@ else: d[app] = value - if account_type == "account-application": + if account_type == "accounts": + self._update_test_accounts_manifest() + elif account_type == "account-application": self._update_test_accounts_application() elif account_type == "account-provider": self._update_test_accounts_provider() @@ -1115,6 +1135,8 @@ TEST_SCOPES = dict() global TEST_CONTENT_HUB TEST_CONTENT_HUB = dict() + global TEST_ACCOUNTS_MANIFEST + TEST_ACCOUNTS_MANIFEST = dict() global TEST_ACCOUNTS_APPLICATION TEST_ACCOUNTS_APPLICATION = dict() global TEST_ACCOUNTS_PROVIDER @@ -1122,7 +1144,7 @@ global TEST_ACCOUNTS_QML_PLUGIN TEST_ACCOUNTS_QML_PLUGIN = dict() global TEST_ACCOUNTS_SERVICE - TEST_ACCOUNTS_APPLICATION = dict() + TEST_ACCOUNTS_SERVICE = dict() global TEST_PUSH_HELPER TEST_PUSH_HELPER = dict() global TEST_BIN_PATH diff -Nru click-reviewers-tools-0.33/clickreviews/cr_url_dispatcher.py click-reviewers-tools-0.34/clickreviews/cr_url_dispatcher.py --- click-reviewers-tools-0.33/clickreviews/cr_url_dispatcher.py 2015-07-22 16:46:42.000000000 +0000 +++ click-reviewers-tools-0.34/clickreviews/cr_url_dispatcher.py 2015-09-16 14:16:24.000000000 +0000 @@ -82,7 +82,7 @@ for r in self.required_keys: found = False t = 'info' - n = 'required_entry_%s_%s' % (app, r) + n = self._get_check_name('required_entry', app=app, extra=r) s = "OK" for entry in self.url_dispatcher[app]: if not isinstance(entry, dict): @@ -110,7 +110,7 @@ for o in self.optional_keys: found = False t = 'info' - n = 'optional_entry_%s_%s' % (app, o) + n = self._get_check_name('optional_entry', app=app, extra=o) s = "OK" for entry in self.url_dispatcher[app]: if not isinstance(entry, dict): @@ -137,7 +137,7 @@ unknown = [] for entry in self.url_dispatcher[app]: t = 'info' - n = 'unknown_entry_%s' % app + n = self._get_check_name('unknown_entry', app=app) s = "OK" if not isinstance(entry, dict): t = 'error' diff -Nru click-reviewers-tools-0.33/clickreviews/modules.py click-reviewers-tools-0.34/clickreviews/modules.py --- click-reviewers-tools-0.33/clickreviews/modules.py 2015-07-22 16:46:42.000000000 +0000 +++ click-reviewers-tools-0.34/clickreviews/modules.py 2015-09-16 14:16:24.000000000 +0000 @@ -48,9 +48,11 @@ module_name)) classes = inspect.getmembers(module, inspect.isclass) - find_cr_class = lambda a: a[0].startswith('Click') and \ - not a[0].endswith('Exception') and \ - a[1].__module__ == module_name + + def find_cr_class(a): + return a[0].startswith('Click') and \ + not a[0].endswith('Exception') and \ + a[1].__module__ == module_name cr_class = list(filter(find_cr_class, classes)) if not cr_class: return None diff -Nru click-reviewers-tools-0.33/clickreviews/tests/test_aaa_example_cr_skeleton.py click-reviewers-tools-0.34/clickreviews/tests/test_aaa_example_cr_skeleton.py --- click-reviewers-tools-0.33/clickreviews/tests/test_aaa_example_cr_skeleton.py 2015-07-22 16:46:42.000000000 +0000 +++ click-reviewers-tools-0.34/clickreviews/tests/test_aaa_example_cr_skeleton.py 2015-09-16 14:16:24.000000000 +0000 @@ -57,8 +57,9 @@ expected = dict() expected['info'] = dict() expected['warn'] = dict() - expected['warn']['skeleton_baz'] = {"text": "TODO", - "link": "http://example.com"} + name = c._get_check_name('baz') + expected['warn'][name] = {"text": "TODO", + "link": "http://example.com"} expected['error'] = dict() self.check_results(r, expected=expected) diff -Nru click-reviewers-tools-0.33/clickreviews/tests/test_cr_common.py click-reviewers-tools-0.34/clickreviews/tests/test_cr_common.py --- click-reviewers-tools-0.33/clickreviews/tests/test_cr_common.py 2015-07-22 16:46:42.000000000 +0000 +++ click-reviewers-tools-0.34/clickreviews/tests/test_cr_common.py 2015-09-16 14:16:24.000000000 +0000 @@ -15,7 +15,7 @@ self.review._add_result('info', 'some-check', 'OK') self.assertEqual(self.review.click_report, { 'info': { - 'review_type_some-check': { + 'some-check': { 'text': 'OK', 'manual_review': False, } @@ -29,7 +29,7 @@ manual_review=True) self.assertEqual(self.review.click_report, { 'info': { - 'review_type_some-check': { + 'some-check': { 'text': 'OK', 'manual_review': True, } @@ -77,3 +77,19 @@ self.assertEqual(1, len(d.keys())) self.assertTrue('disallowed' in d.keys()) self.assertTrue('urls' in d['disallowed'][self.default_appname]) + + def test_get_check_name(self): + name = self.review._get_check_name('prefix') + self.assertEqual(name, 'review_type:prefix') + + def test_get_check_name_with_app(self): + name = self.review._get_check_name('prefix', app='app') + self.assertEqual(name, 'review_type:prefix:app') + + def test_get_check_name_with_extra(self): + name = self.review._get_check_name('prefix', extra='extra') + self.assertEqual(name, 'review_type:prefix:extra') + + def test_get_check_name_with_app_and_extra(self): + name = self.review._get_check_name('prefix', app='app', extra='extra') + self.assertEqual(name, 'review_type:prefix:app:extra') diff -Nru click-reviewers-tools-0.33/clickreviews/tests/test_cr_desktop.py click-reviewers-tools-0.34/clickreviews/tests/test_cr_desktop.py --- click-reviewers-tools-0.33/clickreviews/tests/test_cr_desktop.py 2015-07-22 16:46:42.000000000 +0000 +++ click-reviewers-tools-0.34/clickreviews/tests/test_cr_desktop.py 2015-09-16 14:16:24.000000000 +0000 @@ -35,7 +35,8 @@ expected['info'] = dict() expected['warn'] = dict() expected['error'] = dict() - expected['info']['desktop_files_usable'] = {"text": "OK"} + name = c._get_check_name('files_usable') + expected['info'][name] = {"text": "OK"} self.check_results(r, expected=expected) def test_check_desktop_file_valid(self): @@ -47,8 +48,8 @@ expected['info'] = dict() expected['warn'] = dict() expected['error'] = dict() - expected['info']['desktop_validates (%s)' % self.default_appname] = \ - {"text": "OK"} + name = c._get_check_name('validates', app=self.default_appname) + expected['info'][name] = {"text": "OK"} self.check_results(r, expected=expected) def test_check_desktop_file_valid_missing_exec(self): diff -Nru click-reviewers-tools-0.33/clickreviews/tests/test_cr_lint.py click-reviewers-tools-0.34/clickreviews/tests/test_cr_lint.py --- click-reviewers-tools-0.33/clickreviews/tests/test_cr_lint.py 2015-07-22 16:46:42.000000000 +0000 +++ click-reviewers-tools-0.34/clickreviews/tests/test_cr_lint.py 2015-09-16 14:16:24.000000000 +0000 @@ -201,8 +201,9 @@ expected['info'] = dict() expected['warn'] = dict() expected['error'] = dict() - expected['info']["lint_control_architecture_match"] = \ - {"text": "OK: architecture not specified in manifest"} + name = c._get_check_name('control_architecture_match') + expected['info'][name] = { + "text": "OK: architecture not specified in manifest"} self.check_results(r, expected=expected) def test_check_architecture_specified_needed(self): @@ -487,7 +488,8 @@ expected_counts = {'info': None, 'warn': 0, 'error': 1} self.check_results(r, expected_counts) # Lets check that the right error is triggering - m = r['error']['lint_control_click_version_up_to_date']['text'] + name = c._get_check_name('control_click_version_up_to_date') + m = r['error'][name]['text'] self.assertIn('Click-Version is too old', m) def test_check_maintainer(self): @@ -769,7 +771,7 @@ c.manifest['hooks']["another-app"] = tmp c.check_hooks() r = c.click_report - expected_counts = {'info': None, 'warn': 0, 'error': 1} + expected_counts = {'info': 9, 'warn': 0, 'error': 0} self.check_results(r, expected_counts) def test_check_hooks_multiple_apps(self): @@ -810,9 +812,10 @@ expected['info'] = dict() expected['warn'] = dict() expected['error'] = dict() - expected['info']['lint_sdk_security_extension_test-app'] = \ - {"text": "test-app.json does not end with .apparmor (ok if not " - "using sdk)"} + name = c._get_check_name( + 'sdk_security_extension', app='test-app') + expected['info'][name] = { + "text": "test-app.json does not end with .apparmor (ok if not using sdk)"} self.check_results(r, expected=expected) def test_check_hooks_bad_appname(self): @@ -908,7 +911,8 @@ r = c.click_report expected_counts = {'info': None, 'warn': 0, 'error': 1} self.check_results(r, expected_counts) - self.check_manual_review(r, 'lint_hooks_redflag_test-app') + name = c._get_check_name('hooks_redflag', app='test-app') + self.check_manual_review(r, name) def test_check_hooks_redflagged_apparmor_profile(self): '''Test check_hooks_redflagged() - apparmor-profile''' @@ -921,7 +925,8 @@ r = c.click_report expected_counts = {'info': None, 'warn': 0, 'error': 1} self.check_results(r, expected_counts) - self.check_manual_review(r, 'lint_hooks_redflag_test-app') + name = c._get_check_name('hooks_redflag', app='test-app') + self.check_manual_review(r, name) def test_pkgname_toplevel(self): '''Test check_pkgname - toplevel''' @@ -1396,7 +1401,8 @@ expected_counts = {'info': 0, 'warn': 0, 'error': 1} self.check_results(r, expected_counts) # Lets check that the right warning is triggering - m = r['error']['lint_snappy_unknown']['text'] + name = c._get_check_name('snappy_unknown') + m = r['error'][name]['text'] self.assertIn("unknown entries in package.yaml: 'maintainer' " "(maintainer obsoleted)", m) @@ -1468,9 +1474,11 @@ expected_counts = {'info': 0, 'warn': 0, 'error': 2} self.check_results(r, expected_counts) - m = r['error']['lint_snappy_foo_in_services']['text'] + name = c._get_check_name('snappy_in_services', extra='foo') + m = r['error'][name]['text'] self.assertIn("'foo' in both 'services' and 'binaries'", m) - m = r['error']['lint_snappy_foo_in_binaries']['text'] + name = c._get_check_name('snappy_in_binaries', extra='foo') + m = r['error'][name]['text'] self.assertIn("'foo' in both 'services' and 'binaries'", m) def test_check_snappy_services_and_binaries4(self): @@ -1485,9 +1493,11 @@ expected_counts = {'info': 0, 'warn': 0, 'error': 2} self.check_results(r, expected_counts) - m = r['error']['lint_snappy_foo_in_services']['text'] + name = c._get_check_name('snappy_in_services', extra='foo') + m = r['error'][name]['text'] self.assertIn("'foo' in both 'services' and 'binaries'", m) - m = r['error']['lint_snappy_foo_in_binaries']['text'] + name = c._get_check_name('snappy_in_binaries', extra='foo') + m = r['error'][name]['text'] self.assertIn("'foo' in both 'services' and 'binaries'", m) def test_check_snappy_services_and_binaries5(self): @@ -1503,9 +1513,11 @@ expected_counts = {'info': 0, 'warn': 0, 'error': 2} self.check_results(r, expected_counts) - m = r['error']['lint_snappy_foo_in_services']['text'] + name = c._get_check_name('snappy_in_services', extra='foo') + m = r['error'][name]['text'] self.assertIn("'foo' in both 'services' and 'binaries'", m) - m = r['error']['lint_snappy_foo_in_binaries']['text'] + name = c._get_check_name('snappy_in_binaries', extra='foo') + m = r['error'][name]['text'] self.assertIn("'foo' in both 'services' and 'binaries'", m) def test_check_snappy_hashes_click(self): @@ -1538,7 +1550,8 @@ r = c.click_report expected_counts = {'info': 0, 'warn': 0, 'error': 1} self.check_results(r, expected_counts) - m = r['error']['lint_hashes_archive-sha512_valid']['text'] + name = c._get_check_name('hashes_archive-sha512_valid') + m = r['error'][name]['text'] self.assertIn("hash mismatch: 'deadbeef' != '%s'" % self.sha512, m) def test_check_snappy_hashes_archive_files_missing(self): @@ -1552,7 +1565,8 @@ r = c.click_report expected_counts = {'info': None, 'warn': 0, 'error': 1} self.check_results(r, expected_counts) - m = r['error']['lint_hashes_files_present']['text'] + name = c._get_check_name('hashes_files_present') + m = r['error'][name]['text'] self.assertIn("'files' not found in hashes.yaml", m) def test_check_snappy_hashes_archive_files_ok(self): @@ -1624,7 +1638,8 @@ r = c.click_report expected_counts = {'info': None, 'warn': 0, 'error': 1} self.check_results(r, expected_counts) - m = r['error']['lint_file_mode']['text'] + name = c._get_check_name('file_mode') + m = r['error'][name]['text'] self.assertIn("found errors in hashes.yaml: unusual mode '%s' for entry 'bin/foo'" % "".join(orig_mode), m) def test_check_snappy_hashes_archive_files_mode_world_write(self): @@ -1645,7 +1660,8 @@ r = c.click_report expected_counts = {'info': None, 'warn': 0, 'error': 1} self.check_results(r, expected_counts) - m = r['error']['lint_file_mode']['text'] + name = c._get_check_name('file_mode') + m = r['error'][name]['text'] self.assertIn("found errors in hashes.yaml: 'bin' is world-writable, mode 'frw-rw-rw-' for 'bin/foo' is world-writable", m) def test_check_snappy_hashes_archive_files_mode_mismatch(self): @@ -1667,7 +1683,8 @@ r = c.click_report expected_counts = {'info': None, 'warn': 0, 'error': 1} self.check_results(r, expected_counts) - m = r['error']['lint_file_mode']['text'] + name = c._get_check_name('file_mode') + m = r['error'][name]['text'] self.assertIn("found errors in hashes.yaml: mode '---------' != '%s' for 'bin/foo'" % orig_mode, m) def test_check_snappy_hashes_archive_files_mode_bad_symlink(self): @@ -1681,7 +1698,8 @@ r = c.click_report expected_counts = {'info': None, 'warn': 0, 'error': 1} self.check_results(r, expected_counts) - m = r['error']['lint_file_mode']['text'] + name = c._get_check_name('file_mode') + m = r['error'][name]['text'] self.assertIn("found errors in hashes.yaml: unusual mode 'lrwxrwxr-x' for entry 'badlink'", m) def test_check_snappy_hashes_archive_files_mode_devices(self): @@ -1696,7 +1714,8 @@ r = c.click_report expected_counts = {'info': None, 'warn': 0, 'error': 1} self.check_results(r, expected_counts) - m = r['error']['lint_file_mode']['text'] + name = c._get_check_name('file_mode') + m = r['error'][name]['text'] self.assertIn("found errors in hashes.yaml: illegal file mode 'b': 'brw-rw-r--' for 'badblock', illegal file mode 'c': 'crw-rw-r--' for 'badchar'", m) def test_check_snappy_hashes_archive_files_missing_size(self): @@ -1734,7 +1753,8 @@ r = c.click_report expected_counts = {'info': None, 'warn': 0, 'error': 1} self.check_results(r, expected_counts) - m = r['error']['lint_file_mode']['text'] + name = c._get_check_name('file_mode') + m = r['error'][name]['text'] self.assertIn("found errors in hashes.yaml: size " + "%d != %d for 'bin/foo'" % (new_size, orig_size), m) @@ -1767,7 +1787,8 @@ r = c.click_report expected_counts = {'info': None, 'warn': 0, 'error': 1} self.check_results(r, expected_counts) - m = r['error']['lint_hashes_extra_files']['text'] + name = c._get_check_name('hashes_extra_files') + m = r['error'][name]['text'] self.assertIn("found extra files not listed in hashes.yaml: extrafile", m) diff -Nru click-reviewers-tools-0.33/clickreviews/tests/test_cr_online_accounts.py click-reviewers-tools-0.34/clickreviews/tests/test_cr_online_accounts.py --- click-reviewers-tools-0.33/clickreviews/tests/test_cr_online_accounts.py 2015-07-22 16:46:42.000000000 +0000 +++ click-reviewers-tools-0.34/clickreviews/tests/test_cr_online_accounts.py 2015-09-16 14:16:24.000000000 +0000 @@ -16,6 +16,7 @@ from clickreviews.cr_online_accounts import ClickReviewAccounts import clickreviews.cr_tests as cr_tests +import json import lxml.etree as etree @@ -84,6 +85,185 @@ # More can go here, see /usr/share/accounts/providers/* return xml + def test_check_hooks_versions_new(self): + '''Test check_hooks_versions() - new hook''' + self.set_test_manifest("framework", "ubuntu-sdk-15.10") + self.set_test_account(self.default_appname, "accounts", dict()) + c = ClickReviewAccounts(self.test_name) + c.check_hooks_versions() + r = c.click_report + expected_counts = {'info': 0, 'warn': 0, 'error': 0} + self.check_results(r, expected_counts) + + def test_check_hooks_versions_deprecated_service(self): + '''Test check_hooks_versions() - deprecated -service hook''' + self.set_test_manifest("framework", "ubuntu-sdk-15.10") + self.set_test_account(self.default_appname, "account-service", dict()) + c = ClickReviewAccounts(self.test_name) + c.check_hooks_versions() + r = c.click_report + expected_counts = {'info': 0, 'warn': 1, 'error': 0} + self.check_results(r, expected_counts) + + def test_check_hooks_versions_disallowed_service(self): + '''Test check_hooks_versions() - deprecated -service hook''' + self.set_test_manifest("framework", "ubuntu-sdk-16.04") + self.set_test_account(self.default_appname, "account-service", dict()) + c = ClickReviewAccounts(self.test_name) + c.check_hooks_versions() + r = c.click_report + expected_counts = {'info': 0, 'warn': 0, 'error': 1} + self.check_results(r, expected_counts) + + def test_check_hooks_versions_deprecated_application(self): + '''Test check_hooks_versions() - deprecated -application hook''' + self.set_test_manifest("framework", "ubuntu-sdk-15.10") + self.set_test_account(self.default_appname, "account-application", dict()) + c = ClickReviewAccounts(self.test_name) + c.check_hooks_versions() + r = c.click_report + expected_counts = {'info': 0, 'warn': 1, 'error': 0} + self.check_results(r, expected_counts) + + def test_check_hooks_versions_old_framework(self): + '''Test check_hooks_versions() - deprecated -application hook''' + self.set_test_manifest("framework", "ubuntu-sdk-15.04") + self.set_test_account(self.default_appname, "account-application", dict()) + self.set_test_account(self.default_appname, "account-service", dict()) + c = ClickReviewAccounts(self.test_name) + c.check_hooks_versions() + r = c.click_report + expected_counts = {'info': 0, 'warn': 0, 'error': 0} + self.check_results(r, expected_counts) + + def test_check_manifest(self): + '''Test check_manifest()''' + data = json.loads('''{ + "translations": "my-app", + "services": [ + { + "name": "Example", + "provider": "myapp.com_example", + "description": "publish my photos in example.com", + "auth": { + "oauth2/web_server": { + "ClientId": "foo", + "ClientSecret": "bar", + "UseSSL": false, + "Scopes": ["one scope","and another"] + } + } + }, + { + "provider": "becool" + } + ], + "plugins": [ + { + "provider": "example", + "name": "Example site", + "icon": "example.png", + "qml": "qml_files" + } + ] + }''') + self.set_test_account(self.default_appname, "accounts", data) + c = ClickReviewAccounts(self.test_name) + c.check_manifest() + r = c.click_report + expected_counts = {'info': 3, 'warn': 0, 'error': 0} + self.check_results(r, expected_counts) + + def test_check_manifest_not_specified(self): + '''Test check_manifest() - not specified''' + c = ClickReviewAccounts(self.test_name) + c.check_manifest() + r = c.click_report + expected_counts = {'info': 0, 'warn': 0, 'error': 0} + self.check_results(r, expected_counts) + + def test_check_manifest_missing_services(self): + '''Test check_manifest() - missing services''' + data = json.loads('''{ "translations": "my-app" }''') + self.set_test_account(self.default_appname, "accounts", data) + c = ClickReviewAccounts(self.test_name) + c.check_manifest() + r = c.click_report + expected_counts = {'info': 0, 'warn': 0, 'error': 1} + self.check_results(r, expected_counts) + + def test_check_manifest_invalid_services(self): + '''Test check_manifest() - invalid services''' + data = json.loads('''{ "services": 12 }''') + self.set_test_account(self.default_appname, "accounts", data) + c = ClickReviewAccounts(self.test_name) + c.check_manifest() + r = c.click_report + expected_counts = {'info': 0, 'warn': 0, 'error': 1} + self.check_results(r, expected_counts) + + def test_check_manifest_empty_services(self): + '''Test check_manifest() - empty services''' + data = json.loads('''{ "services": [] }''') + self.set_test_account(self.default_appname, "accounts", data) + c = ClickReviewAccounts(self.test_name) + c.check_manifest() + r = c.click_report + expected_counts = {'info': 0, 'warn': 0, 'error': 1} + self.check_results(r, expected_counts) + + def test_check_manifest_empty_service(self): + '''Test check_manifest() - empty services''' + data = json.loads('''{ "services": [{}] }''') + self.set_test_account(self.default_appname, "accounts", data) + c = ClickReviewAccounts(self.test_name) + c.check_manifest() + r = c.click_report + expected_counts = {'info': 0, 'warn': 0, 'error': 1} + self.check_results(r, expected_counts) + + def test_check_manifest_no_provider(self): + '''Test check_manifest() - no provider''' + data = json.loads('''{ "services": [{ + "name": "Example", + "description": "Hello world" + }] }''') + self.set_test_account(self.default_appname, "accounts", data) + c = ClickReviewAccounts(self.test_name) + c.check_manifest() + r = c.click_report + expected_counts = {'info': 0, 'warn': 0, 'error': 1} + self.check_results(r, expected_counts) + + def test_check_manifest_invalid_provider(self): + '''Test check_manifest() - invalid provider''' + data = json.loads('''{ "services": [{ + "name": "Example", + "provider": "no/slashes.please", + "description": "Hello world" + }] }''') + self.set_test_account(self.default_appname, "accounts", data) + c = ClickReviewAccounts(self.test_name) + c.check_manifest() + r = c.click_report + expected_counts = {'info': 0, 'warn': 0, 'error': 1} + self.check_results(r, expected_counts) + + def test_check_manifest_unknown_key(self): + '''Test check_manifest() - unknown key''' + data = json.loads('''{ "services": [{ + "name": "Example", + "provider": "example", + "description": "Hello world", + "intruder": "Who, me?" + }] }''') + self.set_test_account(self.default_appname, "accounts", data) + c = ClickReviewAccounts(self.test_name) + c.check_manifest() + r = c.click_report + expected_counts = {'info': 0, 'warn': 0, 'error': 1} + self.check_results(r, expected_counts) + def test_check_application(self): '''Test check_application()''' xml = self._stub_application() diff -Nru click-reviewers-tools-0.33/clickreviews/tests/test_cr_security.py click-reviewers-tools-0.34/clickreviews/tests/test_cr_security.py --- click-reviewers-tools-0.33/clickreviews/tests/test_cr_security.py 2015-07-22 16:46:42.000000000 +0000 +++ click-reviewers-tools-0.34/clickreviews/tests/test_cr_security.py 2015-09-16 14:16:24.000000000 +0000 @@ -66,9 +66,10 @@ expected['info'] = dict() expected['warn'] = dict() expected['error'] = dict() - expected['info']["security_policy_version_is_highest (%s, %s)" % - (highest_version, self.default_security_json)] = \ - {"text": "OK"} + name = c._get_check_name( + 'policy_version_is_highest', + extra="(%s, %s)" % (highest_version, self.default_security_json)) + expected['info'][name] = {"text": "OK"} self.check_results(report, expected=expected) def test_check_policy_version_bad(self): @@ -86,13 +87,14 @@ expected['info'] = dict() expected['warn'] = dict() expected['error'] = dict() - expected['info']["security_policy_version_is_highest (%s, %s)" % ( - highest, - self.default_security_json)] = \ - {"text": "0.1 != %s" % highest} - expected['error']["security_policy_version_exists (%s)" % - self.default_security_json] = \ - {"text": "could not find policy for ubuntu/%s" % str(bad_version)} + name = c._get_check_name( + 'policy_version_is_highest', + extra="(%s, %s)" % (highest, self.default_security_json)) + expected['info'][name] = {"text": "0.1 != %s" % highest} + name = c._get_check_name( + 'policy_version_exists', + extra=self.default_security_json) + expected['error'][name] = {"text": "could not find policy for ubuntu/%s" % str(bad_version)} self.check_results(report, expected=expected) def test_check_policy_version_low(self): @@ -114,10 +116,10 @@ expected['info'] = dict() expected['warn'] = dict() expected['error'] = dict() - expected['info']["security_policy_version_is_highest (%s, %s)" % ( - highest, - self.default_security_json)] = \ - {"text": "%s != %s" % (version, highest)} + name = c._get_check_name( + 'policy_version_is_highest', + extra="(%s, %s)" % (highest, self.default_security_json)) + expected['info'][name] = {"text": "%s != %s" % (version, highest)} self.check_results(report, expected=expected) def test_check_policy_version_unspecified(self): @@ -131,9 +133,9 @@ expected['info'] = dict() expected['warn'] = dict() expected['error'] = dict() - expected['error']["security_policy_version_exists (%s)" % - self.default_security_json] = \ - {"text": "could not find policy_version in manifest"} + name = c._get_check_name('policy_version_exists', + extra=self.default_security_json) + expected['error'][name] = {"text": "could not find policy_version in manifest"} self.check_results(report, expected=expected) def test_check_policy_version_framework(self): @@ -186,9 +188,10 @@ expected['info'] = dict() expected['warn'] = dict() expected['error'] = dict() - expected['error']["security_policy_version_matches_framework (%s)" % - self.default_security_json] = \ - {"text": "1.0 != 1.1 (ubuntu-sdk-14.04)"} + name = c._get_check_name( + 'policy_version_matches_framework', + extra=self.default_security_json) + expected['error'][name] = {"text": "1.0 != 1.1 (ubuntu-sdk-14.04)"} self.check_results(report, expected=expected) def test_check_policy_version_framework_unmatch2(self): @@ -207,9 +210,10 @@ expected['info'] = dict() expected['warn'] = dict() expected['error'] = dict() - expected['error']["security_policy_version_matches_framework (%s)" % - self.default_security_json] = \ - {"text": "1.1 != 1.0 (ubuntu-sdk-13.10)"} + name = c._get_check_name( + 'policy_version_matches_framework', + extra=self.default_security_json) + expected['error'][name] = {"text": "1.1 != 1.0 (ubuntu-sdk-13.10)"} self.check_results(report, expected=expected) def test_check_policy_version_framework_unmatch3(self): @@ -228,9 +232,10 @@ expected['info'] = dict() expected['warn'] = dict() expected['error'] = dict() - expected['error']["security_policy_version_matches_framework (%s)" % - self.default_security_json] = \ - {"text": "Invalid framework 'nonexistent'"} + name = c._get_check_name( + 'policy_version_matches_framework', + extra=self.default_security_json) + expected['error'][name] = {"text": "Invalid framework 'nonexistent'"} self.check_results(report, expected=expected) def test_check_policy_version_framework_with_overrides(self): @@ -356,9 +361,10 @@ expected['info'] = dict() expected['warn'] = dict() expected['error'] = dict() - expected['error']["security_policy_vendor_matches_framework (%s)" % - self.default_security_json] = \ - {"text": "ubuntu-snappy != ubuntu (ubuntu-sdk-13.10)"} + name = c._get_check_name( + 'policy_vendor_matches_framework', + extra=self.default_security_json) + expected['error'][name] = {"text": "ubuntu-snappy != ubuntu (ubuntu-sdk-13.10)"} self.check_results(report, expected=expected) def test_check_policy_vendor_framework_unmatch2(self): @@ -377,9 +383,10 @@ expected['info'] = dict() expected['warn'] = dict() expected['error'] = dict() - expected['error']["security_policy_vendor_matches_framework (%s)" % - self.default_security_json] = \ - {"text": "Invalid framework 'nonexistent'"} + name = c._get_check_name( + 'policy_vendor_matches_framework', + extra=self.default_security_json) + expected['error'][name] = {"text": "Invalid framework 'nonexistent'"} self.check_results(report, expected=expected) def test_check_policy_vendor_framework_with_overrides(self): @@ -433,13 +440,15 @@ expected['info'] = dict() expected['warn'] = dict() expected['error'] = dict() - expected['info']["security_template_with_policy_version (%s)" % - self.default_security_json] = {"text": "OK"} - expected['info']["security_template_exists (%s)" % - self.default_security_json] = {"text": "OK"} - expected['warn']["security_template_valid (%s)" % - self.default_security_json] = \ - {"text": "No need to specify 'ubuntu-sdk' template"} + name = c._get_check_name('template_with_policy_version', + extra=self.default_security_json) + expected['info'][name] = {"text": "OK"} + name = c._get_check_name('template_exists', + extra=self.default_security_json) + expected['info'][name] = {"text": "OK"} + name = c._get_check_name('template_valid', + extra=self.default_security_json) + expected['warn'][name] = {"text": "No need to specify 'ubuntu-sdk' template"} self.check_results(report, expected=expected) def test_check_template_default(self): @@ -557,7 +566,8 @@ report = c.click_report expected_counts = {'info': 2, 'warn': 0, 'error': 1} self.check_results(report, expected_counts) - check_name = "security_template_valid (%s.apparmor)" % self.default_appname + check_name = c._get_check_name( + 'template_valid', app="%s.apparmor" % self.default_appname) self.check_manual_review(report, check_name) def test_check_policy_groups_webapps(self): @@ -878,8 +888,9 @@ report = c.click_report expected_counts = {'info': None, 'warn': 0, 'error': 1} self.check_results(report, expected_counts) - check_name = "security_policy_groups_safe_%s (video_files)" % ( - self.default_appname,) + check_name = c._get_check_name( + 'policy_groups_safe', app=self.default_appname, + extra='video_files') self.check_manual_review(report, check_name) def test_check_policy_groups_debug(self): @@ -1885,7 +1896,8 @@ report = c.click_report expected_counts = {'info': 1, 'warn': 0, 'error': 1} self.check_results(report, expected_counts) - m = report['error']['security_yaml_policy_present']['text'] + name = c._get_check_name('yaml_policy_present') + m = report['error'][name]['text'] self.assertIn("(MANUAL REVIEW) 'security-policy' not allowed", m) def test_check_security_yaml_policy_missing1(self): @@ -1897,9 +1909,12 @@ report = c.click_report expected_counts = {'info': None, 'warn': 0, 'error': 2} self.check_results(report, expected_counts) - m = report['error']['security_yaml_policy_present']['text'] + name = c._get_check_name('yaml_policy_present') + m = report['error'][name]['text'] self.assertIn("(MANUAL REVIEW) 'security-policy' not allowed", m) - m = report['error']['security_yaml_policy_format_test-app']['text'] + name = c._get_check_name( + 'yaml_policy_format', app='test-app') + m = report['error'][name]['text'] self.assertIn("'apparmor' not specified in 'security-policy' " + "for 'test-app'", m) @@ -1912,9 +1927,12 @@ report = c.click_report expected_counts = {'info': None, 'warn': 0, 'error': 2} self.check_results(report, expected_counts) - m = report['error']['security_yaml_policy_present']['text'] + name = c._get_check_name('yaml_policy_present') + m = report['error'][name]['text'] self.assertIn("(MANUAL REVIEW) 'security-policy' not allowed", m) - m = report['error']['security_yaml_policy_format_test-app']['text'] + name = c._get_check_name( + 'yaml_policy_format', app='test-app') + m = report['error'][name]['text'] self.assertIn("'seccomp' not specified in 'security-policy' " + "for 'test-app'", m) diff -Nru click-reviewers-tools-0.33/collect-check-names click-reviewers-tools-0.34/collect-check-names --- click-reviewers-tools-0.33/collect-check-names 1970-01-01 00:00:00.000000000 +0000 +++ click-reviewers-tools-0.34/collect-check-names 2015-09-16 14:16:24.000000000 +0000 @@ -0,0 +1,5 @@ +#!/bin/sh + +(./collect-check-names-from-tests 2>&1 | grep 'CHECK|' | cut -d '|' -f 2- \ + | egrep -v '(skeleton|some-check)' | sort \ + | awk -F '|' '(l && $1 != l1) {print l} {l1=$1; l=$0} END {print l}') > check-names.list diff -Nru click-reviewers-tools-0.33/collect-check-names-from-tests click-reviewers-tools-0.34/collect-check-names-from-tests --- click-reviewers-tools-0.33/collect-check-names-from-tests 1970-01-01 00:00:00.000000000 +0000 +++ click-reviewers-tools-0.34/collect-check-names-from-tests 2015-09-16 14:16:24.000000000 +0000 @@ -0,0 +1,28 @@ +#!/usr/bin/python3 +'''collect-check-names-from-tests: print list of check names discovered from tests''' +# +# Copyright (C) 2015 Canonical Ltd. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 3 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# NOTE: changes to this file may also need to be made to 'run-tests' + +import logging +import unittest + +test_directory = 'clickreviews/tests/' + +logging.basicConfig(level=logging.DEBUG) + +suite = unittest.TestLoader().discover(test_directory) +unittest.TextTestRunner(verbosity=0).run(suite) diff -Nru click-reviewers-tools-0.33/data/apparmor-easyprof-ubuntu.json click-reviewers-tools-0.34/data/apparmor-easyprof-ubuntu.json --- click-reviewers-tools-0.33/data/apparmor-easyprof-ubuntu.json 2015-07-22 16:46:42.000000000 +0000 +++ click-reviewers-tools-0.34/data/apparmor-easyprof-ubuntu.json 2015-09-16 14:16:24.000000000 +0000 @@ -175,6 +175,100 @@ "video_files_read" ] } + }, + "15.10": { + "templates": { + "common": [ + "default", + "ubuntu-account-plugin", + "ubuntu-push-helper", + "ubuntu-scope-network", + "ubuntu-sdk", + "ubuntu-webapp" + ], + "reserved": [ + "unconfined" + ] + }, + "policy_groups": { + "common": [ + "accounts", + "audio", + "camera", + "connectivity", + "content_exchange", + "content_exchange_source", + "keep-display-on", + "location", + "microphone", + "networking", + "push-notification-client", + "sensors", + "usermetrics", + "video", + "webview" + ], + "reserved": [ + "calendar", + "contacts", + "debug", + "history", + "music_files", + "music_files_read", + "picture_files", + "picture_files_read", + "video_files", + "video_files_read" + ] + } + } + }, + "ubuntu-personal": { + "15.10": { + "templates": { + "common": [ + "default", + "ubuntu-account-plugin", + "ubuntu-push-helper", + "ubuntu-scope-network", + "ubuntu-sdk", + "ubuntu-webapp" + ], + "reserved": [ + "unconfined" + ] + }, + "policy_groups": { + "common": [ + "accounts", + "audio", + "camera", + "connectivity", + "content_exchange", + "content_exchange_source", + "keep-display-on", + "location", + "microphone", + "networking", + "push-notification-client", + "sensors", + "usermetrics", + "video", + "webview" + ], + "reserved": [ + "calendar", + "contacts", + "debug", + "history", + "music_files", + "music_files_read", + "picture_files", + "picture_files_read", + "video_files", + "video_files_read" + ] + } } }, "ubuntu-snappy": { diff -Nru click-reviewers-tools-0.33/debian/bzr-builder.manifest click-reviewers-tools-0.34/debian/bzr-builder.manifest --- click-reviewers-tools-0.33/debian/bzr-builder.manifest 2015-07-22 16:46:42.000000000 +0000 +++ click-reviewers-tools-0.34/debian/bzr-builder.manifest 2015-09-16 14:16:24.000000000 +0000 @@ -1,2 +1,2 @@ -# bzr-builder format 0.3 deb-version {debupstream}-0~505 -lp:click-reviewers-tools revid:jamie@ubuntu.com-20150722163036-edp082n6ylthbzq7 +# bzr-builder format 0.3 deb-version {debupstream}-0~520 +lp:click-reviewers-tools revid:jamie@ubuntu.com-20150916140455-n3ysrfpjahl8c1bd diff -Nru click-reviewers-tools-0.33/debian/changelog click-reviewers-tools-0.34/debian/changelog --- click-reviewers-tools-0.33/debian/changelog 2015-07-22 16:46:42.000000000 +0000 +++ click-reviewers-tools-0.34/debian/changelog 2015-09-16 14:16:24.000000000 +0000 @@ -1,14 +1,22 @@ -click-reviewers-tools (0.33-0~505~ubuntu14.04.1) trusty; urgency=low +click-reviewers-tools (0.34-0~520~ubuntu14.04.1) trusty; urgency=low * Auto build. - -- Daniel Holbach Wed, 22 Jul 2015 16:46:42 +0000 + -- Daniel Holbach Wed, 16 Sep 2015 14:16:24 +0000 -click-reviewers-tools (0.33) UNRELEASED; urgency=medium +click-reviewers-tools (0.34) UNRELEASED; urgency=medium + + [ Jamie Strandboge ] + * multiple 'desktop' hooks should only be 'info' these days (LP: #1496402) + + -- Jamie Strandboge Thu, 10 Sep 2015 14:28:13 -0500 + +click-reviewers-tools (0.33) wily; urgency=medium [ Alberto Mardegan ] * clickreviews/cr_online_accounts.py: Do not check for "type" element in OA .service files + * clickreviews/cr_online_accounts.py: Support the new "accounts" hook [ Jamie Strandboge ] * clickreviews/cr_common.py: add peer_hooks_link to __init__ and use it @@ -17,8 +25,22 @@ https://wiki.ubuntu.com/SecurityTeam/Specifications/OnlineAccountsConfinement * clickreviews/tests/test_cr_online_accounts.py: don't stub or check for "type" element in OA .service files + * Makefile: make sure check-names.list is up to date via 'make check' + + [ Ricardo Kirkner ] + * Refactor to abstract check name generation. + This will be used in a follow up branch to normalize check names in a way + that allows extracting semantic meaning of check names from review results + data. + * build name from review_type, prefix, app and extra parts using : as + separator + * list all possible check types by running tests and extracting seen check + names + + [ Daniel Holbach ] + * Fix pep8 issues. - -- Jamie Strandboge Wed, 22 Jul 2015 11:30:07 -0500 + -- Jamie Strandboge Thu, 10 Sep 2015 11:17:00 -0500 click-reviewers-tools (0.32) wily; urgency=medium diff -Nru click-reviewers-tools-0.33/Makefile click-reviewers-tools-0.34/Makefile --- click-reviewers-tools-0.33/Makefile 2015-07-22 16:46:42.000000000 +0000 +++ click-reviewers-tools-0.34/Makefile 2015-09-16 14:16:24.000000000 +0000 @@ -11,7 +11,18 @@ ./run-pyflakes ./run-pep8 -check: test syntax-check +check-names: + # make sure check-names.list is up to date + cp -f check-names.list check-names.list.orig + ./collect-check-names + diff -Naur check-names.list.orig check-names.list || exit 1 + rm -f check-names.list.orig + +check: test syntax-check check-names clean: rm -rf ./clickreviews/__pycache__ ./clickreviews/tests/__pycache__ + +.PHONY: check-names.list +check-names.list: + ./collect-check-names diff -Nru click-reviewers-tools-0.33/run-tests click-reviewers-tools-0.34/run-tests --- click-reviewers-tools-0.33/run-tests 2015-07-22 16:46:42.000000000 +0000 +++ click-reviewers-tools-0.34/run-tests 2015-09-16 14:16:24.000000000 +0000 @@ -18,6 +18,9 @@ import sys import unittest +# NOTE: changes to this file may also need to be made to +# 'collect-check-names-from-tests' + test_directory = 'clickreviews/tests/' test_filename = 'test_*' if len(sys.argv) > 1: