Vimeo 가 만든 PHP 용 정적 코드 분석기 psalm 으로 php 코드 품질 개선하기


개요

psalm 은 vimeo 가 만든 PHP 용 static code analyzer 입니다. vimeo 는 사업 초기 빠른 개발을 위해 PHP 를 많이 사용하였는데 비즈니스가 정착된 후 PHP 의 성능 문제와 큰 코드 베이스를 유지하기 어려운 문제에 부딪혔습니다.

보통 이런 문제 해결을 위해 전체 인프라를 재개발하는 것은 실패하는 경우가 많습니다. 새로운 언어로 작성되는 코드는 기존 검증된 코드에 비해서 버그가 많을수 밖에 없고 개발중이므로 급변하는 비즈니스 요구 사항을 반영하기도 어렵게 됩니다.

비메오는 이때문에 기존 레거시 PHP 코드를 개선하는 쪽으로 방향을 잡았고 성능 개선을 위해 PHP 버전을 업그레이드하고 PHP 에 새로 도입된 다양한 문법적 개선 사항(scalar type definition, Return type declarations)들을 반영하여 refactoring 했습니다.

또 인터프리터 방식인 PHP 의 코드 품질을 높이기 위해 정적 코드 분석기를 자체 개발했고 이 결과물이 psalm 입니다.


비메오의 레거시 코드 대응 방식은 비즈니스가 정착된 후에 어떻게 기존 코드 베이스를 개선할 지 많은 시사점을 던져주고 있습니다.

설치

psalm 을 Linux 에서 사용하려면 pcntl 과 posix 확장이 필요하며 없을 경우 다음과 같은 에러가 발생하니 사전에 설치해 줘야 합니다.

The pcntl & posix extensions must be loaded in order for Psalm to be able to use multiple processes.


extension 이 준비되었으면 컴포저로 psalm 을 설치합니다.

composer require --dev vimeo/psalm


라라벨을 사용할 경우 더 정확한 코드 분석을 위해 라라벨 플러그인을 설치해 줍니다.

composer require --dev psalm/plugin-laravel

다음 명령어로 라라벨 플러그인을 활성화합니다.

./vendor/bin/psalm-plugin enable psalm/plugin-laravel


이제 psalm init 명령을 실행하면 psalm 구동 설정 파일인 psalm.xml 이 생성됩니다.

./vendor/bin/psalm --init


또는 라라벨을 사용할 경우 다음 내용을 담고 있는 psalm.xml 을 프로젝트 루트에 만들어 줘도 됩니다.

<?xml version="1.0"?>
<psalm
    errorLevel="5"
    resolveFromConfigFile="true"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="https://getpsalm.org/schema/config"
    xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
>
    <projectFiles>
        <directory name="app"/>
        <directory name="database/factories"/>
        <directory name="database/seeders"/>
        <ignoreFiles>
            <directory name="vendor"/>
            <file name="app/Providers/AppServiceProvider.php"/>
        </ignoreFiles>
    </projectFiles>
    <plugins>
        <pluginClass class="Psalm\LaravelPlugin\Plugin"/>
    </plugins>
</psalm>  


사용

옵션없이 psalm 을 실행하면 psalm.xml 설정에 있는 projectFiles 에서 소스를 찾아서 코드 검사를 수행합니다.

./vendor/bin/psalm  Scanning files...
Analyzing files...


------------------------------
No errors found!
------------------------------
6 other issues found.
You can display them with --show-info=true
------------------------------

Checks took 0.02 seconds and used 8.668MB of memory
No files analyzed 

laravel-ide-helper 와 같이 사용하는 경우 에러가 발생할 경우 ide-helper 의 버전을 고정시켜 주면 됩니다.


composer require --dev barryvdh/laravel-ide-helper ">=2.8.0 <2.9.2"


Option

clear-cache

psalm 은 검사 속도 향상을 위해 캐시를 사용하는데 가끔 오작동하는 경우가 있습니다. 이럴 경우 캐시를 삭제하는 --clear-cache 옵션을 주고 실행하면 됩니다.

$ ./vendor/bin/psalm --clear-cache

Cache directory deleted


코드 수정

--alter 옵션을 추가하면 리포트만 하지 않고 코드를 수정할 수 있으며 수정할 이슈는 issues 뒤에 유형을 적어주면 됩니다. 소스를 수정하는 것이므로 실제 구동전에 --dry-run 옵션을 추가하면 수정 내역이 표시됩니다.

$ ./vendor/bin/psalm --alter --issues=InvalidReturnType,MissingReturnType,MissingParamType --dry-run


+     *
      * @throws \App\Exceptions\InvalidParameterException
+     *
+     * @return void
      */
-    public function retrieved(Param $p)
+    public function retrieved(Param $p): void
     {
         $parser = new Parser();


설정

Error levels

검사할 레벨을 지정하며 숫자가 클 수록 꼼꼼하게 검사합니다. 1 부터  8까지 지정할 수 있으며 기본은 5 입니다.


ignoreFiles

검사에서 제외할 파일이나 디렉터리를 지정합니다. 다음은 vendor 폴더와 AppServiceProvider 파일을 제외하는 설정입니다.

<ignoreFiles>
            <directory name="vendor"/>
            <file name="app/Providers/AppServiceProvider.php"/>
</ignoreFiles>


같이 보기


Ref