1만 시간 프로그래밍 회고

작가님의 허락을 받고 번역한 글입니다.(원문)

이 글은 원래 무료 일보 "스타트업과 공학" 에서 소개된 글입니다.
여기서 구독하실 수 있습니다.

어떤 기술이든 전세계적으로 전문적인 성취의 핵심은 제대로된 방식으로 1만 시간 동안 연습하는 것입니다. - Malcom Gladwell in Outsiders

음.. 저는 전세계적인 전문가는 아닙니다. 하지만 꾸준히 프로그래밍에 1만 시간을 쏟아부었습니다. 아래는 제 경험으로부터 얻은 프로그래밍 고찰 31가지 입니다.

이 회고들은 오직 프로그래밍에 관한 것입니다. "프로그래밍은 사람에 관한 것이다"라거나 "시니어 테크 리드가 되는 법"으로 오해하시면 안됩니다.

이 고찰들은 단지 1만 시간 코드 작성에 꾸준히 임했을 때 얻은 것들입니다. 대부분의 초보자들에게 적용되지 않을 수 있습니다. 이 글은 커리어 상담이 아닙니다. 좋은 밴드 멤버가 되는 것이 아닌, 기술적인 기타리스트가 되는 방법 정도로 생각해 주시기 바랍니다. 이것들은 여러분이 더 나은 프로그래머가 되는 법에 관한 것입니다.

  1. 출처나 원리를 찾는 것이 스택오버플로우 답변을 찾는 것보다 거의 항상 빠릅니다.
  2. 대부분의 경우, 여러분이 겪고 있는 문제는 인터넷에 답이 없습니다. 그것은 여러분의 문제가 정말 어렵거나 중요하거나 둘다일 경우를 의미합니다.
  3. 할 수 있는 한 코드를 많이 지우시기 바랍니다.
  4. Syntactic sugar(가독성만을 위한 구문)은 보통 좋지 않습니다.
  5. 단순함이 가장 어렵습니다.
  6. 도구의 다양성을 넓히고, 일에 위해 어떤 것을 사용해야할 지 아시기 바랍니다.
  7. Git이나 bash와 같이 가장 많이 사용하는 것의 내부를 아셔야 합니다. (저는 대부분 꼬인 git rebase나 merge를 벗어날 수 있습니다.)
  8. 반복 작업에 대해서는 꼭 툴을 만드는게 좋습니다.. 여러분이 스스로 만든 툴보다 빠른 것은 없습니다.
  9. 배움은 최고에게서만. 그래서 저는 Go를 배울 때, standard library를 읽었습니다.
  10. 못생겨보인다면, 대부분 끔찍한 실수를 저지른 것입니다.
  11. Docstring이 아닌 주석을 써야만 한다면, 아마 리팩토링해야할 겁니다. 주석이 늘어날 때마다, 가능성이 증가합니다.
  12. 실제 서비스에서 프로그램이 어떻게 동작하는지 모른다면, 그 프로그램을 모르는 것입니다. 제 경험 상, 최고의 엔지니어는 모든 환경에서 그들의 프로그램이 어떻게 동작할지 알고 있습니다.
  13. 위 규칙은 파이프라인을 제작할 때도 적용됩니다.
  14. 다른 사람들의 코드를 열심히 사용하시기 바랍니다.
  15. 추론: 대부분의 코드들은 끔찍할 것입니다. 때때로, 더 나은 버전을 짜는게 더 쉬울 수 있습니다.
  16. 경험에 따르면, 재작성하고 있는 작은 라이브러리 혹은 작아야 하는 큰 라이브러리에서 직접 의존성은 좋지 않습니다.
  17. 언제 규칙을 깨야하는지 아셔야합니다. 반복하지 말라는 규칙에 대해서 말하자면, 때때로는 약간의 반복이 디펜던시보다 좋을 수도 있습니다.
  18. 코드를 모듈이나 패키지, 함수로 만드는 것은 중요합니다. API의 경계가 구체화되는 곳은 예술이라는 것을 아셔야 합니다.
  19. 가장 효율적인 도구를 고르되, 여러분이 알고 있는 도구도 고릅시다. 아크 리눅스는 현대 개발자들에게 가장 효율적인 운영체제입니까? 저에게는 그렇지만 대부분은 아닙니다. Acme를 써야합니까? 여러분이 Rob Pike라면
  20. 순환 복잡성은 피해야합니다. 주니어 개발자들은 너무 늦을 때까지 디펜던시 그래프가 얽힌 것을 알아차리지 못합니다.
  21. 깊은 중첩 조건은 피해야 합니다. Naming 컨벤션과, 조건 테스트에 대한 상식을 가져야합니다.
  22. 변수 이름은 똑바로 만들어야 합니다. 예술적으로다가 제대로
  23. 흔치는 않지만, 컴파일러가 문제인 경우도 있습니다. 그렇지 않으면 항상 DNS 문제입니다.
  24. 난해한 언어의 기능은 최소화하고, 쓰기로 되어 있는 경우에만 사용해야합니다. 그게 포인트 입니다.
  25. 기술은 동일하게 퍼지지 않습니다. 예를 들면, 저수준 엔지니어로부터 프론트엔드 개발자가 배울 것은 굉장히 많습니다. (특히, 모든 것은 컴파일 되었다는 것). 26. 비슷하게, 자바스크립트 개발자들은 클라우드 엔지니어에게 UX와 사용성 기능에 대해 가르쳐줄 수 있습니다.
  26. 결과적으로 다른 종류의 엔지니어는 세계를 다르게 봅니다.
  27. 어떤 개발자들은 다른 사람들보다 10배 더 효율적입니다. 제가 1인분도 못해본적도 있고, 10인분 한적도 있어서 알고 있습니다.
  28. 10인분 개발자와 10인분 직원 사이에는 상관관계가 없습니다.
  29. 좋은 API들은 사용하기 쉽고, 오용하기 어렵습니다. 설정 사이클은 하드코딩된 값에서부터 환경 변수, CLI 플래그, 설정 파일, DSL, 일반적인 bash 스크립트, 그리고 다시 하드코딩된 값으로 이동합니다. Heptagon of Configuration에서 어디에 위치하고 있는지 확인하시기 바랍니다.
  30. 모든 계층에서 추상화는 좋습니다. 벽에 달려들고 싶다면, 때때로 정답은 아래 수준의 추상화로 가면 됩니다. 여러분은 겉표면에 갇히지 않았습니다.

