본문 바로가기

Unity/작업방식

dotnet: BannedApiAnalyzer 도입기

도입 계기

작업자가 늘어나면서 코딩 스탠다드 및 네이밍 컨벤션 제어만으로는 사용하지 말아야 할 패턴에 대한 필터링이 어려워지고, 코드 리뷰 시간이 길어지기 시작했다. 일부 API들을 래핑해서 사용하기 시작하면서, 원형을 직접 사용하는 케이스를 Pull Request에서 사람이 직접 확인해야 했고, 이를 개선하기 위해 CI/CD에 분석기를 달아 최종적으로 PR이 머지되기 전 최소 1회 검증이 되도록 자동화했던 이력이 있다. 그런데, 이 케이스는 기대했던 것 보다 작업 과정에서 실수를 바로 알아채기가 힘들었고 코드 리뷰가 완료된 후 이 문제로 인해 코드를 수정해야하는 일이 생기곤 해서 검토했던 것 보다 생산성의 향상을 가져다 주지는 못했다. 

 

솔루션

Console.Log, Reflection 기능 등을 사용했을 때, 로컬 개발 환경에서 허용되지 않는 API의 사용을 하고 있다는 부분을 캐치할 필요성이 있었다. 다행히도 MS에서 제공하는 Roslyn 코드 분석기에 위와 같은 기능을 지원하는 BannedApiAnalyzer 유틸리티가 있어 빠르게 도입하였다. 

 

https://github.com/dotnet/roslyn-analyzers

 

GitHub - dotnet/roslyn-analyzers

Contribute to dotnet/roslyn-analyzers development by creating an account on GitHub.

github.com

 

NuGet에서도 BannedApiAnalyzer를 검색해서 쉽게 도입할 수 있다. 

 

도입

원리는 다음과 같다. 

 

  1. NuGet으로 BannedApiAnalyzer를 추가한다. 
  2. Warning을 발생시킬 API들의 Signature를 BannedSymbols.txt 텍스트 파일에 별도 지정한다. 
  3. .csproj를 수정하여, RS0030 경고를 Error로 격상한다. 

다듬기

개발환경에서만 필요하므로, Debug Configuration인 경우에 대해서만 BannedApiAnalyzer를 참조하도록 조치하는 형태로 구성해도 된다. 

만약, Ban 시킨 API를 필수적으로 사용해야 한다면, RS0030 경고를 임시로 껐다가 키는 코드를 삽입하여 관리할 수 있다. 프로젝트에서 특정한 API를 래핑해서 처리하는 용도로 이 방법론을 사용한다면, 아래와 같은 예제 처럼 래핑 코드 처리부에서만 사용을 허용하는 콘셉트가 되는 형태다. 

 

using System;

class GameLogger {
    public static void Log(string message) {
#pragma warning disable RS0030
        string time = System.DateTime.Now.ToString("HH:mm:ss");
        Console.WriteLine($"[{time}] {message}");
#pragma warning restore RS0030
    }
}

 

예제

BannedSymbols.txt에 Console.WriteLine(string arg1); 심볼을 추가했다. 

M:System.Console.WriteLine(System.String);Use implemented class of IConsoleLogger instaed.

 

금지된 API를 사용하려고 하면 경고가 출력된다. 단순 경고라, 컴파일은 성공으로 처리된다. 

프로젝트 속성에서 에러로 격상해주면, 에러로 처리된다. 

실사용처에서는 경고 임시 무시 배리어를 구성하여, 에러로 잡히지 않도록 예외처리한다. 

 

도입 후기

처음에 이를 도입하면서 수정해야 할 곳들이 더러 생겼다. 전체적으로 일괄수정 한 다음 부터는 추가적으로 금지된 API에 대한 수동/자동화 검증을 할 필요가 없게 되었고, 각자의 로컬 개발 환경에서 허용된 API로만 개발을 진행하여 일관적인 코드 품질과 의도를 나타낼 수 있게 되었다. 

 

 

유니티 프로젝트내에서 사용하기 위해서는 props를 활용하여 대응해 주면 된다. 유니티 엔진이 Roslyn 코드 분석기를 지원하는 버전이어야만 한다.