@gracefullight/validate-branch 1.0.1 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ko.md +470 -0
- package/README.md +131 -131
- package/dist/cli.js +41 -41
- package/dist/index.js +40 -40
- package/package.json +36 -19
- package/README.en.md +0 -470
package/README.ko.md
ADDED
|
@@ -0,0 +1,470 @@
|
|
|
1
|
+
# @gracefullight/validate-branch
|
|
2
|
+
|
|
3
|
+
> 커스텀 정규식을 지원하는 Git 브랜치 이름 유효성 검사 도구
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@gracefullight/validate-branch)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
[English](./README.md) | **한국어**
|
|
9
|
+
|
|
10
|
+
## 주요 기능
|
|
11
|
+
|
|
12
|
+
- **유연한 정규식 패턴** - 기본 패턴 또는 커스텀 정규식 사용
|
|
13
|
+
- **현재 브랜치 감지** - Git 저장소에서 현재 브랜치 이름 자동 감지
|
|
14
|
+
- **설정 파일 지원** - `branch.config.{ts,js,mjs}` 파일에서 패턴 로드
|
|
15
|
+
- **CLI 도구** - 명령줄에서 직접 사용 가능
|
|
16
|
+
- **상세한 오류 메시지** - 실패 시 명확한 오류 설명 제공
|
|
17
|
+
- **타입스크립트 지원** - 완전한 TypeScript 타입 정의
|
|
18
|
+
|
|
19
|
+
## 기본 패턴
|
|
20
|
+
|
|
21
|
+
기본적으로 다음 브랜치 이름이 허용됩니다:
|
|
22
|
+
|
|
23
|
+
- `main` / `master` - 메인 브랜치
|
|
24
|
+
- `develop` / `stage` - 개발/스테이지 브랜치
|
|
25
|
+
- `feature/.*` - 기능 브랜치 (예: `feature/login`, `feature/user-auth`)
|
|
26
|
+
- `fix/.*` - 버그 수정 브랜치 (예: `fix/memory-leak`, `fix/typo`)
|
|
27
|
+
- `hotfix/.*` - 핫픽스 브랜치 (예: `hotfix/critical-bug`)
|
|
28
|
+
- `release/.*` - 릴리스 브랜치 (예: `release/v1.0.0`)
|
|
29
|
+
|
|
30
|
+
## 설치
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# pnpm 사용
|
|
34
|
+
pnpm add @gracefullight/validate-branch
|
|
35
|
+
|
|
36
|
+
# npm 사용
|
|
37
|
+
npm install @gracefullight/validate-branch
|
|
38
|
+
|
|
39
|
+
# yarn 사용
|
|
40
|
+
yarn add @gracefullight/validate-branch
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## 사용법
|
|
44
|
+
|
|
45
|
+
### CLI 사용
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
# 현재 브랜치 검증
|
|
49
|
+
npx validate-branch
|
|
50
|
+
|
|
51
|
+
# 특정 브랜치 검증
|
|
52
|
+
npx validate-branch --test feature/new-feature
|
|
53
|
+
|
|
54
|
+
# 커스텀 정규식 사용
|
|
55
|
+
npx validate-branch --regexp "^(main|develop|feature/.+)$"
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### 프로그래밍 방식 사용
|
|
59
|
+
|
|
60
|
+
#### 기본 패턴으로 검증
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
import { validateBranchName, validateWithDetails } from "@gracefullight/validate-branch";
|
|
64
|
+
|
|
65
|
+
// 간단한 boolean 반환
|
|
66
|
+
const isValid = validateBranchName("feature/new-component");
|
|
67
|
+
console.log(isValid); // true
|
|
68
|
+
|
|
69
|
+
// 상세한 결과 반환
|
|
70
|
+
const result = validateWithDetails("feature/new-component");
|
|
71
|
+
console.log(result);
|
|
72
|
+
// { valid: true, branchName: "feature/new-component" }
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
#### 커스텀 정규식 사용
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
import { validateBranchName } from "@gracefullight/validate-branch";
|
|
79
|
+
|
|
80
|
+
const customPattern = "^(main|develop|story/.+|bugfix/.+)$";
|
|
81
|
+
const isValid = validateBranchName("story/US-123-add-user", { customRegexp: customPattern });
|
|
82
|
+
console.log(isValid); // true
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
#### 현재 브랜치 이름 가져오기
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
import { getCurrentBranchName } from "@gracefullight/validate-branch";
|
|
89
|
+
|
|
90
|
+
const currentBranch = await getCurrentBranchName();
|
|
91
|
+
console.log(currentBranch); // "feature/new-component" 또는 null
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
#### 설정 파일 로드
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
import { loadConfig } from "@gracefullight/validate-branch";
|
|
98
|
+
|
|
99
|
+
const config = await loadConfig();
|
|
100
|
+
console.log(config);
|
|
101
|
+
// {
|
|
102
|
+
// pattern: "^(main|develop|feature/.+)$",
|
|
103
|
+
// description: "프로젝트 브랜치 네이밍 규칙"
|
|
104
|
+
// }
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## 설정 파일
|
|
108
|
+
|
|
109
|
+
프로젝트 루트에 `branch.config.ts` 또는 `branch.config.js` 파일을 생성하여 커스텀 패턴을 정의하세요.
|
|
110
|
+
|
|
111
|
+
### TypeScript 설정 (`branch.config.ts`)
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
import type { Config } from "@gracefullight/validate-branch";
|
|
115
|
+
|
|
116
|
+
const config: Config = {
|
|
117
|
+
pattern: "^(main|develop|feature/.+|fix/.+|refactor/.+)$",
|
|
118
|
+
description: "프로젝트 브랜치 네이밍 규칙",
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
export default config;
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### JavaScript 설정 (`branch.config.js`)
|
|
125
|
+
|
|
126
|
+
```javascript
|
|
127
|
+
module.exports = {
|
|
128
|
+
pattern: "^(main|develop|feature/.+|fix/.+)$",
|
|
129
|
+
description: "프로젝트 브랜치 네이밍 규칙",
|
|
130
|
+
};
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### 프리셋 사용 (`branch.config.ts`)
|
|
134
|
+
|
|
135
|
+
커스텀 패턴 대신 내장 프리셋을 사용할 수 있습니다.
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
import type { Config } from "@gracefullight/validate-branch";
|
|
139
|
+
|
|
140
|
+
const config: Config = {
|
|
141
|
+
preset: "jira", // "gitflow" 또는 "jira"
|
|
142
|
+
description: "JIRA 티켓 기반 브랜치 네이밍",
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
export default config;
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**사용 가능한 프리셋:**
|
|
149
|
+
|
|
150
|
+
#### `gitflow` (기본값)
|
|
151
|
+
|
|
152
|
+
Git Flow 브랜치 전략을 따르는 패턴입니다.
|
|
153
|
+
|
|
154
|
+
| 상태 | 브랜치 예시 |
|
|
155
|
+
|------|------------|
|
|
156
|
+
| ✅ 허용 | `main`, `master`, `develop`, `stage` |
|
|
157
|
+
| ✅ 허용 | `feature/login`, `feature/user-auth`, `feature/add-payment` |
|
|
158
|
+
| ✅ 허용 | `fix/memory-leak`, `fix/typo`, `fix/null-pointer` |
|
|
159
|
+
| ✅ 허용 | `hotfix/critical-bug`, `hotfix/security-patch` |
|
|
160
|
+
| ✅ 허용 | `release/v1.0.0`, `release/2.3.1` |
|
|
161
|
+
| ❌ 거부 | `login`, `bugfix`, `my-branch` (prefix 없음) |
|
|
162
|
+
| ❌ 거부 | `feature/`, `fix/` (이름 없음) |
|
|
163
|
+
| ❌ 거부 | `Feature/Login`, `FIX/bug` (대문자 prefix) |
|
|
164
|
+
|
|
165
|
+
#### `jira`
|
|
166
|
+
|
|
167
|
+
JIRA 티켓 번호 기반 브랜치 패턴입니다.
|
|
168
|
+
|
|
169
|
+
| 상태 | 브랜치 예시 |
|
|
170
|
+
|------|------------|
|
|
171
|
+
| ✅ 허용 | `main`, `master`, `develop`, `stage` |
|
|
172
|
+
| ✅ 허용 | `FEATURE-123`, `FEATURE-1`, `FEATURE-99999` |
|
|
173
|
+
| ✅ 허용 | `BUG-456`, `STORY-789`, `TASK-101`, `HOTFIX-202` |
|
|
174
|
+
| ❌ 거부 | `feature/login` (gitflow 스타일) |
|
|
175
|
+
| ❌ 거부 | `FEATURE-ABC` (숫자 아님) |
|
|
176
|
+
| ❌ 거부 | `feature-123` (소문자) |
|
|
177
|
+
| ❌ 거부 | `JIRA-123/description` (슬래시 포함) |
|
|
178
|
+
|
|
179
|
+
## API 레퍼런스
|
|
180
|
+
|
|
181
|
+
### `validateBranchName(branchName, options?)`
|
|
182
|
+
|
|
183
|
+
브랜치 이름이 유효한지 확인합니다.
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
interface ValidateBranchNameOptions {
|
|
187
|
+
customRegexp?: string;
|
|
188
|
+
preset?: "gitflow" | "jira";
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
function validateBranchName(
|
|
192
|
+
branchName: string,
|
|
193
|
+
options?: ValidateBranchNameOptions
|
|
194
|
+
): boolean
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
**매개변수:**
|
|
198
|
+
- `branchName`: 검증할 브랜치 이름
|
|
199
|
+
- `options`: 선택사항, 검증 옵션 객체
|
|
200
|
+
- `customRegexp`: 커스텀 정규식 문자열
|
|
201
|
+
- `preset`: 프리셋 패턴 (`gitflow` 또는 `jira`, 기본값: `gitflow`)
|
|
202
|
+
|
|
203
|
+
**반환값:** 유효 여부
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
### `validateWithDetails(branchName, options?)`
|
|
208
|
+
|
|
209
|
+
상세한 검증 결과를 반환합니다.
|
|
210
|
+
|
|
211
|
+
```typescript
|
|
212
|
+
function validateWithDetails(
|
|
213
|
+
branchName: string,
|
|
214
|
+
options?: ValidateBranchNameOptions
|
|
215
|
+
): ValidationResult
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
**반환값:**
|
|
219
|
+
```typescript
|
|
220
|
+
{
|
|
221
|
+
valid: boolean;
|
|
222
|
+
branchName: string;
|
|
223
|
+
error?: string; // 실패 시 오류 메시지
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
**예시:**
|
|
228
|
+
```typescript
|
|
229
|
+
const result = validateWithDetails("invalid-branch");
|
|
230
|
+
// {
|
|
231
|
+
// valid: false,
|
|
232
|
+
// branchName: "invalid-branch",
|
|
233
|
+
// error: 'Branch name "invalid-branch" does not match pattern: /^(main|master|...)$/'
|
|
234
|
+
// }
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
### `getCurrentBranchName()`
|
|
240
|
+
|
|
241
|
+
현재 Git 브랜치 이름을 가져옵니다.
|
|
242
|
+
|
|
243
|
+
```typescript
|
|
244
|
+
function getCurrentBranchName(): Promise<string | null>
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
**반환값:** 현재 브랜치 이름, Git 저장소가 아닌 경우 `null`
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
### `loadConfig()`
|
|
252
|
+
|
|
253
|
+
프로젝트 설정 파일을 로드합니다.
|
|
254
|
+
|
|
255
|
+
```typescript
|
|
256
|
+
function loadConfig(): Promise<Config | null>
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
**설정 파일 탐색 순서:**
|
|
260
|
+
1. `branch.config.ts`
|
|
261
|
+
2. `branch.config.mts`
|
|
262
|
+
3. `branch.config.js`
|
|
263
|
+
4. `branch.config.cjs`
|
|
264
|
+
5. `branch.config.mjs`
|
|
265
|
+
|
|
266
|
+
**반환값:** 설정 객체 또는 설정 파일이 없는 경우 `null`
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
## 타입 정의
|
|
271
|
+
|
|
272
|
+
### `Config`
|
|
273
|
+
|
|
274
|
+
```typescript
|
|
275
|
+
interface Config {
|
|
276
|
+
pattern?: string; // 단일 정규식 패턴
|
|
277
|
+
patterns?: string[]; // 다중 정규식 패턴 (예정)
|
|
278
|
+
preset?: "gitflow" | "jira"; // 프리셋 패턴 (기본값: "gitflow")
|
|
279
|
+
description?: string; // 설정 설명
|
|
280
|
+
}
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### `ValidationResult`
|
|
284
|
+
|
|
285
|
+
```typescript
|
|
286
|
+
interface ValidationResult {
|
|
287
|
+
valid: boolean;
|
|
288
|
+
branchName: string;
|
|
289
|
+
error?: string;
|
|
290
|
+
}
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
## 예제
|
|
294
|
+
|
|
295
|
+
### Git Hooks와 함께 사용
|
|
296
|
+
|
|
297
|
+
#### `package.json`에서 husky 설정
|
|
298
|
+
|
|
299
|
+
```json
|
|
300
|
+
{
|
|
301
|
+
"husky": {
|
|
302
|
+
"hooks": {
|
|
303
|
+
"pre-commit": "validate-branch"
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
#### 직접 Git Hooks 사용
|
|
310
|
+
|
|
311
|
+
```bash
|
|
312
|
+
#!/bin/sh
|
|
313
|
+
# .git/hooks/pre-commit
|
|
314
|
+
|
|
315
|
+
npx validate-branch
|
|
316
|
+
if [ $? -ne 0 ]; then
|
|
317
|
+
echo "브랜치 이름이 규칙에 맞지 않습니다."
|
|
318
|
+
exit 1
|
|
319
|
+
fi
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### GitHub Actions와 함께 사용
|
|
323
|
+
|
|
324
|
+
```yaml
|
|
325
|
+
name: Branch Validation
|
|
326
|
+
|
|
327
|
+
on:
|
|
328
|
+
pull_request:
|
|
329
|
+
types: [opened, synchronize]
|
|
330
|
+
|
|
331
|
+
jobs:
|
|
332
|
+
validate-branch:
|
|
333
|
+
runs-on: ubuntu-latest
|
|
334
|
+
steps:
|
|
335
|
+
- uses: actions/checkout@v4
|
|
336
|
+
|
|
337
|
+
- name: Setup Node.js
|
|
338
|
+
uses: actions/setup-node@v4
|
|
339
|
+
with:
|
|
340
|
+
node-version: "20"
|
|
341
|
+
|
|
342
|
+
- name: Install validate-branch
|
|
343
|
+
run: npm install -g @gracefullight/validate-branch
|
|
344
|
+
|
|
345
|
+
- name: Validate branch name
|
|
346
|
+
run: validate-branch --test ${{ github.head_ref }}
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
### CI/CD 파이프라인에서 사용
|
|
350
|
+
|
|
351
|
+
```yaml
|
|
352
|
+
# .github/workflows/ci.yml
|
|
353
|
+
|
|
354
|
+
jobs:
|
|
355
|
+
test:
|
|
356
|
+
runs-on: ubuntu-latest
|
|
357
|
+
steps:
|
|
358
|
+
- name: Checkout
|
|
359
|
+
uses: actions/checkout@v4
|
|
360
|
+
|
|
361
|
+
- name: Validate branch name
|
|
362
|
+
run: npx validate-branch
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
### ESLint 플러그인과 함께 사용
|
|
366
|
+
|
|
367
|
+
```javascript
|
|
368
|
+
// .eslintrc.js
|
|
369
|
+
const { execSync } = require("child_process");
|
|
370
|
+
|
|
371
|
+
module.exports = {
|
|
372
|
+
// ... 기본 설정
|
|
373
|
+
rules: {
|
|
374
|
+
"custom/validate-branch": {
|
|
375
|
+
meta: {
|
|
376
|
+
type: "suggestion",
|
|
377
|
+
docs: {
|
|
378
|
+
description: "Validate git branch name",
|
|
379
|
+
},
|
|
380
|
+
},
|
|
381
|
+
create(context) {
|
|
382
|
+
return {
|
|
383
|
+
Program() {
|
|
384
|
+
const branch = execSync("git rev-parse --abbrev-ref HEAD", {
|
|
385
|
+
encoding: "utf-8",
|
|
386
|
+
}).trim();
|
|
387
|
+
|
|
388
|
+
const { validateBranchName } = require("@gracefullight/validate-branch");
|
|
389
|
+
|
|
390
|
+
if (!validateBranchName(branch)) {
|
|
391
|
+
context.report({
|
|
392
|
+
node: {},
|
|
393
|
+
message: `Invalid branch name: ${branch}`,
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
},
|
|
397
|
+
};
|
|
398
|
+
},
|
|
399
|
+
},
|
|
400
|
+
},
|
|
401
|
+
};
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
## 개발
|
|
405
|
+
|
|
406
|
+
### 설정
|
|
407
|
+
|
|
408
|
+
```bash
|
|
409
|
+
# 저장소 클론
|
|
410
|
+
git clone https://github.com/gracefullight/saju.git
|
|
411
|
+
cd packages/validate-branch
|
|
412
|
+
|
|
413
|
+
# 의존성 설치
|
|
414
|
+
pnpm install
|
|
415
|
+
|
|
416
|
+
# 빌드
|
|
417
|
+
pnpm build
|
|
418
|
+
|
|
419
|
+
# 테스트
|
|
420
|
+
pnpm test
|
|
421
|
+
|
|
422
|
+
# 린트
|
|
423
|
+
pnpm lint
|
|
424
|
+
|
|
425
|
+
# 포맷
|
|
426
|
+
pnpm lint:fix
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
### 로컬에서 CLI 테스트
|
|
430
|
+
|
|
431
|
+
```bash
|
|
432
|
+
# 빌드 후 로컬에서 CLI 테스트
|
|
433
|
+
node bin/validate-branch.js --test feature/new-feature
|
|
434
|
+
|
|
435
|
+
# 커스텀 패턴 테스트
|
|
436
|
+
node bin/validate-branch.js --test invalid-name --regexp "^(main|develop)$"
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
## 기여하기
|
|
440
|
+
|
|
441
|
+
기여를 환영합니다! Pull Request를 자유롭게 제출해주세요.
|
|
442
|
+
|
|
443
|
+
1. 저장소 포크
|
|
444
|
+
2. feature 브랜치 생성 (`git checkout -b feature/amazing-feature`)
|
|
445
|
+
3. 변경사항 커밋 (`git commit -m 'Add some amazing feature'`)
|
|
446
|
+
4. 브랜치에 푸시 (`git push origin feature/amazing-feature`)
|
|
447
|
+
5. Pull Request 오픈
|
|
448
|
+
|
|
449
|
+
### 가이드라인
|
|
450
|
+
|
|
451
|
+
- 새 기능에 대한 테스트 작성
|
|
452
|
+
- 코드 커버리지 유지 또는 개선
|
|
453
|
+
- 기존 코드 스타일 따르기 (Biome으로 강제)
|
|
454
|
+
- 필요에 따라 문서 업데이트
|
|
455
|
+
|
|
456
|
+
## 라이선스
|
|
457
|
+
|
|
458
|
+
MIT © [gracefullight](https://github.com/gracefullight)
|
|
459
|
+
|
|
460
|
+
## 관련 프로젝트
|
|
461
|
+
|
|
462
|
+
- [isomorphic-git](https://isomorphic-git.org/) - Git 구현 라이브러리
|
|
463
|
+
- [Commander.js](https://commander.js/) - Node.js CLI 프레임워크
|
|
464
|
+
- [Chalk](https://chalk.js.org/) - 터미널 문자열 스타일링
|
|
465
|
+
|
|
466
|
+
## 지원
|
|
467
|
+
|
|
468
|
+
- [문서](https://github.com/gracefullight/saju#readme)
|
|
469
|
+
- [이슈 트래커](https://github.com/gracefullight/saju/issues)
|
|
470
|
+
- [토론](https://github.com/gracefullight/saju/discussions)
|