어디에 1만 시간을 쏟았습니까? 저는 프로그래밍을 15년 했습니다. 최근, 저는 구글 쿠버네티스 그리고 블랙스톤이라는 사모펀드에서 전문 개발자로 일하고 있습니다. 그 전에는 대학교에서 수학 증명 대신 내 프로젝트를 위한 프로그램을 짰습니다. 그 전에는, 모든 종류의 것들은 해킹했습니다. RuneScape에서 봇넷도 운영하고, 아이폰에 라틴어 번역 앱도 만들기도 했습니다.

1만 시간동안 무엇을 했습니까? 가장 최근일은 분산 시스템이었습니다. 스택을 넘나드는 코드를 짰습니다. 언어는 PHP, JavaScript, Go, Ruby, Python, C#, Java, Swift. 프론트엔드, 백엔드, 모바일, 커널, 클라우드, 데브옵스 등 저는 쿠버네티스같은 오픈소스 프로젝트에서 거대한 스케일에서 일해봤고, 작은 프로젝트를 운영했습니다. 이를 통해 최고의 엔지니어에게 내 코드를 리뷰받을 수 있었습니다.

내가 원했던 git rebase 입문

작가님의 허락을 받고 번역한 글입니다.(원문)

초보 개발자 시절, 제게 가장 중요하고도 어려웠던 git 기능은 rebasing 이었습니다. 지금와서 돌이켜보면, 깔끔한 초보자용 입문서를 찾는 것은 어려운 문제가 아니었습니다. 이 글은 과거의 저 그리고 저와 같은 미래를 꿈꾸는 개발자를 위한 것입니다.

과거의 저에게 해주고 싶은 또 다른 작은 조언은 Jekyll을 활용해서 개인 사이트를 만들라는 것입니다. 워드프레스 사이트 호스팅하느라 안그래도 부족한 용돈을 낭비하지 마세요.

어쨌든 즐겨주시기 바랍니다. 이 글 읽으려면 git과 버전 컨트롤에 대한 기본적인 지식을 가지고 있어야 합니다. 왜 그런지는 읽어보면 알겁니다.

첫번째, 왜 rebase를 해야할까?

온라인에서 Cupid의 컵케익이라는 컵케익 가게를 시작하게된 주니어 개발자가 있다고 가정해봅시다. 이 가게는 온라인 판매로 엄청난 실적을 올리고 있고, 베테랑 개발자를 많이 보유하고 있습니다. 여러분은 프론트엔드를 주로 맡아 일하게 되었습니다.

여러분의 첫 업무는 카드 컴포넌트를 업데이트하는 것이었습니다. 사람들이 구매할 컵 케이크를 찾을 때, 각 컵케이크는 이 카드 모음 안에 있습니다. 저장소에서 가장 최근 master 브랜치 버전을 가져오고, 새로운 브랜치를 만들어 일을 시작합니다.

몇몇 커밋 이후에 모든 것을 완료할 수 있었습니다. 카드는 더 예뻐졌고, 모든 테스트도 통과했습니다. 심지어 모바일 레이아웃도 개선시켰습니다. 남은 것은 실제 라이브 서비스에 업데이트 되도록, 당신의 기능 브랜치를 마스터 브랜치로 병합시키는 것입니다.

하지만 멈춰야합니다!

왜냐하면 당신이 카드 컴포넌트를 만드는 동안 다른 사람들이 해당 사이트에서 작업을 할 수 있기 때문입니다.

  • 한 개발자는 네비게이션바를 변경했습니다.
  • 다른 한명은 불필요한 정보를 삭제하기 위해 데이터베이스 필드를 변경했습니다.
  • 또 다른 사람은 각 컵케이크에 대한 추가 정보를 덧붙였습니다.
  • 누군가는 아무도 모르게 가게의 은행 기록을 변경하여 돈을 횡령했습니다.

