같은 CLI를 Go로 다시 만들기

greet-cli와 gitx를 Go(cobra + os/exec)로 포팅하며, Go가 CLI 세계에서 갖는 결정적 차별점인 “배포”를 집중적으로 다룬다. go build 한 줄로 만드는 3MB 단일 바이너리, 한 장비에서 6개 OS/arch 조합을 모두 빌드하는 크로스 컴파일, GoReleaser + GitHub Actions로 태그 푸시만으로 Homebrew tap까지 자동 배포하는 워크플로우를 보여준다. npm/pipx와 비교한 사용자 경험 차이, Go의 단점(개발 속도, API 호출 코드 길이, 의존성 패치 배포 부담)도 솔직히 짚어 언제 Go를 선택할지 판단 기준을 제시한다. 시리즈 전체 회고로 마무리.

같은 CLI를 Python으로 다시 만들기

본편에서 TypeScript로 만든 greet-cli와 gitx를 Python으로 포팅하며 “설계 원리는 언어 독립적”을 실증한다. 라이브러리 매핑(commander→click, chalk→rich, fetch→httpx, child_process→subprocess)을 정리하고, 데코레이터 vs 체이닝, click의 Choice 자동 검증, httpx의 타임아웃 파라미터, rich 마크업, subprocess.run의 동기 API 등 언어 관용구 차이를 구체적으로 비교한다. shell injection 방어, JSON 모드, exit code 규약, 테스트 전략은 언어와 무관하게 동일함을 코드로 보인다. pipx를 통한 배포와 pyproject.toml 구조도 package.json과 1:1로 대응함을 확인한다.

실전 품질: 테스트, 배포, 유지보수

본편의 마지막 편으로, greet-cli와 gitx를 실전 배포 수준으로 끌어올린다. 테스트 전략의 핵심은 순수 로직과 IO의 분리이며, fetch와 child_process.spawn을 vitest로 모킹하는 패턴을 코드로 보여준다. cosmiconfig로 하드코딩 제거, package.json의 files/engines/prepublishOnly 필드, npm publish –dry-run으로 사전 점검, 시맨틱 버저닝과 CHANGELOG, GitHub Actions 기반 자동 릴리스 (+ npm provenance), README 베스트 프랙티스까지 커버한다. 플러그인·TUI·단일 바이너리 등 다음 단계 주제와 번외편 예고로 시리즈를 마무리한다.

gitx 만들기: 기존 CLI 래핑하기 (Type A)

git 명령을 내부에서 호출하는 Type A Wrapper gitx를 만든다. child_process의 세 가지 API(exec/execFile/spawn) 중 왜 spawn + shell: false 만 안전한지, 출력을 캡처할지 스트리밍할지 판단하는 기준, save·sync·cleanup 세 명령을 통해 여러 git 명령의 체이닝·전제 조건 검증·대화형 프롬프트·부분 실패 처리까지 다룬다. commander의 –no-* 관례, @inquirer/prompts의 Ctrl+C 처리(exit code 130), Windows 줄바꿈과 git 로케일 같은 실무 함정까지 정리한다.

greet-cli 완성: 공개 API 호출하기 (Type B)

greet-cli에 외부 API를 호출하는 두 명령어 weather(wttr.in)와 quote(Quotable)를 추가하면서 Type B Wrapper의 핵심 주제들을 관통한다. Node.js 내장 fetch와 AbortController로 타임아웃을 거는 법, 네트워크 에러와 HTTP 에러를 분류하는 법, chalk·ora로 UX를 입히는 법, 그리고 –json 모드에서 장식을 전부 끄는 이유를 다룬다. 명령어 단위 파일 분리(src/commands/*.ts), ESM 환경의 import 경로 규칙, 외부 API 타입을 “필요한 필드만” 정의하는 실무 패턴까지 커버한다.

설계와 프로젝트 세팅: greet-cli 시작하기

greet-cli의 요구사항을 한 문장으로 정의하고, 동사형 서브커맨드와 옵션 설계 원칙을 먼저 세운 뒤 구현에 들어간다. TypeScript CLI 프로젝트의 세 가지 핵심 설정(“type”: “module”, “bin” 필드, 셰뱅)을 짚고, commander로 첫 명령어 greet hello를 구현한다. commander vs yargs vs oclif 비교, tsx 기반 개발 루프, npm link로 글로벌 설치 테스트까지 다루며, 2편이 끝나면 터미널에서 직접 만든 greet 명령이 다국어 인사 메시지를 출력한다.

CLI Wrapper, 왜 그리고 언제 만드는가

CLI Wrapper의 본질을 프로세스·stdio·exit code·argv 관점에서 정리하고, alias·shell function과의 차이를 명확히 구분한다. 기존 CLI를 감싸는 Type A와 임의 동작을 CLI화하는 Type B로 유형을 나누고, TypeScript·Python·Go·Rust의 생태계·배포·기동속도를 비교해 언어 선택의 판단 기준을 제시한다. 본 시리즈가 TypeScript로 진행되는 이유와 다른 언어 독자를 위한 라이브러리 매핑까지 안내하며, 앞으로 만들 greet-cli와 gitx 두 프로젝트의 최종 모습을 미리 공개한다.