vimの勉強中にLSP(Language Server Protocol)を知って、
Dockerでいろんな言語サーバーが簡単に起動できたら、
便利じゃない?っと思ったので、
今回はDockerで言語サーバーのPhanを動かしてみた。
できたやつ
あとはできたやつの説明
ディレクトリ構成
phan/
.phan/
config.php
src/
Foo.php
Dockerfile
docker-compose.yml
docker-compose.yml
version: '3.7'
services:
phan:
build: ./phan
volumes:
- type: bind
source: ./phan/.phan
target: /analyze/.phan
volume:
nocopy: true
- type: bind
source: ./phan/src #ここに解析したいディレクトリを設定する
target: /analyze/src
volume:
nocopy: true
できたやつでは、phan/src
ディレクトリが解析対象となるように、設定している。
ディレクトリを変更すれば解析対象を変更できる
Dockerfile
FROM php:7.3.10-cli-alpine3.10
WORKDIR /analyze
ENV PHPIZE_DEPS \
autoconf \
dpkg-dev dpkg \
file \
g++ \
gcc \
libc-dev \
make \
pkgconf \
re2c
RUN apk update && apk add --no-cache --virtual .build-deps $PHPIZE_DEPS; \
pecl install ast-1.0.1; \
echo 'extension=ast.so' > /usr/local/etc/php/php.ini; \
apk del --no-network .build-deps
ENV COMPOSER_ALLOW_SUPERUSER=1
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"; \
php -r "if (hash_file('sha384', 'composer-setup.php') === 'a5c698ffe4b8e849a443b120cd5ba38043260d5c4023dbf93e1558871f1f07f58274fc6f4c93bcfd858c6bd0775cd8d1') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"; \
php composer-setup.php; \
php -r "unlink('composer-setup.php');"; \
php composer.phar require "phan/phan:2.x"
CMD [ "./vendor/bin/phan"]
PhanのGetting Startedを参考にして必要なものを揃える
https://github.com/phan/phan/wiki/Getting-Started
PHPの7.1以上が必要なので、PHPの7.3.10のイメージを使用する
FROM php:7.3.10-cli-alpine3.10
php-ast 1.0.1以上が必要なので、php-astをpeclでインストールする
ENV PHPIZE_DEPS \
autoconf \
dpkg-dev dpkg \
file \
g++ \
gcc \
libc-dev \
make \
pkgconf \
re2c
RUN apk update && apk add --no-cache --virtual .build-deps $PHPIZE_DEPS; \
pecl install ast-1.0.1; \
echo 'extension=ast.so' > /usr/local/etc/php/php.ini; \
apk del --no-network .build-deps
今回のPHPのイメージはalpineをベースイメージとしているので、
peclを使用するために必要なものをPHPIZE_DEPSという環境変数にいれて、
ENV PHPIZE_DEPS \
autoconf \
dpkg-dev dpkg \
file \
g++ \
gcc \
libc-dev \
make \
pkgconf \
re2c
--virtualオプションで、 .build-deps という名前をつけてインストールしている
apk add --no-cache --virtual .build-deps $PHPIZE_DEPS
名前をつけると下記のように名前を指定するだけで、パッケージを削除できる
(削除する方法を知ってしまったので、遊びでイメージを小さくしています)
apk del --no-network .build-deps
削除の方法は、今回使用しているPHPのイメージのdockerfileを参考にしたよ
https://github.com/docker-library/php/blob/29a47a90c8569bcb5e1960fcebab323bf2d89816/7.3/alpine3.10/cli/Dockerfile
php-astのREADME.mdより、
https://github.com/nikic/php-ast
インストールして、php.iniにextension=ast.soを設定している
pecl install ast-1.0.1; \
echo 'extension=ast.so' > /usr/local/etc/php/php.ini; \
Phan 2.x をComposerでインストールする
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"; \
php -r "if (hash_file('sha384', 'composer-setup.php') === 'a5c698ffe4b8e849a443b120cd5ba38043260d5c4023dbf93e1558871f1f07f58274fc6f4c93bcfd858c6bd0775cd8d1') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"; \
php composer-setup.php; \
php -r "unlink('composer-setup.php');"; \
php composer.phar require "phan/phan:2.x"
まず、composer.pharをインストールする
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"; \
php -r "if (hash_file('sha384', 'composer-setup.php') === 'a5c698ffe4b8e849a443b120cd5ba38043260d5c4023dbf93e1558871f1f07f58274fc6f4c93bcfd858c6bd0775cd8d1') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"; \
php composer-setup.php; \
php -r "unlink('composer-setup.php');"; \
composer.pharでPhan 2.x をインストールする
php composer.phar require "phan/phan:2.x"
.phan/config.php
phan/.phan/config.php
はPhanの解析の設定ファイル
https://github.com/phan/phan/wiki/Incrementally-Strengthening-Analysis
vendor/bin/phan --init --init-level=1
解析が一番厳しい設定のファイルを作成しました
設定の項目の内容について
https://github.com/phan/phan/wiki/Phan-Config-Settings
解析してみる
$three = 3;
って変数が使われてなくて、
var_dum($one);
がタイポしている、
できたやつのphan/src/Foo.php
を解析する
<?php
class Foo
{
public function bar()
{
$one = 1;
$two = 2;
$three = 3;
var_dum($one);
var_dump($one + $two);
}
}
$ docker-compose run phan
src/Foo.php:9 PhanUnusedVariable Unused definition of variable $three
src/Foo.php:10 PhanUndeclaredFunction Call to undeclared function \var_dum() (Did you mean \var_dump())
変数が使われていないのと、var_dumpじゃないって教えてくれてる
おわり
LSPとして使うにはまだ、時間がかかりそう。
クライアントの設定がむずい。