이 모든 변화는 우려와 고민을 불러일으킵니다. 당신이 만든 것에 영향력이 있거나 겹치는 변경사항이 누군가에 의해 병합된다면, 이것은 컵케이크 웹사이트에 버그를 발생시킬 수 있습니다. 변경사항의 차이를 보면, 버그 한개 정도는 보일 겁니다. 어떻게 하면 충돌이나 다른 사람들의 작업을 놓치지 않으면서, 여러분의 작업을 병합할 수 있을까요?

이런 상황이 여러분이 rebase를 해야하는 전형적인 경우입니다.

rebase는 뭘까?

여러분이 마스터 브랜치에서 새로운 브랜치를 만들었다고 가정해봅시다. 그 마스터 브랜치에는 커밋 1번이 있습니다. 여러분의 브랜치에서 발생하는 모든 커밋은 1번 커밋의 위에 있습니다. 여러분의 브랜치를 병합할 준비가 되었을 때 보니, 가장 최근 커밋이 5번 커밋인 것을 발견하게 됩니다.

Rebase는 여러분의 브랜치에 있는 모든 커밋을 받아들이고, 그 커밋들을 1 번 커밋이 아니라 5번 커밋 위에 추가하는 작업입니다. 만약 여러분이 1번 커밋이 여러분 브랜치의 베이스라고 생각하고 있ㄷ면, 그 베이스가 가장 최근 것인 5번 커밋으로 변경된다고 보면 됩니다. 그래서 rebase라고 불리는 겁니다.

AA

rebase를 하는 방법

여러분은 Cupid 컵케잌을 위한 훌륭한 카드 컴포넌트를 가지고 있습니다. 이제 여러분은 rebase가 무엇인지 알게 되었습니다. 이제 어떻게 해야할지 더 자세히 알아봅시다.

먼저, 여러분이 rebase할 브랜치가 최신 버전인지 확인해야 합니다. 이 예제에서는 마스터 브랜치라고 가정하겠습니다. git checkout master그리고 git pull을 차례로 실행시켜 최신 버전을 가져옵니다. 그리고 나서 git checkout updated-card을 실행시켜 여러분의 브랜치로 다시 체크아웃합니다.

직관적인 rebase는 꽤 간단한 명령어 구조를 가지고 있습니다: git rebase <branch>. branch는 여러분이 rebase할 _목적지 브랜치_입니다. 여기서는 git rebase master를 실행시키면 됩니다. 만약 충돌이 없다면, 이것으로 rebase 작업이 끝납니다.

Rebase 자체는 기술적으로 저장소의 커밋 기록을 재작성해서, 여러분의 이전 커밋을 삭제하고 동일한 커밋을 새로 만드는 겁니다. 이건 원격 저장소에 rebase할 때 추가적으로 무언가 필요하다는 것을 의미합니다. git push --force를 사용하면 잘 수행됩니다. 하지만 더 안전한 옵션은 git push --force-with-lease입니다. 후자는 여러분에게 알지 못했던 upstream 변화를 경고하고 push를 방지합니다. 이렇게 하면 다른 사람의 작업을 덮어쓰는 것을 피할 수 있어 좀 더 안전하게 작업할 수 있습니다.

이것으로 여러분의 rebase는 다 끝났습니다. 하지만, rebase 작업들은 항상 원활하게 진행되지는 않습니다.

rebase 충돌은 어떻게 처리합니까?

다른 사람의 작업과 여러분의 새로운 카드 작업이 충돌할 것을 걱정했던게 기억나십니까? 바로 이 상황이 rebase 충돌 상황입니다. 한 개발자가 새 컵 케이크 카드에 칼로리와 같은 새로운 정보를 추가했습니다. 양쪽에서 업데이트된 마크업들은 같은 라인에 변경사항이 있습니다. 이것은 rebase가 자동으로 일어날 수 없다는 것을 의미합니다. Git은 어느 부분의 변경사항을 유지하고 제거할지 알 수 없습니다. 그래서 개발자가 꼭 해결해야합니다.

다행히, git은 이 작업을 쉽게 할 수 있도록 도와줍니다. Rebase를 하는 동안, git은 각 커밋을 새로운 베이스에 따라 하나씩 추가합니다. 만약 특정 라인에서 서로 다른 두 커밋이 충돌을 하게 되면, rebase를 중단하고, 해당 부분 충돌이 해결되었을 때 다시 시작합니다.

이전에 병합 충돌을 해결해본 경험이 있다면, rebase 충돌은 그와 동일한 방식으로 다루어질 것입니다. git status를 실행하는 것은 어디에 충돌이 있는지 알려줄 것입니다. 그리고 충돌이 발생하는 부분의 코드는 여러분이 어떻게 고칠지 정할 수 있게 한 눈에 볼 수 있습니다.

모든 충돌이 해결되면, 일반적인 병합 충돌처럼 변경사항을 addcommit 하면 됩니다. 그러면 git rebase --continue를 실행하여 git이 나머지 커밋을 rebase할 수 있습니다. 추후에도 충돌이 발생한다면 잠시 일시 정지를 하게 됩니다. 그리고 마찬가지로 충돌이 해결이 되었을 때, push --force-with-lease를 하면 됩니다.

