写土熊指南¶
欢迎。本文档介绍了如何为Coala写一只熊的信息。它假设您知道如何使用Coala。如果没有,请阅读我们的 main tutorial
本教程的示例源代码位于我们的Coala-Tutorial库中,请使用以下命令克隆它:
git clone https://github.com/coala/coala-tutorial
这里给出的所有路径和命令都是从Coala-Tutorial存储库的根目录执行的。
备注
如果要包装已有的工具,请参阅 this tutorial instead .
熊是什么?¶
熊是用来对源代码进行一些分析的。源代码将由Coala提供,这样熊就不必关心它来自哪里或去了哪里。
熊有两种:
LocalBears,它只对每个文件本身执行分析
GlobalBears,它们是项目范围的,就像GitCommittee Bear
熊可以通过两种方式与用户通信:
通过日志消息
VIA结果
日志消息将根据用户设置进行记录,通常在出现问题时使用。但是,您可以使用DEBUG来提供与开发相关的调试信息,因为默认情况下它不会显示给用户。如果使用错误/失败消息,则预计BEAR不会继续分析。
一只你好的世界熊¶
以下是为每个文件发送调试消息的简单BEAR提供的代码:
import logging
from coalib.bears.LocalBear import LocalBear
class HelloWorldBear(LocalBear):
def run(self,
filename,
file):
logging.debug("Hello World! Checking file {}.".format(filename))
这只熊存放在 ./bears/HelloWorldBear.py
In order to let coala execute this bear you need to let coala know where
to find it. We can do that with the -d
(--bear-dirs
) argument:
coala -f src/*.c -d bears -b HelloWorldBear -L DEBUG --flush-cache
备注
给定的BEAR目录中不能有任何全局表达式。任何可以解释为全局表达式一部分的字符都将被转义。请使用逗号分隔值给出几个这样的目录。不要忘记刷新缓存(通过添加参数 --flush-cache
在运行Coala时),如果您对先前分析过的文件运行新的Bear(由Coala分析)。
现在,您应该在命令行上看到类似以下内容的输出:
[WARNING][15:07:39] Default coafile '.coafile' not found!
Here's what you can do:
* add `--save` to generate a config file with your current options
* add `-I` to suppress any use of config files
[DEBUG][15:07:39] Platform Linux -- Python 3.5.2, coalib
0.12.0.dev20170626132008
[DEBUG][15:07:39] The file cache was successfully flushed.
[DEBUG][15:07:39] Files that will be checked:
/home/LordVoldemort/programs/coa_dir/coala-tutorial/src/main.c
[DEBUG][15:07:40] coala is run only on changed files, bears' log
messages from previous runs may not appear. You may use the
`--flush-cache` flag to see them.
[DEBUG][15:07:40] Running bear HelloWorldBear...
[DEBUG][15:07:40] Hello World! Checking file /home/LordVoldemort/
programs/coa_dir/coala-tutorial/src/main.c .
Notice that the last ``[DEBUG]`` message is what was coded in
``HelloWorldBear.py``. All the other messages are inherited from the
``LocalBear`` class or run by the code responsible for executing the
bear.
备注
第一 WARNING
消息是因为我们的目录不包含 .coafile
。如果您已按照我们的 main tutorial ,您将拥有一个 .coafile
在您的工作目录中。最好在学习本教程之前删除该文件,否则您还会看到来自其他熊的一大堆其他输出。
有关Python内置的更多详细信息 logging
设施,请参阅https://docs.python.org/3/library/logging.html.
与用户通信¶
现在我们可以通过队列发送消息了,我们可以做真正的工作了。比方说:
我们需要来自用户的一些信息(例如,如果我们依赖缩进,则制表符宽度)。
我们为用户提供了一些有用的信息,并希望将其展示给他们。他们的代码可能有问题,或者只是行数之类的信息。
因此,让我们将HelloWorldBear扩展一下,我将新熊命名为CommunicationBear,这个名字很有创意:
import logging
from coalib.bears.LocalBear import LocalBear
class CommunicationBear(LocalBear):
def run(self,
filename,
file,
user_input: str):
"""
Communicates with the user.
:param user_input: Arbitrary user input.
"""
logging.debug("Got '{ui}' as user input of type {type}.".format(
ui=user_input,
type=type(user_input)))
yield self.new_result(message="A hello world result.",
file=filename)
尝试执行它:
coala -f=src/\*.c -d=bears -b=CommunicationBear -L=DEBUG --flush-cache
嘿,我们会被要求输入用户信息的!
[WARNING][15:20:18] Default coafile '.coafile' not found!
Here's what you can do:
* add `--save` to generate a config file with your current options
* add `-I` to suppress any use of config files
Please enter a value for the setting "user_input" (No description given.)
needed by CommunicationBear for section "cli":
那不是很容易吗?继续,输入一些内容并观察输出。
Avada Kedavra
[DEBUG][15:22:55] Platform Linux -- Python 3.5.2, coalib
0.12.0.dev20170626132008
[DEBUG][15:22:55] The file cache was successfully flushed.
[DEBUG][15:22:55] Files that will be checked:
/home/LordVoldemort/programs/coa_dir/coala-tutorial/src/main.c
[DEBUG][15:22:55] coala is run only on changed files, bears' log messages
from previous runs may not appear. You may use the `--flush-cache` flag to
see them.
[DEBUG][15:22:55] Running bear CommunicationBear...
[DEBUG][15:22:55] Got 'Avada Kedavra' as user input of type <class 'str'>.
**** CommunicationBear [Section: cli] ****
! ! [Severity: NORMAL]
! ! A hello world result.
[ ] Do (N)othing
[ ] (O)pen file
[ ] Add (I)gnore comment
[ ] Enter number (Ctrl-D to exit):
那么,科拉在这里做了什么?
首先,Coala查看了run方法的参数,发现我们需要一些名为user_input的值。然后,它解析我们的文档注释并找到参数的描述,该描述显示给我们以帮助我们选择正确的值。在提供了所需的值之后,Coala将该值转换为字符串,因为我们已经提供了 str
此参数的批注。如果没有给出批注,或者值不能转换为所需的数据类型,您将获得一个 coalib.settings.Setting.Setting
.
您的文档字符串还可以用来告诉用户您的熊到底做了什么。
试着执行
coala -d bears -b CommunicationBear --show-bears --show-description
这将向用户显示一系列与熊相关的信息,如:-熊做什么的描述-使用它的部分-它使用的设置(可选和必需)
备注
熊还没有安装好。我们仍然需要使用以下命令指定BEAR目录 -d
或 --bear-dirs
旗帜。
安装本地写入的熊¶
假设我们编写了一个包含NewBear的文件NewBear.py,并希望在本地运行它。要安装我们的NewBear,请执行以下操作:
移动
NewBear.py
给我们克隆的科拉熊coala-bear/bears/<some_directory>
.使用以下内容更新来源中的所有熊:
pip3 install -U <path/to/coala-bears>
我们的新熊装好了。
尝试执行以下命令:
coala --show-bears
这显示了所有已安装的熊的列表。我们可以在单子里找到我们的新熊。
支持哪些数据类型?¶
该设置确实支持一些非常基本的类型:
弦 (
str
)浮标 (
float
)int (
int
)布尔 (
bool
,将接受如下值true
,yes
,yeah
,no
,nope
,false
)字符串列表 (
list
,值将用逗号拆分)字符串词典 (
dict
,值将以逗号和冒号分隔)
您可以使用基本类型的快捷方式, str_list
对于字符串, int_list
对于INT, float_list
对于浮点数和 bool_list
用于布尔值。
如果需要其他类型,可以自己编写转换函数并将此函数用作注释(如果不能转换值,请确保抛出 TypeError
或 ValueError
)。我们为您提供了一些高级转换:
coalib.settings.Setting.path
,转换为相对于设置了设置的文件/命令的绝对文件路径coalib.settings.Setting.path_list
,转换为相对于设置了设置的文件/命令的绝对文件路径列表coalib.settings.Setting.typed_list(typ)
,转换为列表并应用给定的转换。 (typ
)添加到每个元素。coalib.settings.Setting.typed_ordered_dict(key_type, value_type, default)
方法时,转换为词典。key_type
转换为所有密钥时,value_type
转换为所有值,并使用default
所有未设置关键点的值。使用typed_dict
如果订单对你无关紧要。coalib.settings.Setting.language
,转换为CoalaLanguage
对象。
结果¶
最后,我们得到了一个结果。如果提供了文件,Coala将显示该文件,如果提供了行,Coala还将在受影响的行之前显示几行。Result构造函数有几个参数,因此您可以创建一个向用户建议代码更改的结果。如果用户喜欢,Coala会自动应用它-你不需要在意。
您的函数需要返回一个可迭代的 Result
对象:这意味着您可以返回一个 list
属于 Result
对象,或者简单地将它们返回并将该方法编写为生成器。
备注
我们目前正计划为熊市写手和我们简化熊市。为了使您的Bear将来成为证据,我们建议以生成器样式编写您的方法。
别担心:为了将您的Bears迁移到我们的新API,您可能只需要更改两行代码。有关熊未来的更多信息,请在https://github.com/coala/coala/issues/725上阅读或在https://coala.io/chat.上询问我们
熊依赖于其他熊¶
所以我们已经有了一个结果,但是如果我们需要我们的Bear依赖于另一个Bear的结果呢?
Coala有一个高效的依赖管理系统,它可以在您的Bear之前运行另一个Bear,并为您获取其结果。你所需要做的就是告诉Coala你想在你的熊之前跑哪只熊。
那么让我们看看你如何告诉Coala在你之前跑哪只熊:
from coalib.bears.LocalBear import LocalBear
from bears.somePathTo.OtherBear import OtherBear
class DependentBear(LocalBear):
BEAR_DEPS = {OtherBear}
def run(self, filename, file, dependency_results):
results = dependency_results[OtherBear.name]
如你所见,我们有一个 coalib.bears.Bear.Bear.BEAR_DEPS 集合,其中包含我们希望依赖的熊的列表。在本例中,它是一个包含1个项目的集合:“OtherBear”。
备注
这个 BEAR_DEPS set必须有Bear本身的类,而不是字符串形式的名称。
科拉得到了 BEAR_DEPS
在执行 DependentBear
先把所有的熊队都放进去。
在运行这些熊之后,Coala给出了熊队在 dependency_results
DICTIONARY,它将熊的名字作为关键字,将结果列表作为值。例如,在这种情况下,我们将有 dependency_results == {{'OtherBear' : [list containing results of OtherBear]]}}
.
备注
dependency_results
在这里是关键字,不能由任何其他名称调用。
更多配置选项¶
Coala提供元数据,根据您的需要进一步配置您的熊。以下是您可以提供的所有元数据的列表:
LANGUAGES¶
要指示您的熊支持哪些语言,您需要给它一个 set 将字符串表示为值:
class SomeBear(Bear):
LANGUAGES = {'C', 'CPP','C#', 'D'}
备注
对于语言命名,请始终考虑相应Wikipedia页面中使用的格式(例外情况:使用CPP,而不是CPP或C++)。
如果该定义尚不存在,则在编写新的Bear时应添加语言定义。
语言中使用的别名应该是Coala定义中的名称之一。
REQUIREMENTS¶
若要指示熊的要求,请指定 REQUIREMENTS
具有的子类实例的集合 PackageRequirement
例如:
PipRequirement
NpmRequirement
CondaRequirement
DistributionRequirement
GemRequirement
GoRequirement
JuliaRequirement
RscriptRequirement
class SomeBear(Bear):
REQUIREMENTS = {
PipRequirement('coala_decorators', '0.2.1')}
要指定多个需求,您可以使用Multiple方法。这可以接收两个字符串元组(如果需要特定版本)或简单字符串(如果需要指定最新版本)。
class SomeBear(Bear):
REQUIREMENTS = PipRequirement.multiple(
('colorama', '0.1'),
'coala_decorators')
INCLUDE_LOCAL_FILES¶
如果您的熊需要包括本地文件,则通过将包含文件路径的字符串(相对于包含熊的文件)提供给 INCLUDE_LOCAL_FILES
.
class SomeBear(Bear):
INCLUDE_LOCAL_FILES = {'checkstyle.jar',
'google_checks.xml'}
可检测和可修复(_D)¶
要轻松跟踪熊可以做什么,可以设置 CAN_FIX 和 CAN_DETECT 成套的。
class SomeBear(Bear):
CAN_DETECT = {'Unused Code', 'Spelling'}
CAN_FIX = {'Syntax', 'Formatting'}
要查看可能值的完整列表,请检查此列表:
Syntax
Formatting
Security
Complexity
Smell
Unused Code
Redundancy
Variable Misuse
Spelling
Memory Leak
Documentation
Duplication
Commented Code
Grammar
Missing Import
Unreachable Code
Undefined Element
Code Simplification
指定要执行的操作 CAN_FIX 很明显,它也可以被检测到,因此可以从 CAN_DETECT
BEAR_DEPS¶
BEAR_DEPS
包含要在执行此Bear之前执行的Bear类。然后,这些Bear的结果将作为字典通过 dependency_results 论点。DICT将以熊的名称作为关键字,并将其结果列表作为值:
class SomeOtherBear(Bear):
BEAR_DEPS = {SomeBear}
有关更多详细信息,请参见 Bears Depending on Other Bears .
其他元数据¶
其他元数据,如 AUTHORS
, AUTHORS_EMAILS
, MAINTAINERS
, MAINTAINERS_EMAILS
, LICENSE
, ASCIINEMA_URL
, SEE_MORE
可按如下方式使用:
class SomeBear(Bear):
AUTHORS = {'Jon Snow'}
AUTHORS_EMAILS = {'jon_snow@gmail.com'}
MAINTAINERS = {'Catelyn Stark'}
MAINTAINERS_EMAILS = {'catelyn_stark@gmail.com'}
LICENSE = 'AGPL-3.0'
ASCIINEMA_URL = 'https://asciinema.org/a/80761'
SEE_MORE = 'https://www.pylint.org'
Aspect Bear(方面熊)¶
Aspect是Coala中的一个特性,它使得在项目中配置Coala变得更加容易,并且与语言无关。有关Aspect的更多详细信息,请参阅https://github.com/coala/cEPs/blob/master/cEP-0005.md.中的CEP-005.
符合方面的BEAR必须:
声明它可以修复和检测的方面列表。请注意,方面必须是叶方面。您可以在此处查看支持的方面列表https://github.com/coala/aspect-docs.
声明支持的语言列表。请参阅支持的语言https://github.com/coala/coala/tree/master/coalib/bearlib/languages/definitions.列表
使用将设置映射到其等效的纵横比或品味
map_setting_to_aspect
装饰者。与相关方面的产出结果。
例如,让我们创建一个名为SpellingCheckBear的方面熊。
from coalib.bearlib.aspects import map_setting_to_aspect
from coalib.bearlib.aspects.Spelling import (
DictionarySpelling,
OrgSpecificWordSpelling,
)
from coalib.bears.LocalBear import LocalBear
class SpellingCheckBear(
LocalBear,
aspect={
'detect': [
DictionarySpelling,
OrgSpecificWordSpelling,
],
},
languages=['Python']):
@map_setting_to_aspect(
use_standard_dictionary=DictionarySpelling,
additional_dictionary_words=OrgSpecificWordSpelling.specific_word,
)
def run(self,
filename,
file,
use_standard_dictionary: bool=True,
additional_dictionary_words: list=None):
"""
Detect wrong spelling.
:param use_standard_dictionary: Use standard English dictionary.
:param additional_dictionary_words: Additional list of word.
"""
if use_standard_dictionary:
# Imagine this is where we save our standard dictionary.
dictionary_words = ['lorem', 'ipsum']
else:
dictionary_words = []
if additional_dictionary_words:
dictionary_words += additional_dictionary_words
for word in file.split():
if word not in dictionary_words:
yield self.new_result(
message='Wrong spelling in word `{}`'.format(word),
aspect=DictionarySpelling('py'),
)