1.はじめに
最近、仕事で複数スクリプトを組み合わせてコーディングすることが多くなりました。
それだと、各スクリプトの癖を忘れたり、そもそもどう書くのか忘れたりと、不良を作りこむ可能性が多くなります。
なので、スクリプトの整形/文法チェック(lint)する環境を整える必要があると考えました。
主に使用するスクリプトは以下としました。
- perl(5.26,1)
- python(3.5.2)
IDEを使う方式もありますが、今回はコマンドで起動する方式にします。
以降で各スクリプトの整形/lintツールのインストール方法を書いていきます。
2.perl
2.1 インストール
perltidyとPerl::Criticは以下でインストールします。
$ cpanm Perl::Tidy $ cpanm Perl::Critic $ cpanm Test::Perl::Critic
2.2 整形ツール(perltidy)
整形は perltidy というコマンドを使用します。例として、s3.pl(ファイル名)にperltidyをかけると、s3.pl.tdyというファイルを生成します。
$HOME/.perltidyrcに以下のように書いておきます。
-l=78 # Max line width is 78 cols -i=4 # Indent level is 4 cols -ci=4 # Continuation indent is 4 cols -se # Errors to STDERR -vt=2 # Maximal vertical tightness -cti=0 # No extra indentation for closing brackets -pt=1 # Medium parenthesis tightness -bt=1 # Medium brace tightness -sbt=1 # Medium square brace tightness -bbt=1 # Medium block brace tightness -nsfs # No space before semicolons -nolq # Don't outdent long quoted strings -wbb="% + - * / x != == >= <= =~ !~ < > | & >= < = **= += *= &= <<= &&= -= /= |= >>= ||= .= %= ^= x=" # Break before all operators
実行例は以下の通りです。
$ vi s3.pl
#!/usr/bin/perl
package TEST;
use strict;
use warnings;
use Smart::Comments;
foo();
sub foo {
bar();
}
sub bar {
baz();
}
sub baz {
### <here>
print "loooooooooooooooooonggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg";
}
$ perltidy s3.pl
$ ls -l s3.pl.tdy
s3.pl.tdy
$ cat s3.pl.tdy
#!/usr/bin/perl
package TEST;
use strict;
use warnings;
use Smart::Comments;
foo();
sub foo {
bar();
}
sub bar {
baz();
}
sub baz {
### <here>
print
"loooooooooooooooooonggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg";
}
ソースを直接編集するなら-bをつけます。
$ perltidy -b s3.pl
2.3 文法チェック(Perl::Critic)
文法チェックには、 Perl::Critic を使用します。以下でs3.plをチェックします。
ディレクトリを指定すれば、ディレクトリ下のソースを再帰してチェックします。
$ perlcritic --profile-proto > t/perlcriticrc
$ vi t/99.-perlcritic.t
use strict;
use Test::More;
eval { require Test::Perl::Critic; Test::Perl::Critic->import(-profile => "t/perlcriticrc") };
plan skip_all => "Test::Perl::Critic is not installed." if $@;
all_critic_ok("s3.pl");
手元のコードを確認してみると、以下のようになります。
$ perl t/99-perlcritic.t ok - Test::Perl::Critic for "s3.pl" 1..1
3.python
pythonのバージョンは3.5を仮定しています。
3.1 インストール
autopep8とflake8は以下のようにインストールします。
$ pip install autopep8 $ pip install flake8
3.2 整形ツール(autopep8)
整形ツールには、autopep8が使えます。その他に[yapf]
というのもありますが、今回はautopep8で整形してみます。
以下のようにインストールします。
以下のようなテストコードを書いてみます。
vi hw.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from bottle import route, run
a = ['', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa','bb','cc','dd','ee','ff']
b = {'aa': 1,'bb':2, 'ccccccccccccccccccccccccccccccccccccccccc': 3333333333333333, 'ddd': 'bbbb'}
#テスト用コード
@route('/hello')
def hello():
""" テスト実装
"""
print(a)
print(b)
return "Hello World!"
#テスト用起動
run(host='0.0.0.0', port=8080, debug=True, reloader=True)
以下で起動します。「-i」はそのファイルを直接修正します。「-a」はaggressiveの意味で、より見やすく修正されるようなのでつけて起動しています。
$ autopep8 -i -a -a hw.py
autopep8を通した結果、以下になりました。コメントの位置がちょっと納得いきませんが、PEP8に準拠するとこうなることになりますので、問題ないようです。
vi hw.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from bottle import route, run
a = [
'',
'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
'bb',
'cc',
'dd',
'ee',
'ff']
b = {
'aa': 1,
'bb': 2,
'ccccccccccccccccccccccccccccccccccccccccc': 3333333333333333,
'ddd': 'bbbb'}
# テスト用コード
@route('/hello')
def hello():
""" テスト実装
"""
print(a)
print(b)
return "Hello World!"
# テスト用起動
run(host='0.0.0.0', port=8080, debug=True, reloader=True)
3.3 文法チェック(flake8/tox)
flake8は複数のLintコマンドを統合したツールです。
修正前のhw.pyを通したところ、以下のように言われました。
$ flake8 hw.py hw2.py:1:1: E902 IndentationError: unindent does not match any outer indentation level hw2.py:5:75: E231 missing whitespace after ',' hw2.py:5:80: E501 line too long (100 > 79 characters) hw2.py:5:80: E231 missing whitespace after ',' hw2.py:5:85: E231 missing whitespace after ',' hw2.py:5:90: E231 missing whitespace after ',' hw2.py:5:95: E231 missing whitespace after ',' hw2.py:7:13: E231 missing whitespace after ',' hw2.py:7:18: E231 missing whitespace after ':' hw2.py:7:80: E501 line too long (98 > 79 characters) hw2.py:9:1: E265 block comment should start with '# ' hw2.py:10:1: E302 expected 2 blank lines, found 1 hw2.py:13:1: W191 indentation contains tabs hw2.py:14:10: E999 IndentationError: unindent does not match any outer indentation level
flake8をtox経由起動することもできます。以下がtoxを起動した際の出力です。
$ tox -e flake8 flake8 installed: flake8==3.5.0,flake8-colors==0.1.6,flake8-docstrings==1.3.0,flake8-import-order==0.17.1,flake8-polyfill==1.0.2,mccabe==0.6.1,pep8-naming==0.5.0,pycodestyle==2.3.1,pydocstyle==2.1.1,pyflakes==1.6.0,six==1.11.0,snowballstemmer==1.2.1 flake8 runtests: PYTHONHASHSEED='1882794980' flake8 runtests: commands[0] | flake8 . ./hw.py:1:1: D100 Missing docstring in public module ./hw.py:22:1: E302 expected 2 blank lines, found 1 ./hw.py:23:1: D400 First line should end with a period ./hw.py:23:1: D210 No whitespaces allowed surrounding docstring text ./hw.py:23:1: D200 One-line docstring should fit on one line with quotes
tox.iniは、
https://github.com/KenichiTanino/practice_the_script/blob/master/lint/tox.ini
に置いてあります。
4. 終わりに
開発には必須ですが、どうしても後回しにしがちなので、調べておきました。
有効に活用していきたいと思います。