rebase에는 많이 사용하지 않지만 두 가지 옵션이 있습니다. 하나는 git rebase --abort입니다. 이는 rebase를 시작하기 전으로 되돌아가고자 할 때 사용하는 옵션입니다. 예상치 못한 충돌이 일어나 결정을 제때 내릴 수 없을 때 유용합니다. 또 다른 하나는 git rebase --skip입니다. 충돌을 일으키는 커밋들을 완전히 건너뛰는 기능입니다. 불필요한 커밋이 아니고, 만사가 귀찮지 안하다면, 많이 사용하지는 않을 것입니다.

rebase 프로세스를 추가적으로 제어할 수 있나요?

보셨듯이, git rebase는 강력합니다. 유명한 사람들이 말하듯, 더 강력한 힘은 더 큰 책임을 요구합니다. 감사하게도, 여러분은 rebase의 프로세스를 넘어 더 많은 것을 제어할 수 있습니다.

그렇게 하기 위해서는 --interactive, 혹은 -i 플래그를 명령어 안에 포함시키면 됩니다. 앞선 컵 케잌 rebase의 경우에 적용해보면, git rebase -i master이 됩니다.

이것은 rebase하려는 모든 커밋들의 목록을 보여줍니다. 어떤 것을 멈추고 수정할지 그리고 어떤 것을 건너뛰고 혹은 병합할지 결정할 수 있습ㄴ니다. 이것에 대해서 여기서는 더 이상 자세히 다루지는 않겠습니다. 관심이 있으시면 이 글이 더 나아가는데 좋은 시작점이 될 겁니다.

다만, 모든 것은 vim 인터페이스를 통해 이루어진다는 점을 유의하시면 되겠습니다. Rebase를 실행시키기 위해서는, esc + : + w + q + enter를 입력하시면 됩니다. VIM의 나머지 부분 설명은 다른 분께 부탁드리도록 하겠습니다.

마지막, 유용한 rebase 트릭: autosquashing!

대화형 rebase에서 하나 유용한 트릭이 있다면, autosquashing commit을 소개할 수 있을 것 같습니다. 이것은 두 커밋을 함께 병합하고, 새로우 ㄴ이름으로 바꿉니다. 만약에 크기는 작지만 개수가 많은 유사 커밋들이 결합되어 있거나, 오래된 커밋을 수정할 필요가 있을 경우, 굉장히 유용합니다. Rebasing은 이런 상황을 "autosquash"로 아주 쉽게 만들어 줍니다.

Cupid Cupcake의 새 카드를 위한 브랜치에 5개의 커밋이 있다고 가정해봅시다. 그런 다음 우리가 2번째 커밋에서 작은 세부사항을 놓친 것을 깨달았다고 칩시다. 만약 커밋 기록을 깨끗하게 유지하고 싶다면, 이 변경사항들을 두번째 커밋에 병합할 필요가 있습니다.

이 작업은 fixup 커밋을 활용하여 할 수 있습니다. 이렇게요:

  1. 변경사항을 만들고, stage 단계로 만듭니다.
  2. 합쳐버리고 싶은 커밋들의 아이디를 구해옵니다. 여기서는 123456ABCD라고 하겠습니다. 커밋 아이디는 git log명령어를 실행시켜서 찾으실 수 있습니다.
  3. Fixup 커밋을 위한 공식은 다음과 같습니다. git commit --fixup <commitID>. 우리의 경우에는 git commit --fixup 123456ABCD를 사용하면 됩니다. 이것은 변경사항을 일반적으로 커밋합니다. 하지만 이름은 두번째 커밋과 동일하게 됩니다.
  4. 다음으로 rebase를 실행시킬 겁니다. 중요한 것은 제대로 된 매개 변수르 ㄹ포함시켜야 한다는 것입니다. git rebase -i autosquash master를 실행시킵니다.
  5. VIM 인터페이스에 모든 커밋이 나열되어 있는, 대화형 rebase를 위한 일반적인 페이지를 보게 되실 겁니다. 하지만 우리의 fixup 커밋은 자동으로 병합되어 우리의 두번째 커밋 바로 밑에 있습니다.
  6. Rebase를 실행하시면, 커밋들은 자동으로 결합됩니다. 만약 충돌이 있다면, 일반적인 병합 충돌처럼 해결을 요청할 겁니다. 그리곤 계속됩니다.

이 기능은 지루하고 헷갈리게 만드는 수많은 작은 수정들이 기록을 지저분하게 만드는 것을 막는데 굉장히 유용합니다. 최고의 커밋 기록은 이해할 수 있는 이야기를 말해줍니다. Autosquashing은 아주 불쾌한 주석에 의해 압도당하는 것을 방지해줍니다. 활용해보십시오.

컵케익을 즐기십시오!

이 글이 git rebasing의 기초와 용도, 사용법, 접근법을 설명하는데 도움이 되었길 바랍니다. 마침내 rebase를 스스로 이해했을 때, rebase는 자주 사용하고 필수적인 도구가 되었습니다. 다른 주니어 개발자들이 좌절감이나 패닉을 겪지 않고 똑같이 잘 할 수 있기를 바랍니다.

