refactor(view): processMessage 함수 공통화 및 리팩토링#938
Conversation
… text and issue references - Supports 'githru#123', '(githru#123)', and '[githru#123]' - Preserves original spacing by extracting surrounding whitespace from the commit message
…Content - Extract shared helper for issue-linked rendering (renderIssueLinkedNodes) - Unify IssueLinkedMessage type across components - Switch derived computations from useEffect to useMemo to avoid extra renders
…link to github-issue-link
chae-dahee
left a comment
There was a problem hiding this comment.
LGTM!!!
테스트코드가 너무 잘 작성되어있네요~ PR 문서와 함께 봐서 이해하기 좋았습니다! 고생하셨습니다 👍
| const issueLinkedMessage: IssueLinkedMessage = useMemo(() => { | ||
| const message = commitNodeListInCluster?.[0]?.commit?.message; | ||
| if (!message) return { title: [], body: null }; | ||
|
|
||
| parts.push( | ||
| <GithubIssueLink | ||
| key={`issue-${issueNumber}-${match.index}`} | ||
| owner={owner} | ||
| repo={repo} | ||
| issueNumber={issueNumber} | ||
| /> | ||
| ); | ||
| const [title, ...rest] = message.split("\n"); | ||
| const body = rest.filter((line) => line.trim()).join("\n"); | ||
|
|
||
| lastIndex = match.index + match[0].length; | ||
| } | ||
|
|
||
| // 마지막 부분 추가 | ||
| if (lastIndex < message.length) { | ||
| parts.push(message.slice(lastIndex)); | ||
| } | ||
|
|
||
| return parts.length > 0 ? parts : [message]; | ||
| return { | ||
| title: renderIssueLinkedNodes(title, owner, repo), | ||
| body: body ? renderIssueLinkedNodes(body, owner, repo) : null, | ||
| }; | ||
|
|
||
| if (commitNodeListInCluster?.[0]?.commit?.message) { | ||
| const { message } = commitNodeListInCluster[0].commit; | ||
| const messageLines = message.split("\n"); | ||
| const title = messageLines[0]; | ||
| const body = messageLines | ||
| .slice(1) | ||
| .filter((line: string) => line.trim()) | ||
| .join("\n"); | ||
|
|
||
| // 제목과 본문을 각각 처리 | ||
| const processedTitle = processMessage(title); | ||
| const processedBody = body ? processMessage(body) : null; | ||
|
|
||
| setLinkedMessage({ | ||
| title: processedTitle, | ||
| body: processedBody, | ||
| }); | ||
| } |
There was a problem hiding this comment.
로직 분리와 useMemo 를 통해 코드가 훨신 깔끔해진게 직관적으로 보입니다. 너무 좋네요~~ 👍 👍
| for (;;) { | ||
| const match = GITHUB_ISSUE_REGEX.exec(message); | ||
| if (!match) break; |
There was a problem hiding this comment.
오! 이 방식으로도 조건없는 반복문을 표현할 수 있군요..!!
There was a problem hiding this comment.
(사소) 이런 표현도 좋긴 한데, 명확하게 loop를 exit하는 condition을 기술할 수 있는 방법도 좋은 것 같습니다.
코드 보는 사람이 break가 어디있는지 loop문을 다 훑지 않아도 어떤 조건일 때 계속 도는지 바로 확인할 수 있으니까요!
ytaek
left a comment
There was a problem hiding this comment.
아 코드 깔끔하게 넘 좋습니다!! 이제 리팩토링 장인이 되신 듯!! 👍👍👍👍👍
| ["fix: 500 on null (", "#10", ") and [", "#20", "], also ", "#30"], | ||
| ["#10", "#20", "#30"], | ||
| ], | ||
| ] as const satisfies readonly IssueRefSplitCase[]; |
| issueParts.forEach((part) => expect(message.slice(part.index, part.index + part.value.length)).toBe(part.value)); | ||
| }); | ||
|
|
||
| it("remains stateless across calls", () => { |
There was a problem hiding this comment.
추후에 negative Test case도 한번 만들어보시면 좋을 것 같습니다.
경계값 테스 등 두요!
| for (;;) { | ||
| const match = GITHUB_ISSUE_REGEX.exec(message); | ||
| if (!match) break; |
There was a problem hiding this comment.
(사소) 이런 표현도 좋긴 한데, 명확하게 loop를 exit하는 condition을 기술할 수 있는 방법도 좋은 것 같습니다.
코드 보는 사람이 break가 어디있는지 loop문을 다 훑지 않아도 어떤 조건일 때 계속 도는지 바로 확인할 수 있으니까요!
Related issue
#900
Result
Detail.tsx,Content.tsx에 중복되어 있던 커밋 메시지 파싱/이슈 링크 렌더링 로직을 공통 유틸과 헬퍼로 분리하는 리팩토링 작업을 진행했습니다.Work list
1. 커밋 메시지 분리 유틸 함수 추가
splitMessageByIssueRefs (
src/utils/commitMessage.ts)processMessage함수 로직을 공통 유틸로 분리-> 한 번의 스캔으로 메시지를 분리하기 위함. 세부 단계로 나누면 각 단계에서 문자열을 분리/탐색하고 재조립하는 과정에서 중복 탐색이나 불필요한 메모리 할당이 발생할 수 있음. 단일 함수에서 커서 기반으로 처리
2. 파싱 오류 수정 / 기능 보강
(#123),[#123]과 같은 패턴도 정확히 매칭하여 링크로 치환할 수 있도록 수정e.g. "Merge pull request #921 from user/main" -> ["Merge pull request", "#921" "from user/main"] -> "Merge pull request#921from user/main"
e.g. "Merge pull request #921 from user/main" -> ["Merge pull request ", "#921" " from user/main"] -> "Merge pull request #921 from user/main"
(전)

(후)

3. splitMessageByIssueRefs 단위 테스트 추가
4. Detail, Content 컴포넌트 리팩토링
renderIssueLinkedNodes공용 렌더 헬퍼 추출GithubIssueLink로 렌더하는 로직 분리useMemo로 전환linkedMessge->issueLinkedMessage로 이름 변경5. 이전 PR 피드백 반영
Related issue: #921
GithubIssueLink컴포넌트 내 css 클래스명 변경commit-message__issue-link->github-issue-link