# Google Drive 이사 (gdrive-migrate)

서로 **다른 두 구글 계정** 사이로 대용량 폴더를 통째로 옮기는 macOS 앱.
웹에서 폴더를 zip으로 다운로드하다 실패하거나, 사람이 일일이 쪼개서 받아 다시 올리던 작업을 없앤다.

내부적으로 [rclone](https://rclone.org)을 써서 **파일을 하나씩** 옮기므로:
- zip을 만들지 않는다 → 폴더 용량과 무관
- 중간에 끊겨도 **이어받기**(이미 옮긴 파일은 건너뜀)
- 일일 업로드 한도(계정당 약 750GB)에 걸리면 **자동으로 기다렸다가 이어서** 진행
- 폴더 구조·파일명 그대로 유지

전부 **로컬(내 맥)** 을 거쳐 처리한다. 외부 클라우드 서비스에 계정을 넘기지 않는다.

**로컬 디스크는 거의 안 쓴다**: rclone은 원본에서 읽은 데이터를 디스크에 저장하지 않고 곧바로 대상으로 스트리밍한다("다운로드 폴더에 쌓았다가 지우는" 방식이 아님). 메모리 버퍼만 약 `동시전송 4 × 청크 64MB ≈ 256MB` 정도 쓴다. 통과하는 데이터(대역폭)는 폴더 크기만큼이지만 저장 공간은 먹지 않는다.

## 구성

| 경로 | 역할 |
|---|---|
| `src/host/` | GUI 앱 (AppKit, Swift). 계정 연결·폴더 트리(다중 선택/새 폴더)·용량 미리보기·진행 로그 |
| `engine/gdrive-migrate.sh` | rclone 래퍼 엔진(`check`/`connect`/`lsjson`/`mkdir`/`preview`/`migrate`). 앱 번들 `Contents/Resources/` 안에 포함되어 서브프로세스로 실행됨 |
| `icon/icon.svg` | 앱 아이콘 원본(클라우드 + 양방향 화살표). `make-icon.sh`로 `.icns` 생성 |
| `make-icon.sh` | `icon/icon.svg` → `src/host/AppIcon.icns` 렌더(rsvg/cairosvg/qlmanage 자동 선택) |
| `build.sh` | 앱 컴파일·서명(Developer ID, hardened runtime) + **rclone 동봉** → `build/` + 개발기 설치 |
| `notarize.sh` | `build/` 앱 Apple 공증 + staple → `dist/` |
| `make-dmg.sh` | 드래그 설치용 `.dmg` 생성(서명 포함) → `dist/Drive Migrate.dmg` |
| `notarize-dmg.sh` | `dist/` dmg 공증 + staple |
| `install.sh` | zip 으로 받은 경우의 설치기(앱 복사 + 격리 속성 제거) |

## 쓰는 법 (사용자)

0. 설치: `Drive Migrate.dmg` 를 열고 앱을 **Applications 로 끌어놓기**. rclone 이 앱에 동봉되어 있어 **따로 설치할 것이 없다**(Homebrew 불필요).
1. 앱 실행 → **rclone 설치 확인** (동봉본이 자동으로 잡힌다).
2. **① 원본 계정 연결** — 브라우저가 열리면 옮길 원본 계정으로 로그인. 연결되면 **원본 폴더 트리**가 나타난다. (연결 후 버튼은 **연결 끊기**로 바뀜 — 누르면 해제되어 다른 계정으로 다시 연결 가능)
3. **② 대상 계정 연결** — 브라우저에서 **대상 계정으로 전환/로그인**(원본과 다른 계정). 연결되면 **대상 폴더 트리**가 나타난다.
4. **원본 폴더 선택** — 트리에서 옮길 폴더를 **여러 개(Cmd/Shift 클릭) 선택**한다. 삼각형을 눌러 하위 폴더까지 들어갈 수 있다.
   - 원본이 "나와 공유됨(공유 문서함)"에 있으면 트리 위 체크박스를 켜면 목록이 그쪽으로 바뀐다.
5. **대상 폴더 선택** — 트리에서 받을 폴더를 하나 고르거나, **＋ 여기에 새 폴더 만들기**로 만든다(선택한 폴더 안, 없으면 루트에 생성). 아무것도 안 고르면 대상 루트로 간다.
   - 선택한 원본 폴더들은 각각 `대상폴더/<원본폴더이름>` 으로 들어간다.
6. (선택) **용량 미리보기** — 옮기기 전에 선택한 원본들의 총 크기·파일 수와 대상 계정 여유 공간을 확인한다.
7. **이사 시작**. 진행 로그가 실시간으로 표시된다("Transferred: 12 GiB / 40 GiB, 30%, 25 MiB/s, ETA 18m"). 이사 중에는 **중지 버튼만** 활성화되고 나머지 조작은 잠긴다(완료·중지 시 다시 활성화).
   - 일일 한도에 걸리면 1시간 간격으로 자동 대기·재개.
   - 대상 저장 용량이 가득 차면(일일 한도와 다름) **즉시 멈추고** 안내한다 — 공간 확보 후 다시 시작하면 이어진다.
   - 창을 닫아도, 나중에 같은 선택으로 다시 시작하면 남은 파일만 이어서 옮긴다.
   - 완료되면 **총 이동 용량·파일 수·소요 시간**을 로그에 요약해 보여준다.

## 개발기에서 빌드·공증

```bash
./build.sh          # 컴파일·서명 + rclone 동봉 → build/Drive Migrate.app (+ 개발기 /Applications 설치)

# 공증 자격증명 1회 저장 (값은 본인만 입력, 키체인에 저장됨):
xcrun notarytool store-credentials gdrivemigrate-notary \
  --apple-id "<Apple ID>" --team-id 7Y6MHBMMH4 --password "<앱 암호>"

./notarize.sh       # 앱 공증 + staple → dist/Drive Migrate.app
./make-dmg.sh       # 드래그 설치용 dmg → dist/Drive Migrate.dmg
./notarize-dmg.sh   # dmg 공증 (배포용이면 권장)
```

## 다른 맥에 설치

**권장**: `dist/Drive Migrate.dmg` 를 전달 → 열어서 Applications 로 끌어놓기. 준비물 없음.

zip 으로 전달했다면 폴더에서 `bash install.sh` 를 실행한다.

> 공증 전 앱을 배포하면 내려받은 사용자가 Gatekeeper 경고를 본다.
> `install.sh` 는 격리 속성을 제거하므로 경고 없이 설치되지만, dmg 로 배포할 거라면 공증을 권장한다.

## 참고 / 한계

- **일일 한도**: 구글 드라이브는 계정당 하루 업로드 약 750GB 제한이 있다. 이보다 크면 여러 날에 걸쳐 자동 재개된다.
- **공유 드라이브(Shared Drive, 팀 드라이브)**: v1은 "내 드라이브"와 "나와 공유됨"을 지원한다. 원본/대상이 팀 드라이브면 rclone remote에 `team_drive` 설정이 필요하다:
  ```bash
  rclone config reconnect src:          # 또는
  rclone config update src team_drive <DRIVE_ID>
  ```
- **서명 인증서**: `Developer ID Application: Hong Kyu Lee (7Y6MHBMMH4)`. (hwp-quickaction과 동일)
- rclone 설정 파일 위치: `~/.config/rclone/rclone.conf` (remote 이름 `src`, `dst`).

## 제거

- `/Applications/Drive Migrate.app` (또는 `~/Applications/…`) 삭제
- 연결 해제: `rclone config delete src` / `rclone config delete dst`
- `brew uninstall rclone` (다른 데서 rclone을 안 쓰면)
