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. 終わりに
開発には必須ですが、どうしても後回しにしがちなので、調べておきました。
有効に活用していきたいと思います。