회사 내부용 CLI 만들기
(blog.chay.dev)- 개발팀에서 조직의 지식을 수집하고 보존하는 유용한 방법 중 하나는 유용한 스니펫, 스크립트 또는 워크플로우 모음을 늘리는 것
- 그래서 많은 리포지토리에 Makefile, bash 스크립트 같은 것들이 만들어짐
- 조직 전반에 걸쳐서 유용한 도구 설치, 상용구 코드 생성, 아무도 기억하지 못하는 복잡한 AWS 명령 실행 같은 것은 어떻게 해야 할까?
- Slack이나 Shopify와 같은 일부 회사에는 자체 내부 CLI가 있음
- 최신 터미널인 Warp에는 워크플로를 문서화하고 공유할 수 있는 기능이 있음
- 조직 내부용 CLI는 쉽게 만들수 있음. 예로 acme란 회사용 CLI를 제작해 봄
CLI 설계 요구사항
acme <command>로 어디서든 명령어를 실행할 수 있는 공통 진입점을 가짐- 모든 개발자는 특정 리포지토리로 먼저 이동할 필요 없이 어디서나 acme <command>를 실행하여 명령을 트리거할 수 있음
- 개발자들이 새 명령어를 쉽게 기여할 수 있도록 함
acme update로 새 버전을 쉽게 배포할 수 있게 함- 크로스 플랫폼 지원(예:
acme download something을 하면 Linux에서는curl, Windows에서는Invoke-WebRequest사용) acme list로 사용 가능한 명령어 목록과 간단한 설명을 볼 수 있게 함
just를 사용해 프로젝트 시작하기
- just는
make와 유사하지만 명령어 실행에 특화된 도구임 - 크로스 플랫폼을 지원하고 플랫폼 특화 명령어도 실행 가능함
- 다른 옵션으로는 Slack의
magic-cli(Ruby를 잘 안다면 시작하기에 훌륭함)나make가 있음
프로젝트 세팅하기
just설치. 여기 지침 따르기~/acme/cli폴더 만들고 루트에 다음justfile추가:
default:
just --list
# arch와 os 이름 표시
os-info:
echo "Arch: {{arch()}}"
echo "OS: {{os()}}"
just문서에선 명령어를 "recipes"라고 부름.- 레시피 없이
just를 실행하면 justfile의 첫번째 레시피 실행. 보통 첫번째 레시피의 이름을 "default"로 지정하는게 일반적인 패턴
$ just
just --list
Available recipes:
default
os-info # Show arch and os name
- default 레시피는
just list실행. 모든 레시피 목록과 주석을 보여줌 - default 레시피는 숨기는 게 좋음
- 레시피 실행하면 각 명령어가 실행되기 전 출력됨.
@접두사로 이 출력 제거 가능. Makefile과 유사
[private]
@default:
just --list
# arch와 os 이름 표시
@os-info:
echo "Arch: {{arch()}}"
echo "OS: {{os()}}"
acme alias 만들기
acme <command>형태로 실행하기 위해.bashrc에 alias 추가alias acme='just --justfile ~/acme/cli/justfile'source ~/.bashrc나exec bash로 새 별칭 로드
새 레시피 작성하기
간단한 레시피
- AWS IAM 사용자/역할 정보 가져오기
@aws-id: aws sts get-caller-identity- 아무도 기억하지 못하는 명령을 단순화하는 것이 아마도 내부 CLI의 주요 사용 사례
- awscli는 크로스 플랫폼이라고 가정하고 있으므로 이 레시피는 호출 위치에 관계없이 작동
플랫폼 특화 레시피
systemd와 같은 도구가 포함된 스니펫은 개발자가 Linux 머신을 사용하는 경우에만 노출[linux]속성을 사용해 Linux에서만 레시피 노출되게 함
[linux]
@list-systemd-services:
systemctl list-units --type=service
크로스 플랫폼 레시피
- 폴더 크기 구하기를 Windows와 Linux에서 각각 구현
[windows] [no-cd] get-folder-size path: (Get-ChildItem "{{path}}" -Recurse -Force | Measure-Object -Property Length -Sum).Sum / 1MB [linux] [no-cd] get-folder-size path: du -sh {{path}}
스크립트 레시피
- 레시피에 전체 스크립트를 삽입할 수 있음
- Shebang(
#!)으로 시작하는 레시피는 별도 파일로 저장되어 실행됨 - 제어 흐름(if-else, 루프) 사용, 변수 저장 및 조작 등과 같이 워크플로에 약간 더 복잡한 로직이 필요한 경우에 유용
# Say hello world in sh
hello-world-sh:
#!/usr/bin/env sh
hello='Yo'
echo "$hello from a shell script!"
- 강력한 스크립팅 기능을 갖춘 프로그래밍 언어를 활용할 수 있다는 의미. 어떤 작업은 Bash보다 Python에서 더 쉽게 수행할 수 있음
# scale jpg image by 50%
[no-cd]
scale-jpg path:
#!/usr/bin/env python3
import PIL.Image
image = PIL.Image.open("{{path}}")
factor = 0.5
image = image.resize((round(image.width * factor), round(image.height * factor)))
image.save("{{path}}.s50.jpg")
- 모든 개발자가 컴퓨터에 파이썬을 설치하는 것은 아니며, 설치되어 있더라도 pillow가 설치되어 있지 않을 수도 있음.
nix를 사용하여 종속성이 포함된 스크립트를 실행 가능:
# scale jpg image by 50%
[no-cd]
scale-jpg path:
#! /usr/bin/env nix-shell
#! nix-shell -i python3 -p python3Packages.pillow
import PIL.Image
...
레시피 배포하기
- 자체 배포 메커니즘을 롤링하는 대신
git을 사용 - GitHub에 저장소 만들고 현재까지 만든 것을 푸시
$ git init
$ git commit -m "first commit"
$ git branch -M main
$ git remote add origin git@github.com:acme/cli.git
$ git push -u origin main
- 이제 이 리포지토리에 액세스할 수 있는 사람은 누구나 PR을 만들어 변경 사항을 기여할 수 있음
acme update레시피로git pull자동화
# Update the Acme CLI
@update:
git fetch
git checkout main
문서화
- 내부 도구의 성공에는 채택(Adoption) 매우 중요하며, 신규 사용자가 도구를 설치하고 탐색할 수 있도록 안내하는 좋은 사용 설명서가 꼭 필요함
README에 설치 및 사용 방법 안내
# Acme CLI
## Prerequisites
`just`: Install just [here](https://github.com/casey/just/blob/master/README.md#installation)
## Installation
Clone this repo:
...
Set up the `acme` alias:
...
## Usage
List all available recipes:
...
- 이제 모든 Acme Corp 개발자가 사용할 수 있게 되었음!
- 사내에 Slack 메시지를 게시하여 모든 사람이 사용해 보도록 독려하고, 각자가 자신만의 스니펫을 제공할 수 있음
추가 기능
- 자동 완성(Completion) 기능은 TAB 키를 누르면 하위 명령, 파일 경로, 옵션 등을 자동 완성할 수 있는 메커니즘
- 대부분의 셸은 이 기능을 제공하며, 대부분의 주요 CLI 도구는 완성 기능을 설치하는 방법을 제공
- Python의 Click, Golang의 Cobra, Rust의 clap 등 대부분의 주요 CLI 프레임워크는 자동으로 완성 기능을 생성할 수 있음
Just는just --completion <shell>.를 실행하여 Completion을 생성할 수 있음
GeekNews Weekly에 포함된 글입니다.
에디터 코멘트 보기