From patchwork Sun Feb 19 22:17:23 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ricardo Martincoski X-Patchwork-Id: 729671 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3vRLsr5Q3wz9s7R for ; Mon, 20 Feb 2017 09:24:48 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="hut8VEJD"; dkim-atps=neutral Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id 2613F8843C; Sun, 19 Feb 2017 22:24:47 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org X-Amavis-Alert: BAD HEADER SECTION, Duplicate header field: "References" Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id zP3nWh1OWs8b; Sun, 19 Feb 2017 22:24:44 +0000 (UTC) Received: from ash.osuosl.org (ash.osuosl.org [140.211.166.34]) by fraxinus.osuosl.org (Postfix) with ESMTP id 9E1AF8835F; Sun, 19 Feb 2017 22:24:44 +0000 (UTC) X-Original-To: buildroot@lists.busybox.net Delivered-To: buildroot@osuosl.org Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by ash.osuosl.org (Postfix) with ESMTP id 1F2531C1650 for ; Sun, 19 Feb 2017 22:24:44 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id 1894D8835F for ; Sun, 19 Feb 2017 22:24:44 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org X-Amavis-Alert: BAD HEADER SECTION, Duplicate header field: "References" Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 4rUAUO73QVsk for ; Sun, 19 Feb 2017 22:24:43 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mail-qt0-f194.google.com (mail-qt0-f194.google.com [209.85.216.194]) by fraxinus.osuosl.org (Postfix) with ESMTPS id 2EA988833F for ; Sun, 19 Feb 2017 22:24:43 +0000 (UTC) Received: by mail-qt0-f194.google.com with SMTP id n13so12085387qtc.0 for ; Sun, 19 Feb 2017 14:24:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=x5HsF6+jx4dGLKj40zLFkTvgAhNNDGm7eX01wbJNjMI=; b=hut8VEJDK3HkltF8nQb7Df2Mskg8ljuOqy/2+8yG+k3T43ipvNPUNmiM+lrAFPsEXv yKssNCw1B5bv2wiuaaJc2SFeCS/CMrWexr022T2WXKE4wAJyduCt04J1BR9sBlo4IJK4 3332ss5iMhtkJHehkzSDVluX+DiizQwrDNpDIILL+89zakA1cCBGGEMvVTXDboDfUkqr x+tpwkSBVvy93B4DZqxtLfh6jnDPW32OgK5YCS4p9Vtgi0xmUgVjsCiDQQYDzk5C6FMs d5uHSR2vXWTneVDn7L4erZ4Z85cqq7bj8vvg5LvggiFacQpEiBt/fFmAMP4FMY0tKolz gz3A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=x5HsF6+jx4dGLKj40zLFkTvgAhNNDGm7eX01wbJNjMI=; b=IqnluOai05LSlN0qwlTL+5SIXwM4XSoWtOPA86CDdamRgHlY7+5kE1+U/ja7fyZ07o VlxjdtL2djfxGYl1x289sSxnmXh0iJ60XXn1+SOREbXs0MJK1lA6o80aWAF6JjOIwyYP QA5c/pm+/a7WPLO3GbFCa2Qhs1NvRV9sK52vpg9O/sATHttEtfeQ3dHffIBDCDQFlQUL gNrwA3miBYCR17bBMQWpXhRRKOlZURryr9RT5LWQ93Oio7CCEBcghlxW/2AuhMgRsT+m LYRHZi5PWdrpR7SYDDf5FEIYYZwAa1xVInzEi/YsivWNs6dZSDOq6+I+lP7TVealZm2V q5Eg== X-Gm-Message-State: AMke39n1MOMI1/UvuhYBU334CK1n+btvq08UhzhM4jlhV+CX3sgYL8yRAK1D8LBNaM/sxw== X-Received: by 10.200.49.76 with SMTP id h12mr4268416qtb.44.1487543082176; Sun, 19 Feb 2017 14:24:42 -0800 (PST) Received: from ultri3.home ([201.86.219.185]) by smtp.gmail.com with ESMTPSA id d127sm10970245qka.30.2017.02.19.14.24.39 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 19 Feb 2017 14:24:40 -0800 (PST) From: Ricardo Martincoski To: buildroot@buildroot.org Date: Sun, 19 Feb 2017 19:17:23 -0300 Message-Id: <20170219221724.27298-9-ricardo.martincoski@gmail.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170219221724.27298-1-ricardo.martincoski@gmail.com> References: <20170219221724.27298-1-ricardo.martincoski@gmail.com> In-Reply-To: <20161231032110.11573-1-ricardo.martincoski@gmail.com> References: <20161231032110.11573-1-ricardo.martincoski@gmail.com> Cc: Thomas De Schampheleire , Ricardo Martincoski Subject: [Buildroot] [PATCH v2 8/9] check-package: check Config.* files X-BeenThere: buildroot@busybox.net X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: Discussion and development of buildroot List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: buildroot-bounces@busybox.net Sender: "buildroot" Warn when help text is larger than 72 columns, see [1]. Warn for wrongly indented attributes, see [1]. Warn when the convention of attributes order is not followed, see [2]. [1] http://nightly.buildroot.org/#writing-rules-config-in [2] http://nightly.buildroot.org/#_config_files Signed-off-by: Ricardo Martincoski --- Changes v1 -> v2: - update commit subject since now Config.* are tested; - use classes instead of functions to declare each check (Thomas DS); --- Notes: $ time support/scripts/check-package $(find package -type f) >/dev/null 2>/dev/null real 0m2.196s user 0m2.116s sys 0m0.044s AttributesOrder: support/scripts/check-package --include-only AttributesOrder \ $(find package -name 'Config.*') 2>/dev/null | wc -l 369 (cd support/scripts/check-package-example && \ ../check-package --include-only AttributesOrder -vv package/*/*) package/package1/Config.in:3: attributes order: type, default, depends on, select, help (http://nightly.buildroot.org/#_config_files) < tab >bool "pAcKaGe" package/package1/Config.in:6: attributes order: type, default, depends on, select, help (http://nightly.buildroot.org/#_config_files) < tab >depends on BR2_USE_WCHAR package/package1/Config.something:6: attributes order: type, default, depends on, select, help (http://nightly.buildroot.org/#_config_files) < tab >bool "Extension 1" 180 lines processed 3 warnings generated HelpText: support/scripts/check-package --include-only HelpText \ $(find package -name 'Config.*') 2>/dev/null | wc -l 987 (cd support/scripts/check-package-example && \ ../check-package --include-only HelpText -vv package/*/*) package/package1/Config.in:8: help text: <2 spaces><62 chars> (http://nightly.buildroot.org/#writing-rules-config-in) < tab > package1 is a bad stylized package. Its only purpose is to exemplify < tab > 123456789 123456789 123456789 123456789 123456789 123456789 12 package/package1/Config.in:9: help text: <2 spaces><62 chars> (http://nightly.buildroot.org/#writing-rules-config-in) common style mistakes < tab > 123456789 123456789 123456789 123456789 123456789 123456789 12 package/package1/Config.in:10: help text: <2 spaces><62 chars> (http://nightly.buildroot.org/#writing-rules-config-in) < tab >some more help text but no url < tab > 123456789 123456789 123456789 123456789 123456789 123456789 12 package/package1/Config.in:23: help text: <2 spaces><62 chars> (http://nightly.buildroot.org/#writing-rules-config-in) < tab > Another paragraph. - But this time we cross the column 72 by 1. < tab > 123456789 123456789 123456789 123456789 123456789 123456789 12 package/package1/Config.in:24: help text: <2 spaces><62 chars> (http://nightly.buildroot.org/#writing-rules-config-in) < tab > wrong_line_with_single_word < tab > 123456789 123456789 123456789 123456789 123456789 123456789 12 package/package1/Config.in:25: help text: <2 spaces><62 chars> (http://nightly.buildroot.org/#writing-rules-config-in) < tab > http://www.example.com/ urls do not have spaces and this line is too long. < tab > 123456789 123456789 123456789 123456789 123456789 123456789 12 180 lines processed 6 warnings generated Indent: support/scripts/check-package --include-only Indent \ $(find package -name 'Config.*') 2>/dev/null | wc -l 501 (cd support/scripts/check-package-example && \ ../check-package --include-only Indent -vv package/*/*) package/package1/Config.in:13: should not be indented config BR2_PACKAGE_PACKAGE1_OPTION package/package1/Config.in:14: should be indented with one tab (http://nightly.buildroot.org/#_config_files) bool "package1 option" package/package1/Config.in:15: should be indented with one tab (http://nightly.buildroot.org/#_config_files) depends on BR2_USE_MMU package/package1/Config.in:16: should be indented with one tab (http://nightly.buildroot.org/#_config_files) select BR2_PACKAGE_GETTEXT if BR2_NEEDS_GETTEXT_IF_LOCALE package/package1/Config.in:17: should be indented with one tab (http://nightly.buildroot.org/#_config_files) help package/package1/Config.in:37: continuation line should be indented using tabs if BR2_aarch64 package/package1/Config.in:44: should be indented with one tab (http://nightly.buildroot.org/#_config_files) depends on BR2_USE_MMU package/package1/package1.mk:22: unexpected indent with tabs < tab >PACKAGE1_INSTALL_STAGING = NO package/package1/package1.mk:27: expected indent with tabs depend3 package/package1/package1.mk:42: expected indent with tabs mkdir -p $(TARGET_DIR)/var/lib package/package1/package1.mk:51: expected indent with tabs $(PACKAGE1_INSTALL_SOMETHING_ELSE) 180 lines processed 11 warnings generated support/scripts/checkpackagelib_config.py | 128 ++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) diff --git a/support/scripts/checkpackagelib_config.py b/support/scripts/checkpackagelib_config.py index ee5981e64..be52d9432 100644 --- a/support/scripts/checkpackagelib_config.py +++ b/support/scripts/checkpackagelib_config.py @@ -3,8 +3,136 @@ # "bool", so below check functions don't need to check for things already # checked by running "make menuconfig". +import re + +from checkpackagebase import _CheckFunction # Notice: ignore 'imported but unused' from pyflakes for check functions. from checkpackagelib import ConsecutiveEmptyLines from checkpackagelib import EmptyLastLine from checkpackagelib import NewlineAtEof from checkpackagelib import TrailingSpace + + +def _empty_or_comment(text): + line = text.strip() + # ignore empty lines and comment lines indented or not + return line == "" or line.startswith("#") + + +def _part_of_help_text(text): + return text.startswith("\t ") + + +# used in more than one check +entries_that_should_not_be_indented = [ + "choice", "comment", "config", "endchoice", "endif", "endmenu", "if", + "menu", "menuconfig", "source"] + + +class AttributesOrder(_CheckFunction): + attributes_order_convention = { + "bool": 1, "prompt": 1, "string": 1, "default": 2, "depends": 3, + "select": 4, "help": 5} + + def before(self): + self.state = 0 + + def check_line(self, lineno, text): + if _empty_or_comment(text) or _part_of_help_text(text): + return + + attribute = text.split()[0] + + if attribute in entries_that_should_not_be_indented: + self.state = 0 + return + if attribute not in self.attributes_order_convention.keys(): + return + new_state = self.attributes_order_convention[attribute] + wrong_order = self.state > new_state + + # save to process next line + self.state = new_state + + if wrong_order: + return ["{}:{}: attributes order: type, default, depends on," + " select, help ({}#_config_files)" + .format(self.filename, lineno, self.url_to_manual), + text] + + +class HelpText(_CheckFunction): + HELP_TEXT_FORMAT = re.compile("^\t .{,62}$") + URL_ONLY = re.compile("^(http|https|git)://\S*$") + + def before(self): + self.help_text = False + + def check_line(self, lineno, text): + if _empty_or_comment(text): + return + + entry = text.split()[0] + + if entry in entries_that_should_not_be_indented: + self.help_text = False + return + if text.strip() == "help": + self.help_text = True + return + + if not self.help_text: + return + + if self.HELP_TEXT_FORMAT.match(text.rstrip()): + return + if self.URL_ONLY.match(text.strip()): + return + return ["{}:{}: help text: <2 spaces><62 chars>" + " ({}#writing-rules-config-in)" + .format(self.filename, lineno, self.url_to_manual), + text, + "\t " + "123456789 " * 6 + "12"] + + +class Indent(_CheckFunction): + ENDS_WITH_BACKSLASH = re.compile(r"^[^#].*\\$") + entries_that_should_be_indented = [ + "bool", "default", "depends", "help", "prompt", "select", "string"] + + def before(self): + self.backslash = False + + def check_line(self, lineno, text): + if _empty_or_comment(text) or _part_of_help_text(text): + self.backslash = False + return + + entry = text.split()[0] + + last_line_ends_in_backslash = self.backslash + + # calculate for next line + if self.ENDS_WITH_BACKSLASH.search(text): + self.backslash = True + else: + self.backslash = False + + if last_line_ends_in_backslash: + if text.startswith("\t"): + return + return ["{}:{}: continuation line should be indented using tabs" + .format(self.filename, lineno), + text] + + if entry in self.entries_that_should_be_indented: + if not text.startswith("\t{}".format(entry)): + return ["{}:{}: should be indented with one tab" + " ({}#_config_files)" + .format(self.filename, lineno, self.url_to_manual), + text] + elif entry in entries_that_should_not_be_indented: + if not text.startswith(entry): + return ["{}:{}: should not be indented" + .format(self.filename, lineno), + text]