Alfred workflow란?
맥 사용자라면 필수 앱으로 빠지지 않고 소개되는 알프레드 앱의 기능 중, Powerpack(유료) 라이선스가 있다면 사용할 수 있는 기능입니다.
간단한 작업이라면 알프레드에서 제공해주는 기능들을 이어 붙임으로써 어떤 Trigger 가 일어나면 연결된 작업들이 순차적으로 수행되게끔 만들 수 있고, 알프레드가 지원해주지 않는 기능도 스크립트를 만들어서 수행시킬 수 있습니다.
업무 자동화에 관심이 많다보니, 큰 서비스 속에서의 개발을 떠나 작고 소소한 것이지만 내가 루틴하게 수행하는 일들을 스크립트로 개발하는 시간을 가집니다.
그 중 제가 하루에 30번 이상도 수행하는 스크립트가 있어서 Alfred workflow 만드는 방법과 같이 소개하려고 합니다.
intellij 프로젝트 검색 후 실행
제가 자주 쓰는 이 workflow는 아래와 같이 동작합니다.
- 사용자가 어떤 IDE 를 사용할건지 입력한다 (ij: intellij, py: pycharm, cl: clion)
- 사용자가 프로젝트 이름을 검색어로 입력한다
- 특정 디렉토리들 하위에 해당 이름을 가진 jetbrain project 디렉토리가 있는지 검색한다
- 사용자가 그 중 하나를 선택하면 IDE 로 해당 디렉토리를 열어준다
- 성공 알림을 띄운다
IDE가 열려있지 않은 상태에서 바로 특정 프로젝트를 열때도 유용하고, jetbrain IDE는 하나의 window에서 여러 프로젝트를 다룰 수 없기 때문에 여러 프로젝트를 열어서 코드를 봐야할 때도 유용하게 쓰고 있습니다.
workflow 만들기
Blank workflow 생성
검색 기능을 담당할 Script Filter 생성
마우스 우클릭 > Inputs > Script Filter
우선 alfred workflow 에서 각 작업의 input/output 을 알 필요가 있습니다.
input 은 python 스크립트 실행 시에 argv 인자로 넘겨받을 수 있습니다.
ouput 은 기존에는 표준출력에 xml 형태의 텍스트를 출력해주는 방식이였는데 이 방식은 레거시가 되었다고 하고 지금은 json 텍스트를 표준출력 해주면 됩니다.
https://www.alfredapp.com/help/workflows/inputs/script-filter/
https://www.alfredapp.com/help/workflows/inputs/script-filter/json/
우선 검색어를 입력하면 해당 검색어와 icon image 를 보여주는 스크립트이고 아래처럼 keyword 를 입력하고 한칸 띄운 뒤 검색어를 입력하면 python 스크립트에서 sys.argv 로 검색어를 받은 뒤, print 표준 출력으로 json 형태를 출력해주면 하단에 검색된 리스트가 보여집니다.
참고로 workflow 를 만들게 되면 아래의 경로에 디렉토리가 생성되고, 등록한 icon image 이름 등을 확인하고 사용할 수 있습니다. (suffix로 붙는 해쉬값은 다를 수 있습니다)
~/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.FE921C80-4368-40EC-A7E9-EC232B5FC4B9
> ls -alF
total 256
drwxr-xr-x 5 jaekwon staff 160 9 20 17:00 ./
drwxr-xr-x 7 jaekwon staff 224 9 20 16:54 ../
-rw-r--r--@ 1 jaekwon staff 39687 9 20 17:00 3575E4D3-70B9-4D80-BB77-FD73B9C9F170.png
-rw-r--r-- 1 jaekwon staff 81932 9 20 16:54 icon.png
-rw-r--r-- 1 jaekwon staff 2245 9 20 17:08 info.plist
기반은 다 만들었으니 검색 로직을 만들어야 합니다. 검색의 단계를 나눠서 생각해보면
- 특정 디렉토리 하위를 조회
- 해당 디렉토리가 project 디렉토리인지 확인
- 검색어에 일치하는 project 인지 확인
같은 과정이 필요하다고 생각해볼 수 있습니다.
- 특정 디렉토리 하위를 조회
내가 프로젝트 디렉토리로 자주 쓰는 곳들을 등록해두면 그 하위에 디렉토리를 loop 돌며 찾아가는 방식으로 구현해볼 수 있습니다.
def search(q, dirname):
ps = []
filenames = os.listdir(dirname)
for i, filename in enumerate(filenames):
# TODO 2,3 과정을 검증하고 ps 변수에 디렉토리 추가
return ps
- 해당 디렉토리가 project 디렉토리인지 확인
intellij 를 좀 쓰신 분들이라면 intellij 로 프로젝트 디렉토리를 열때 메타데이터나 캐시데이터를 저장하기 위해 .idea 디렉토리가 생긴다는 것을 알고 있을 것입니다. 해당 디렉토리의 유무로 프로젝트 디렉토리인지를 확인할 수 있습니다.
다만 이 경우에 git clone 으로 특정 프로젝트를 다운로드 받은 직후에 한번도 intellij 로 열지 않은 프로젝트 같은 경우는 검색이 안됩니다.
def check_jetbrain_project(path):
filenames = os.listdir(path)
for filename in filenames:
if filename == ".idea":
return True
return False
- 검색어에 일치하는 project인지 확인
프로젝트의 이름과 디렉토리의 이름이 같다면 디렉토리 이름으로도 찾을 수 있겠지만, 그렇지 않은 프로젝트들도 있을 수 있습니다.
그렇지 않은 프로젝트들은 /.idea/.name 파일로 프로젝트의 이름이 생성되기에 이 정보를 이용할 수 있습니다.
def get_project_name(path):
name = path.split("/")[-1]
dotname_path = path + '/.idea/.name'
if os.path.exists(dotname_path):
with open(dotname_path, 'r') as file:
name = file.read().replace('\n', '')
return name
def search(q, dirname):
ps = []
filenames = os.listdir(dirname)
for i, filename in enumerate(filenames):
full_path = os.path.join(dirname, filename)
if os.path.isdir(full_path) and check_jetbrain_project(full_path):
project_name = get_project_name(full_path)
if q == "" or filename.find(q) >= 0 or project_name.find(q) >= 0:
ps.append({
"index": i,
"project_name": project_name,
"dirname": filename,
"path": os.path.join(dirname, filename)
})
return ps
위 과정을 통해서 검색어에 일치하는 프로젝트 디렉토리들을 찾을 수 있고, 이제 사용자가 선택할 수 있도록 json 형태로 출력해주면 됩니다.
그리고 다음 step에서 해당 디렉토리를 열 수 있게끔 디렉토리 full path를 "arg" 라는 속성으로 넘겨주어야 합니다.
전체 코드는 git repo 참고: github.com/JaekwonHa/alfred-workflow/blob/master/open_project_in_jetbrain/search_script.py
특정 IDE를 실행할 Run Script 생성
마우스 우클릭 > Actions > Run Script
여기서 query 로 인자를 받을 수 있는데, 이는 이전 작업에서 json 데이터 중에 arg 속성으로 넘겨준 값입니다. 여기서는 프로젝트 디렉토리의 full path를 받습니다.
IDEA_PATH
라는 항목이 있는데 intellij 를 실행시켜주는 바이너리 파일의 경로입니다.
tool > Create Command-line Launcher 를 이용해서 생성해줍니다.
성공 알림을 띄워줄 Post Notification 생성
마우스 우클릭 > Outputs > Post Notification
결과
여기까지 진행하시면 디렉토리 이름 or 프로젝트 이름으로 jetbrain 프로젝트 디렉토리들이 검색되게 됩니다.
TIP
- 디버깅
상단의 벌레 아이콘으로 스크립트의 실행 로그를 확인할 수 있습니다.
이때 주의하실 점은 표준출력으로 로그를 찍게되면 json 형태가 아니라는 에러가 발생하기에 주의해야 합니다.
이상으로 Alfred workflow 를 만들어 보았습니다. 여기서 더 나아가본다면, 많이 검색된 데이터는 우선순위를 더 준다거나, 이전 검색어를 캐시해둔다거나 하는 추가적인 기능들도 생각해볼 수 있겠고 나중에 또 시간이 된다면 개발하고 글로 남겨보겠습니다.