결국, 더 많은 사람들이 컴케잌을 사먹는걸 돕는게 우리가 원하는 거 아니겠습니까? 물론입니다. Git rebasing은 모든 좋은 것들과 같이 그 목표를 현실로 만들어 주는 것입니다.

AA

충분한 설명이 있는 커밋 메시지 작성하기

작가님의 허락을 받고 번역한 글입니다.(원문)

소개

이렇게 커밋 하십니까?

0-bad-example

이러면 안됩니다! 혼자 개발을 하고, 커밋을 읽을 사람이 없다고 하더라도, 여러분은 결국 3개월 지난 프로젝트를 읽지 못하게 될 겁니다.

"XX 기능을 더했었나?", "내가 햄버거 메뉴 버그를 고쳤었나?"

이렇게 해서는 코드를 확인해보기 전까지는 어떤 것을 더했고, 어떤 버그를 수정했는지 알 수 없습니다. 여러분이 팀과 협업한다고 생각해봅시다. 10개의 커밋을 리뷰해야하는데, 그 커밋 메시지가 충분한 설명을 주지 않는다면, 커밋 10개의 코드를 전부 읽어야 할 것입니다.

1단계: 충분히 묘사된 커밋 메시지

커밋 메시지의 가이드라인에서는 "커밋 메시지는 그것을 읽는 것만으로도 최소한 무슨 작업을 했는지 알수 있어야 한다. "라는 항목이 있습니다. 또한 일반적으로 명령형 문장과 현재 시제를 사용을 요구하고 있습니다.

예를 들면:

  • change aspect ratio for company profile video
  • add hamburger menu for mobile
  • remove unused imports
  • fix hamburger menu not opening on mobile
  • add test for helper functions
  • refactor remove todo logic
  • add documentation on hamburger menu
  • install react-icons

이렇게 하면 코드 변경 사항을 보지 않더라도 일반적으로 어떤 작업을 했는지 알 수 있습니다.

충분한 설명이 있는 커밋 메시지 작성에 10초 투자함으로써, 미래에 코드 변경 사항을 봐야하는 몇분을 아낄 수 있습니다.


2단계: 그룹화

코드 리뷰나, 오래된 프로젝트를 재활용하고자 할 때, 충분한 설명이 있는 커밋 메시지가 많은 도움이 된다는 것을 배웠습니다.

지금 배운 방법으로는 커밋 메시지를 보며 어떤 작업을 했는지 추측해볼 수 있습니다. 하지만 전체 문장을 읽어야만 기능을 추가한 건지, 삭제한 건지, 버그를 수정한 건지, 패키지를 설치한 건지 알 수 있는 단점이 있습니다. 첫 번째 단어만으로 커밋의 기능을 알 수 있다면 더 좋지 않습니까? 이모티콘을 사용하여 차별화하는 것을 좋아하는 사람들도 있습니다. 원한다면 해도 되지만 저는 하지 않는 것을 권합니다.

이와 관련된 수많은 컨벤션들이 있으며, 저는 주로 Conventional Commit을 활용합니다. 제가 세부 사항(대문자를 써야 하나 말아야 하나, 과거형을 써야 하나, 현재형을 써야 하나, 마침표를 써야 하나 말아야 하나 등)을 추후에 알려드리겠습니다. 그룹화 단계에서는 Conventional Commit을 따릅니다.

아래는 카테고리(아래 예시는 일부분으로 필요에 따라 카테고리를 추가하셔도 됩니다.)입니다.:

  • feat, 기능의 추가 혹은 삭제
  • fix, 버그 수정
  • chore, 패키지 설치 등
  • test, 테스트 케이스 추가
  • refactor, 기능은 수정하지 않았지만, 코드를 리팩토링 했을 때
  • style, 코드의 순서를 바꾸거나, 들여쓰기, 사용하지 않는 패키지 정리 등을 할 때

아래는 위 카테고리를 적용한 예시입니다.:

  • feat change aspect ratio for company profile video
  • feat add hamburger menu for mobile
  • style remove unused imports
  • fix hamburger menu not opening on mobile
  • test add test for helper functions
  • refactor remove todo logic
  • docs add documentation on hamburger menu
  • chore install react-icons

이런 식으로 커밋을 차별화하면 좀 더 효과적인 설명이 될 수 있습니다. 커밋을 훑어보면서 찾고자 하는 카테고리를 찾을 수 있기 때문입니다.


3단계: Changelog 생성

여러분이 NPM 패키지를 만든다고 해봅시다. 그러면 여러분의 유저들이 변경 사항을 알기 위해서는 Changelog를 만들 필요가 있을 겁니다. changelog를 만들기 위해서 여러분의 git log를 찾아보고, feat과 fix 카테고리에 있는 커밋 메시지를 복사할 수 있습니다. 이 두가지 카테고리는 changelog를 만들 때 가장 많이 쓰입니다. 왜냐하면 유저들은 사용하지 않는 라이브러리나, 세미콜론을 더했는지 등을 알 필요가 없기 때문입니다.

추신: 일반적인 프로젝트를 할 때, 원한다면 더 많은 카테고리를 changelog에 추가할 수 있습니다.

두가지 카테고리의 커밋들을 일일이 선정하는 것은 고되고, 아무도 하고 싶어하지 않는 일입니다. 그렇기 때문에 changelog를 만들기 위해서 standard-version을 사용하면 좋습니다.

