.NET 로컬 도구
이 스킬을 사용해야 할 때
다음과 같은 상황에서 이 스킬을 사용하세요:
- 개발 팀 전체에 일관된 도구 환경을 설정할 때
- CI/CD 파이프라인이 로컬 개발과 동일한 도구 버전을 사용하도록 보장할 때
- 프로젝트별 CLI 도구(docfx, incrementalist, dotnet-ef 등)를 관리할 때
- 프로젝트 간 전역 도구 버전 충돌을 방지할 때
로컬 도구란?
로컬 도구는 리포지토리별로 설치되고 버전이 관리되는 .NET CLI 도구입니다. 전역(global)으로 설치되는 대신 .config/dotnet-tools.json에 정의되며 dotnet tool restore 명령어로 복원됩니다.
로컬 도구와 전역 도구 비교
| 항목 | 전역 도구 | 로컬 도구 |
|---|---|---|
| 설치 | dotnet tool install -g | dotnet tool restore |
| 범위 | 시스템 전체 | 리포지토리별 |
| 버전 관리 | 수동 | .config/dotnet-tools.json |
| CI/CD | 각 도구 별도 설치 필요 | 단일 복원 명령어 |
| 충돌 | 버전 충돌 가능 | 프로젝트별 격리 |
로컬 도구 설정
매니페스트 초기화
# .config/dotnet-tools.json 생성
dotnet new tool-manifest
다음 구조가 생성됩니다:
.config/
└── dotnet-tools.json
도구를 로컬로 설치
# 도구를 로컬로 설치
dotnet tool install docfx
# 특정 버전 설치
dotnet tool install docfx --version 2.78.3
# 특정 소스에서 설치
dotnet tool install MyTool --add-source https://mycompany.pkgs.visualstudio.com/_packaging/feed/nuget/v3/index.json
도구 복원
# 매니페스트에서 모든 도구 복원
dotnet tool restore
dotnet-tools.json 형식
{
"version": 1,
"isRoot": true,
"tools": {
"docfx": {
"version": "2.78.3",
"commands": [
"docfx"
],
"rollForward": false
},
"dotnet-ef": {
"version": "9.0.0",
"commands": [
"dotnet-ef"
],
"rollForward": false
},
"incrementalist.cmd": {
"version": "1.2.0",
"commands": [
"incrementalist"
],
"rollForward": false
},
"dotnet-reportgenerator-globaltool": {
"version": "5.4.1",
"commands": [
"reportgenerator"
],
"rollForward": false
}
}
}
필드
| 필드 | 설명 |
|---|---|
version | 매니페스트 스키마 버전 (항상 1) |
isRoot | 이 매니페스트를 루트로 표시 (상위 디렉터리 검색 방지) |
tools | 도구 구성의 딕셔너리 |
tools.<name>.version | 설치할 정확한 버전 |
tools.<name>.commands | 도구가 제공하는 CLI 명령어 |
tools.<name>.rollForward | 최신 버전 허용 여부 (재현성을 위해 보통 false) |
일반적인 도구
문서화
# DocFX - API 문서 생성기
dotnet tool install docfx
"docfx": {
"version": "2.78.3",
"commands": ["docfx"],
"rollForward": false
}
사용법:
dotnet docfx docfx.json
dotnet docfx serve _site
Entity Framework Core
# EF Core CLI (마이그레이션용)
dotnet tool install dotnet-ef
"dotnet-ef": {
"version": "9.0.0",
"commands": ["dotnet-ef"],
"rollForward": false
}
사용법:
dotnet ef migrations add InitialCreate
dotnet ef database update
코드 커버리지
# ReportGenerator (커버리지 보고서용)
dotnet tool install dotnet-reportgenerator-globaltool
"dotnet-reportgenerator-globaltool": {
"version": "5.4.1",
"commands": ["reportgenerator"],
"rollForward": false
}
사용법:
dotnet reportgenerator -reports:coverage.cobertura.xml -targetdir:coveragereport -reporttypes:Html
증분 빌드
# Incrementalist - 변경된 프로젝트만 빌드
dotnet tool install incrementalist.cmd
"incrementalist.cmd": {
"version": "1.2.0",
"commands": ["incrementalist"],
"rollForward": false
}
사용법:
# main 브랜치 이후 변경된 프로젝트 확인
incrementalist --branch main
코드 서식
# CSharpier - 의견이 반영된 C# 포맷터
dotnet tool install csharpier
"csharpier": {
"version": "0.30.3",
"commands": ["dotnet-csharpier"],
"rollForward": false
}
사용법:
dotnet csharpier .
dotnet csharpier --check . # CI 모드 - 변경이 필요하면 실패
코드 분석
# JB dotnet-inspect (라이선스 필요)
dotnet tool install jb
"jb": {
"version": "2024.3.4",
"commands": ["jb"],
"rollForward": false
}
CI/CD 통합
GitHub Actions
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
global-json-file: global.json
- name: Restore tools
run: dotnet tool restore
- name: Build
run: dotnet build
- name: Test with coverage
run: dotnet test --collect:"XPlat Code Coverage"
- name: Generate coverage report
run: dotnet reportgenerator -reports:**/coverage.cobertura.xml -targetdir:coveragereport
- name: Build documentation
run: dotnet docfx docs/docfx.json
Azure Pipelines
steps:
- task: UseDotNet@2
inputs:
useGlobalJson: true
- script: dotnet tool restore
displayName: 'Restore .NET tools'
- script: dotnet build -c Release
displayName: 'Build'
- script: dotnet test -c Release --collect:"XPlat Code Coverage"
displayName: 'Test'
- script: dotnet reportgenerator -reports:**/coverage.cobertura.xml -targetdir:$(Build.ArtifactStagingDirectory)/coverage
displayName: 'Generate coverage report'
도구 버전 관리
도구 업데이트
# 최신 버전으로 업데이트
dotnet tool update docfx
# 특정 버전으로 업데이트
dotnet tool update docfx --version 2.79.0
설치된 도구 목록 확인
# 로컬 도구 목록 확인
dotnet tool list
# 구버전 확인과 함께 목록 확인
dotnet tool list --outdated
도구 제거
dotnet tool uninstall docfx
모범 사례
1. 항상 isRoot: true 설정
MSBuild가 상위 디렉터리에서 도구 매니페스트를 검색하지 못하도록 방지합니다:
{
"version": 1,
"isRoot": true,
...
}
2. 정확한 버전 고정
재현 가능한 빌드를 위해 "rollForward": false를 사용하세요:
"docfx": {
"version": "2.78.3",
"rollForward": false
}
3. 사용 전 CI에서 복원
로컬 도구를 사용하기 전에 항상 dotnet tool restore를 실행하세요:
- run: dotnet tool restore
- run: dotnet docfx docs/docfx.json
4. 도구 요구 사항 문서화
README에 주석 또는 섹션을 추가하세요:
## 개발 환경 설정
1. 도구 복원: `dotnet tool restore`
2. 빌드: `dotnet build`
3. 테스트: `dotnet test`
5. 업데이트에 Dependabot 사용
# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: "nuget"
directory: "/"
schedule:
interval: "weekly"
# .config/dotnet-tools.json의 로컬 도구를 포함합니다.
문제 해결
복원 후 도구를 찾을 수 없음
리포지토리 루트에서 실행 중인지 확인하세요:
# 잘못된 경우 - 하위 디렉터리에서 실행
cd src/MyApp
dotnet docfx # 오류: 도구를 찾을 수 없음
# 올바른 경우 - 솔루션 루트에서 실행
cd ../..
dotnet docfx docs/docfx.json
버전 충돌
버전 충돌이 발생하면 다음을 확인하세요:
- 다른 버전의 전역 도구:
dotnet tool list -g - 여러 도구 매니페스트: 상위 디렉터리에서
.config/dotnet-tools.json찾기
도구 캐시 지우기
# NuGet 도구 캐시 지우기
dotnet nuget locals all --clear
# 도구 재복원
dotnet tool restore
예제: 완전한 개발 환경 설정
{
"version": 1,
"isRoot": true,
"tools": {
"docfx": {
"version": "2.78.3",
"commands": ["docfx"],
"rollForward": false
},
"dotnet-ef": {
"version": "9.0.0",
"commands": ["dotnet-ef"],
"rollForward": false
},
"dotnet-reportgenerator-globaltool": {
"version": "5.4.1",
"commands": ["reportgenerator"],
"rollForward": false
},
"csharpier": {
"version": "0.30.3",
"commands": ["dotnet-csharpier"],
"rollForward": false
},
"incrementalist.cmd": {
"version": "1.2.0",
"commands": ["incrementalist"],
"rollForward": false
}
}
}
개발 워크플로:
# 초기 설정
dotnet tool restore
# 커밋 전 코드 서식 지정
dotnet csharpier .
# 커버리지와 함께 테스트 실행
dotnet test --collect:"XPlat Code Coverage"
dotnet reportgenerator -reports:**/coverage.cobertura.xml -targetdir:coverage
# 문서 빌드
dotnet docfx docs/docfx.json
# 변경된 프로젝트 확인 (대규모 리포지토리용)
incrementalist --branch main