LoginSignup
3
2

More than 3 years have passed since last update.

Dockerで言語サーバーのPhanを動かしてみた

Last updated at Posted at 2019-10-05

vimの勉強中にLSP(Language Server Protocol)を知って、
Dockerでいろんな言語サーバーが簡単に起動できたら、
便利じゃない?っと思ったので、
今回はDockerで言語サーバーのPhanを動かしてみた。

できたやつ

あとはできたやつの説明

ディレクトリ構成

phan/
  .phan/
    config.php
  src/
    Foo.php
Dockerfile
docker-compose.yml

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

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を解析する

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として使うにはまだ、時間がかかりそう。
クライアントの設定がむずい。

3
2
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2