1-standard-version

단순히 이 명령어를 실행시키면, 자동으로 버전을 만들어내고, changelog, 커밋을 생성하며, 태그가 추가됩니다.

1-standard-version

위 이미지는 커밋만으로 생성된 보고서입니다. 우리가 포함을 원하는 카테고리를 지정할 수도 있습니다.

하지만 standard-version과 같은 자동 생성 패키지를 사용하는 것은 단점이 하나 있습니다. standard-verion 프로그램에서 제공하는 규칙을 따라야 한다는 것 입니다.


4단계: Conventional Commits

Conventional Commits는 사람과 기계가 읽을 수 있는 커밋 메시지를 위한 설명서입니다.

여기서 가이드를 읽어봅시다.

이 규칙은 커밋 메시지의 가독성을 향상 시키고 changelog를 자동 생성하는데 도움이 됩니다. 저는 일반적으로 readme 파일에 이 내용을 적어둬서 다른 사람들이 따라할 수 있게 하고 있습니다. 제 요약을 복사해서 여러분 프로젝트에 붙여넣으셔도 좋습니다.

하지만 사이트에 있는 가이드는 꼭 읽어 보시기 바랍니다. 더 상세한 정보가 있습니다.

Commit Message Convention Readme

## Commit Message Convention

이 웹사이트는 [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/)을 준수합니다.

