지저분한 스크립트에서 믿을 만한 도구까지: 1회용 실험을 사람들이 실제로 쓰는 도구로 바꾸는 법
대부분의 유용한 개발자 도구는 대충 만든 해킹에서 시작됩니다. 이 글은 엉망인 1회용 스크립트를 다른 사람도 믿고 쓸 수 있는 안정적이고 유지보수 가능한 도구로 바꾸는 실전 가이드입니다.
대부분의 개발자들이 사랑하는 도구는 처음부터 잘 다듬어진 제품이 아니었습니다. 보통은 이런 못생긴 것들에서 시작합니다.
- 밤샘 디버깅하다가 급하게 이어 붙인 스크립트
- “이번 한 번만”이라며 만든 데이터 마이그레이션용 임시 해킹 코드
- 아이디어가 먹힐지 테스트해 보려고 만든 작은 실험
그런데 어떻게든, 버리려고 만든 그 스크립트가 없으면 안 되는 존재가 됩니다. 처음 만든 사람에게도, 다른 사람들에게도요.
이 글은 그 변신을 의도적으로 만드는 방법에 대한 이야기입니다. 허술한 개인 실험을 어떻게 하면 사람들이 믿고 쓸 수 있는 도구로 바꿀 수 있을까요?
실제 문제에서 출발해, 스크립트를 진짜 소프트웨어처럼 대하고, 테스트와 자동화를 더하고, 피드백을 수집하고, 라이브러리로 리팩터링하고, 확장성과 유지보수를 고려한 설계를 통해, 점점 “집중된 제품”으로 다듬어가는 구체적인 단계를 순서대로 살펴보겠습니다.
1. 진짜, 반복해서 겪는 문제(당신 것)에서 시작하기
아무도 안 쓰는 걸 가장 빨리 만드는 방법은, 구체적인 고통 말고 추상적인 아이디어에서 출발하는 것입니다.
대신, 당신이 반복적으로 겪는 문제에 실험을 anchoring 하세요.
- 매주 혹은 매달 반복해서 수동으로 하는 일은 무엇인가요?
- 지루하고 실수하기 쉬워서 손이 안 가는 작업은 무엇인가요?
- 똑같은 명령어나 코드 조각을 계속 복붙하고 있는 곳은 어디인가요?
자신의 실제 워크플로를 위해 만들면:
- 첫 번째 사용자가 분명합니다. (바로 당신)
- 도구가 단순한 기술 데모가 아니라 구체적인 목적을 갖게 됩니다.
- 늘 직접 쓰고 있기 때문에 개선 효과를 빠르게 검증할 수 있습니다.
현실성 체크: “이 스크립트가 내 삶에서 없애주는 고통스러운 작업”을 한 문장으로 못 적겠다면, 아직 제품으로 만들 준비가 안 된 것입니다.
“이 스크립트는 Git 커밋에서 릴리스 노트를 자동 생성해 줘서, 배포 전에 일일이 수동으로 정리하지 않아도 되게 해준다.”
이 정도면 구체적이고, 측정 가능하고, 현실에 비춰 테스트하기도 쉽습니다.
2. 아주 작은 스크립트도 ‘진짜 소프트웨어’처럼 다루기
대부분의 실험은 하나의 지저분한 파일로 태어나고, 거기서 생을 마감합니다. 첫날엔 괜찮습니다. 하지만 30일째가 되면, 어디를 건드려도 부서질 것 같아서 아무것도 못 하게 됩니다.
초기부터, 실험이라도 소프트웨어로 취급하세요. 일회용 메모가 아니라.
a) 최소한의 모듈 구조 도입하기
규모가 작더라도 기본적인 구조는 잡아둡니다.
my-tool/ src/ cli.py core.py utils.py tests/ README.md
- 엔트리 포인트(CLI, 메인 스크립트)는 한곳에 모으고,
- 핵심 로직(비즈니스 규칙, 알고리즘)은 또 다른 곳에 두고,
- 헬퍼(로깅, 포매팅, IO 등)는 별도 모듈로 뺍니다.
b) 경계를 명확히 정의하기
스스로에게 물어보세요: 이 코드의 각 부분은 무엇을 알고, 무엇을 신경 쓰는가?
- CLI 레이어: CLI 인자 파싱, 출력, 종료 코드
- 코어 레이어: 데이터 변환, 의사 결정
- 인프라 레이어: 파일 읽기/쓰기, API 호출
이런 분리는 다음을 가능하게 합니다.
- 파일 시스템이나 네트워크에 의존하지 않고 핵심 로직만 따로 테스트하기 쉽습니다.
- 나중에 CLI에서 웹 UI로 바꾸는 등 인터페이스를 바꾸기 훨씬 수월합니다.
c) 이름을 진지하게 짓기
함수, 모듈, 변수 이름을 의미 있게 지으세요. 사용자(지금은 당신뿐일 수 있지만)를 위한 API를 설계하는 셈입니다. 앞으로 기여할 사람은, 코드를 얼마나 쉽게 이해할 수 있는지로 이 도구를 평가하게 됩니다.
3. 테스트와 자동화에 일찍 투자하기
“재밌는 실험”과 “믿고 쓰는 도구” 사이의 간극은 보통 자동화로 메워집니다.
변경 사항을 검증하는 유일한 방법이 손으로 클릭해 보거나 눈으로 출력 확인하는 것뿐이라면, 다음과 같이 될 가능성이 큽니다.
- 코드 변경을 회피하게 되고
- 억지로 바꾸면 버그를 내보내고
- 유지보수하다가 지쳐 버립니다.
a) 작지만 현실적인 테스트부터 시작하기
커버리지를 100% 맞출 필요는 없습니다. 필요한 건 신뢰감입니다.
집중해야 할 것은:
- 핵심 변환 로직 (입력 → 출력)
- 중요한 플로우 (예: “디렉터리 안의 파일들을 전부 제대로 처리하는가?”)
- 이미 한 번 데인 적 있는 엣지 케이스
설치나 세팅 없이도 빠르게 도는 테스트를 쓰세요. 예를 들어, 로그 파서 도구라면:
def test_parses_single_log_line(): line = "2025-01-01 10:00:00 INFO User logged in" record = parse_log_line(line) assert record.level == "INFO" assert record.user == "User"
b) 귀찮지만 중요한 일부터 자동화하기
초기부터 간단한 자동화를 붙입니다.
- CI(Continuous Integration): 매 푸시마다 테스트를 돌리기
- 린팅 / 포매팅 (예: ESLint, Black, Prettier)으로 스타일 논쟁 방지
- 기본 릴리스 워크플로 (예: semantic versioning, changelog 관리)
목표는 이겁니다: 코드를 바꾸고, 푸시하고, 대단한 수작업 없이도 빨리 “뭐가 깨졌는지/안 깨졌는지” 알 수 있게 만드는 것.
4. 첫날부터 실제 사용자 피드백 받기
누군가(동료 한 명이라도)가 당신의 도구를 쓰기 시작하는 순간, 그 실험은 제품이 됩니다.
이제 피드백 루프가 필요합니다.
a) 저기술(low-tech) 방식으로 시작하기
처음부터 거창한 분석 대시보드는 필요 없습니다. 간단한 채널이면 충분합니다.
#my-tool-feedback같은 슬랙 채널- GitHub 이슈 템플릿에 다음 질문 넣기:
- 무엇을 하려고 했나요?
- 실제로는 무엇이 일어났나요?
- 대신 무엇을 기대했나요?
- 아이디어와 버그 리포트를 환영한다고 적어 둔 짧은
CONTRIBUTING.md
b) “좋아요?”를 넘어서 묻기
“마음에 드세요?”보다 개발에 도움이 되는 질문을 하세요.
- 이 도구가 당신에게서 어떤 작업을 대체해 주나요?
- 이 도구를 쓰다 거의 포기할 뻔한 지점은 어디였나요?
- 지금 이 도구의 한계를 어떻게 우회해서 쓰고 있나요?
단발적인 불만보다 패턴을 찾아야 합니다. 설정에서 세 사람이 모두 막힌다면, 그건 “사용자 문제”가 아니라 “제품 문제”입니다.
그리고 피드백을 행동으로 연결하세요.
- 공통적인 고통 포인트는 이슈로 만들고
- 핵심 워크플로에서 마찰을 줄이는 수정에 우선순위를 두세요.
5. 대충 짠 코드를 깔끔한 재사용 라이브러리로 리팩터링하기
초기 코드는 못생겨도 됩니다. 안 되는 건, “이 실험이 가치 있다는 걸 알면서도” 못생긴 상태에 그대로 두는 것입니다.
전환점은 이럴 때 옵니다. 코드 조각을 여기저기 복붙하고 있거나, if/else 피라미드에 기능을 계속 달아 붙이고 있다면, 라이브러리로 뽑아낼 때가 된 겁니다.
a) 리팩터링 기회를 포착하기
다음과 같은 징후를 찾으세요.
- 여러 스크립트에 복사된 코드 → 공용 모듈로 추출
- 한 함수가 여러 일을 하고 있다 → 더 작고 포커스된 함수로 분리
- 하드코딩된 값들(파일 경로, API URL 등) → 설정값으로 분리
b) 안정적인 추상화를 추출하기
처음부터 과한 추상화를 할 필요는 없습니다. 대신에:
- 바뀔 가능성이 낮은 동작(예: 특정 파일 포맷 파싱 방식)을 찾고
- 그걸 명확한 인터페이스(함수, 클래스, 모듈)로 감싸고
- 그 인터페이스 주변에 테스트를 추가하세요.
시간이 지나면, 당신의 실험은 이렇게 변합니다.
- 작은 코어는 접착 코드(glue code)에 불과하고
- 그 아래에는 다른 프로젝트에서도 가져다 쓸 수 있는 깔끔한 재사용 라이브러리들이 받치고 있는 상태로요.
6. 확장성과 유지보수를 염두에 두고 설계하기
첫날부터 “백만 사용자”를 위한 설계를 할 필요는 없습니다. 하지만 답도 없는 구석으로 스스로를 몰아넣는 일은 피해야 합니다.
스스로에게 물어보세요: 사용자가 10배 늘면, 가장 먼저 뭐가 부서질까?
a) 설정을 명시적으로 만들기
환경별로 다른 내용을 코드에 박아 넣지 마세요. 다음을 활용합니다.
- 설정 파일 (
.yaml,.json,.toml등) - 환경 변수
- 잘 문서화된 CLI 플래그
이렇게 하면 도구를 이식하기 쉽고, 새로운 환경에 배포하기도 쉬워집니다.
b) 추측하지 말고, 로그 남기기
기본적인 로깅과 진단 정보를 넣으세요.
- 도구가 무엇을 했는지
- 어떤 입력을 받았는지
- 왜 실패했는지
단순한 INFO, ERROR 로그만으로도 디버깅이 **찍어맞추기에서 조사(investigation)**로 바뀝니다.
c) 딱 필요한 만큼만 문서화하기
소설을 쓸 필요는 없습니다. 그래도 다음은 꼭 있어야 합니다.
- README
- 이 도구가 무엇을 하는지
- 누구를 위한 것인지
- 2–3개의 명령으로 설치하고 실행하는 방법
- 현실적인 사용 사례를 바탕으로 한 Quickstart 예제
- 기여자를 위한 짧은 설계 개요 (핵심 로직 위치, 테스트 구조 등)
유지보수성은 코드에만 있는 것이 아닙니다. 미래의 나와 다른 사람을 성공하게 만드는 것 전체가 유지보수성입니다.
7. 해킹 덩어리가 아니라, 초점을 좁힌 제품으로 반복 개선하기
실험은 옆으로 성장하는 경향이 있습니다. 여기엔 기능 하나, 저기엔 플래그 하나, 어딘가에는 문서도 안 된 환경 변수가 하나 더.
이걸 진짜 제품으로 바꾸려면 초점(focus) 이 필요합니다.
a) 핵심 사용 사례를 정의하기
당신의 도구가 특히 잘해야 하는 단 한 가지 일은 무엇인가요?
이렇게 쓰세요.
“이 도구는 X를 자동화해서, Y를 더 이상 수동으로 하지 않아도 되게 하려고 존재한다.”
이 문장을 기준으로:
- 무엇이 필수 기능이고, 무엇이 있으면 좋은 기능인지 결정하고
- 도구의 핵심 목적을 흐리는 아이디어에는 과감히 아니라고 말하세요.
b) 작고 일관된 단위로 배포하기
실제 사용 데이터와 피드백을 기준으로 반복 개선하세요.
- 작고 포커스된 개선을 자주 릴리스하고
- 사람들이 실제로 어떻게 쓰는지(명령, 플래그, 워크플로)를 관찰하고
- 아무도 쓰지 않거나, 사용자들을 헷갈리게 하는 기능은 과감히 걷어냅니다.
시간이 지나면, 당신의 실험용 스크립트는 사람들이 이해하고 믿고 쓸 수 있는 날카롭고 의견이 분명한(opinionated) 도구로 변해 있을 겁니다.
마무리: 전부 합쳐 보면
1회용 코딩 실험을 사람들이 실제로 쓰는 도구로 바꾸는 건 마법이 아닙니다. 일련의 의도적인, 실용적인 단계들일 뿐입니다.
- 자신의 진짜, 반복되는 문제를 해결해서 도구에 분명한 목적과 1호 사용자를 부여한다.
- 작은 스크립트도 진짜 소프트웨어처럼 모듈 구조와 명확한 경계를 가진 채 다룬다.
- 테스트와 자동화에 일찍 투자해서 “무서워서 못 고치는 개발”을 피한다.
- 첫날부터 피드백을 수집하고, 그 피드백이 로드맵을 이끌게 한다.
- 대충 짠 코드를 깔끔한 라이브러리로 리팩터링해서, 실험이 쓸모 있다는 게 보이면 구조를 다듬는다.
- 확장성과 유지보수를 고려해 설계해서, 다른 사람들이 가져다 쓰고 확장하기 쉽게 만든다.
- 실제 사용을 바탕으로 반복 개선해서, 방향 잃은 기능 집합이 아니라 초점 있는 제품으로 키운다.
이걸 꾸준히 해나가다 보면, 언젠가 문득 깨닫게 될 겁니다. 예전에 지워버릴까 말까 고민했던 그 스크립트가 이제는 팀—혹은 더 큰 커뮤니티—가 없으면 안 된다고 느끼는 도구가 되어 있다는 사실을.
그때가 되면, 그건 우연이 아니었을 겁니다.