커밋 메시지는 [husky and commit lint](https://theodorusclarence.com/library/husky-commitlint-prettier)를 사용해 검증될 예정입니다. 아래 컨벤션을 따르지 않는다면, 커밋하실 수 없습니다.

### 형식

@@@text
<type>[optional scope]: <description>

[optional body]

[optional footer(s)]
@@@

* @을 to \`로 바꾸셔야 합니다. dev.to 사이트는 백틱을 여러개 사용하는 것을 허용하지 않고 있습니다.

예시: `feat(pre-event): add speakers section`

### 1. 타입

사용가능한 타입:

- feat → 기능의 추가 혹은 삭제. Ex: feat: add table on landing page, feat: remove table from landing page
- fix → 이슈에 따른 버그 수정 (이슈 없이 진행하지 마십시오). Ex: fix: illustration overflows in mobile view
- chore → 새로운 패키지 설치
- docs → 문서 업데이트
- style → 로직이 아닌 코드의 순서나 공백문자 수정
- refactor → 같은 기능을하지만, 다른 방식으로 수정한 경우
- ci → github workflows, husky를 수정
- test → 테스트 케이스 수정 혹은 추가
- revert → 커밋을 되돌릴 때
- perf → 성능과 관련된 것을 고칠 때

큰 변화의 경우에는 타입 뒤에 느낌표(!)를 더해주시기 바랍니다. Ex: feat!: drop support for internet explorer

### 2. (선택사항) 범위

페이지별 라벨 Ex: feat(pre-event): add date label

\* 범위가 필요하지 않으면 쓸 필요도 없습니다.

### 3. 설명

무엇을 했는지 구체적으로 설명해야합니다.

### 중요 규칙

**여러가지 변경사항이 있다면, 하나씩 커밋해야합니다.**

- 콜론 뒤에는 공백문자 한개가 있어야 합니다. Ex: feat: add something
- `fix` 타입을 사용할 때는 문제 상태를 설명해야합니다. Ex: fix: file size limiter not working
- 명령어와 현재시제를 사용해야합니다.: "changed"이거나 "changes"가 아니라 "change"로
- 문장 앞에 대문자 사용을 금합니다.
- 문장 끝에 마침표 사용을 금합니다.

이 규칙들을 사용하면 changelog는 잘 생성될 겁니다. 그러나 커밋 메시지가 충분히 설명하는지 여부는 여러분에게 달려있습니다.

5단계: Commitlint 추가

팀에 새로운 개발자와 함께 일하고 있다면, 이 컨벤션을 잘 모를 수 있습니다. 이 포스팅을 읽어보라고 하는 동안 😉, 프로젝트를 위한 linter를 추가하시면, 커밋 메시지들이 엉망이 되진 않을 겁니다.

3-commitlint

이 프로그램은 여러분이 커밋 메시지를 작성할 때, conventional commit의 사용을 강제할 겁니다.

Husky를 사용하면서 Commitlint를 추가하려면 이 포스팅을 확인해보시기 바랍니다.

요약

충분히 설명하는 커밋 메시지를 사용해야한다. 그렇게 하기 위해서 카테고리를 추가하고, Conventional Commit 규칙을 가이드로 따르자. 그러면 changelog 생성에도 도움이 된다. 그리고 Commitlint를 사용하면 커밋 메시지가 엉망이 되는 것을 막을 수 있다.

고품질의 소스코드를 보장하는 방법

작가님의 허락을 받고 번역한 글입니다.(원문)

요약 lint, 유닛 테스트, 정적 코드 분석, CI/CD를 합시다.

현대 소프트웨어 개발

지난 몇 년 간 소프트웨어 개발 프로세스가 많이 바뀌었습니다. 많은 현대적인 개발 도구와 프레임워크들이 코드 정리, 유지 관리, 가독성 향상 기능을 내장하고 있습니다. 이런 기능에도 불구하고 누구나 프로그래밍을 하면서 실수할 수 있습니다. 우리 모두 그런 단계를 거쳐왔고, 실수를 통해 배워왔습니다.

이 포스팅을 통해 실제 프로들이 사용하는 기본적인 코드 점검 기법을 공유해보겠습니다. 아래는 따라하기 좋은 모범 사례들입니다.

1. Code Linting

장기적으로 많은 이점을 제공하는 기본 설정 중 하나는 code linting입니다. 이것을 활용하면 코딩 컨벤션을 따르지 않거나, 읽을 수없는 코드를 작성하는 개발자들의 실수를 어느 정도 막을 수 있습니다. Code Linting 대신에 팀이 합의한 코딩 컨벤션을 지킬 수도 있습니다.

저희 팀은 Angular 프로젝트에서 기본적으로 지원하는 TSLint을 사용합니다. 제가 사용하는 TSLint의 전형적인 설정은 아래 이미지를 참조하시면 됩니다.

TSLint config

2. 유닛 테스트

유닛 테스트는 테스트 피라미드에서 가장 큰 부분을 차지하고 있습니다. 만약 여러분이 의미있고 고품질 유닛 테스트 작성에 시간을 투자한다면, 버그 없는 개발을 할 수 있을 겁니다.

저희는 istanbul.js 툴을 사용하여 코드 커버리지를 항상 85% 이상 유지하고 있습니다. 또한 풀 리퀘스트를 통해 추가된 새로운 코드가 기준에 일치하는지 확인합니다. (방법은 다음 파트에 나와있습니다.)

Istanbuls 설정 파일: TSLint config

3. Husky hooks

Husky 🐶는 프로젝트에 추가할 수 있는 가장 좋은 git hook 툴입니다. Husky는 먼저 실패할 기회를 줄겁니다.
아래는 제가 사용하는 hook의 일부분으로 추가해보셔도 좋습니다.

  • 팀에 의해 정해진 구체적인 커밋메시지 형식 확인하기
  • 이슈 lint, 형식 확인하기
  • 저장소에 코드를 push할 때 테스트 돌리기

Hooks 설정: Husky hooks

4. CI/CD 파이프라인

CI/CD 파이프라인은 모든 풀 리퀘스트에 대해서 전체적인 코드에 대한 linting, formatting 그리고 테스트를 진행합니다. 이렇게 하면 새 구성 요소/기능을 추가해도 무결성이 유지됩니다. 병합, 주간 정적 코드 점검, 월간 취약점 점검과 같은 배포도 파이프라인에서 예약을 걸어둘 수 있습니다.

젠킨스 파이프라인은 groovy 스크립트로 실행되고 그 결과 보고서를 팀의 메일링 리스트에 보냅니다.

Jenkins pipelines

5. 정적 코드 분석

Sonarqube플랫폼은 지속적인 정적 코드 분석 품질 보증을 제공합니다. 과학기술인이든 아니든 Sonarqube의 다양한 보고서(보안, 코드 스멜, 기술 부채 등)를 분석할 수 있고, 현재 코드 상태에 대한 전반적인 개요를 확인할 수 있습니다.

또한 놓친 테스트 커버리지, 중복, 순환 복잡성을 탐지하는데 도움이 됩니다. 코드가 실제 서버에 적용되기 전에 주간 Sonarqube 파이프라인으로 품질을 확인할 필요가 있습니다.

Sonarqube dashboard

6. [선택 사항]심층 보안 검사

보안 검사는 선택 사항처럼 보이지만, 회사 수준의 소프트웨어에서는 아닙니다. 그런 소프트웨어는 제대로 보호될 필요가 있습니다. 특히 Veracode 보안 검사는 꼭 해야합니다. 저희는 월간 파이프라인으로 veracode platform을 이용하여 스캔을 실행하고 있습니다.

또한 BlackDuck을 사용하여, 모든 계층에서 최적의 프로토콜이 사용되고 있는지 심도있는 보안 테스트를 하고 있습니다. Veeracode Dashboard

읽어주셔서 감사합니다. 댓글 달아주세요 :)

Git: 실수를 되돌리는 5가지 방법

작가 허락을 받고 번역한 글입니다.(원문)

개발자 업무 방식에 익숙한 사람이라면, Git이 어떻게 사용되는지 잘 알고 계실 겁니다. Git은 코딩을 하다가 만들어진 애매한 상황을 대부분 해결 해주는 좋은 도구입니다.

Git은 분산처리 되어 있기 때문에 모든 상황에서 되돌리기 기능을 제공하지는 않습니다. 하지만, 대부분의 상황에 적절한 해결방법을 가지고 있습니다. 가장 흔한 시나리오를 확인해봅시다.

 

Tip #1

험난한 시작: unstaged된 변경사항 버리기

파일을 변경하기로 결정했지만, 더 좋은 방법으로 바꿔야겠다고 생각 했을 때,

$ git checkout -- <filename>

파일이 unstaged상태이고 그 변경사항을 버리고 싶다면, 위 명령어를 사용하시면 됩니다.

파일의 현재 버전은 최근 staged 되어 있는 버전이거나, 커밋된 버전으로 바뀝니다. 그리고 버린 변경사항들은 저장되지 않습니다. 디렉토리에 있는 수정사항들을 버리고 싶을 때도 이 명령어를 사용할 수 있습니다.

$ git checkout -- <dirname>

 

Tip #2

개발의 울타리: 인덱스에서 staging 되지 않은 파일들

점심 전에 꽤 괜찮은 작업을 했거나 방금 작업한 것이 지금 하려고 하는일에 적절하지 않지만, 삭제 하기 싫다면

$ git reset <filename>

Index는 준비 영역으로 커밋에 어떤 변경사항을 허락할지 결정하는 공간입니다.

git add 명령어를 통해 변경사항을 이미 staged 했지만, 해당 파일을 커밋할 준비가 되어 있지 않다면, 위 명령어를 통해 unstage 시킬 수 있습니다.

이 명령어를 사용하면 변경사항은 unstage되지만, 실제로 삭제되지는 않습니다. 이 변경사항은 커밋이 될 때 까지 뒤로 미뤄지게 됩니다. 하지만 영구적 변경사항 삭제를 원한다면 아래 명령어를 쓰시면 됩니다.

$ git reset --hard <filename>

 

Tip #3

한 발자국 뒤로 물러나 봅시다: 커밋된 변경사항 되돌리기

잘못된 커밋을 찾으려고 했으나, 변경 이력에 파묻혀있다면..

$ git revert <commit>

좋은 소식은 git revert 명령어를 통해 쉽게 해결할 수 있다는 것입니다.
위 명령어는 새로 혹은 잘못 커밋된 최근 커밋을 되돌리는데 사용됩니다. 잘못된 커밋을 삭제하지 않고, 되돌리는 커밋을 새로 만들기 때문에 git 로그를 재작성하지 않아 안전한 사용이 가능합니다. 또한 로컬과 레포지토리 두 경우 모두 사용할 수 있습니다.
커밋 아이디를 찾기 위해서는 아래 명령어를 사용하면 됩니다.

$ git log --oneline

 

Tip #4

cherry-picking의 예술성: 다른 브랜치에 있는 커밋 적용해보기

잘못된 브랜치에 커밋을 했다면, 브랜치 전체를 병합하지 않고 제대로된 곳에 적용하고 싶을 겁니다.

$ git cherry-pick <commit>

Cherry-pick은 커밋 하나를 특정 브랜치에서 다른 브랜치로 적용할 수 있게 해줍니다. 실행을 위해서는 커밋하고 싶은 브랜치로 이동하고 위 명령어를 실행시키면 됩니다. 잘못 적용한 브랜치에서 해당 커밋 삭제하는 것을 잊어버리시면 안됩니다. 해당 커밋을 삭제는 아래 명령어를 사용하시면 됩니다.

$ git reset --hard HEAD{index}

💡 Git에 push나 pull하지 않고 코드를 공유하고 싶다면? GitLive를 통해 커밋하지 않은 변경사항을 cherry-pick하여 로컬에서 복사해서 직접 동료에게 보낼 수 있습니다. 이걸 읽어보시면 됩니다. ******

Tip #5

시간을 되돌릴 수 있다면 : 오래된 커밋의 메시지 변경하기

커밋 로그를 보는 동안 오래된 커밋 메시지에 오타가 있을 수 있습니다.

$ git rebase -i <sha>

위 명령어를 사용하면 쉘에서 메뉴를 바꿔가며 해당 커밋을 수정, 삭제, 병합할 수 있습니다. 경험 상, 저장소의 git 로그를 수정해선 절대 안됩니다. 하지만 로컬에서는 안전하게 할 수 있습니다.

연습을 위해 샘플 저장소를 만들어 rebase를 시도해보셔도 좋습니다. 실행을 하면 커밋 목록을 확인할 수 있을 겁니다.

$ git log --oneline

interactive rebase-1.png

다섯번째 커밋 메시지의 오타를 수정하기 위해서는 $ git rebase -i <sha>를 실행시키고, sha를 5번째 커밋의 해쉬 값으로 교체하면 됩니다.

interactive rebase-2.png

이 명령어를 치고 난 후에는 기본으로 지정된 에디터가 열립니다. 지시에 따라 실행시킬 동작을 선택하십시오.
커밋 메시지를 수정하기 위해서는 단어 pickr로 교체하고 저장 후 에디터를 닫으면 됩니다.
메시지는 지금 바로 변경하면 안됩니다. 에디터가 다시 열리고 메시지 수정을 유도할 겁니다. 이제 에디터를 끄고 쉘로 돌아오면 됩니다.

git log -oneline 명령어를 실행시키면 오타가 수정된 것을 볼 수 있습니다. 참 쉽죠?

interactive rebase-3.png

 

읽어 주셔서 감사합니다. 이 방법들을 통해 그 어떤 Git 문제도 여러분을 힘들게 하지 않길 바랍니다.
더 많은 Git 팁을 원한다면,
우리 Git 시리즈의 이전 포스팅을 확인하시면 됩니다: Top 5 Git Tips & Tricks and 5 Git Tips To Level Up Your Workflow.
Happy Git-ing!