188 lines
7.6 KiB
C#
188 lines
7.6 KiB
C#
#if UNITY_EDITOR
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using Debug = UnityEngine.Debug;
|
|
|
|
/// <summary>
|
|
/// GitAutoSync — Unity Editor 자동 git sync (BurningTimes BT5-Dev C안, 2026-04-23 PD 승인)
|
|
///
|
|
/// 구조: Unity Editor(본 스크립트) = trigger 전용. 실제 git 작업은
|
|
/// BT 본 레포 scripts/unity_auto_sync.sh (bash) 가 수행.
|
|
/// 이 분리로 스크립트 컴파일 오류가 git 기능을 마비시키는 리스크 차단.
|
|
///
|
|
/// 동작:
|
|
/// - Unity Editor 시작 시: 자동 pull (EditorPrefs 토글 가능)
|
|
/// - Unity Editor 종료 시: 자동 push (add + commit + push 일괄)
|
|
/// - Menu: Tools/Git/Pull Now·Push Now·Status·토글 옵션
|
|
///
|
|
/// 의존:
|
|
/// - Git for Windows (bash.exe) — PD 실증 환경
|
|
/// - BURNINGTIMES_ROOT 환경변수 또는 기본 E:/BurningTimes
|
|
/// - paths.local.json 의 UNITY_PROJECT_ROOT · UNITY_GIT_REMOTE 설정
|
|
/// </summary>
|
|
[InitializeOnLoad]
|
|
public static class GitAutoSync
|
|
{
|
|
private const string BT_ROOT_ENV = "BURNINGTIMES_ROOT";
|
|
private const string BT_ROOT_FALLBACK = "E:/BurningTimes";
|
|
private const string SYNC_SCRIPT_REL = "scripts/unity_auto_sync.sh";
|
|
|
|
private const string PREF_PULL_ON_LOAD = "GitAutoSync.PullOnLoad";
|
|
private const string PREF_PUSH_ON_QUIT = "GitAutoSync.PushOnQuit";
|
|
|
|
private const string GIT_BASH_FALLBACK = @"C:\Program Files\Git\bin\bash.exe";
|
|
|
|
static GitAutoSync()
|
|
{
|
|
// Unity Editor 시작 시 컴파일 안정화 후 pull (delayCall은 프레임 지연)
|
|
EditorApplication.delayCall += OnEditorStart;
|
|
EditorApplication.quitting += OnEditorQuit;
|
|
}
|
|
|
|
// ─────────────────────────────────────────────────────────
|
|
// 경로·bash 해결
|
|
// ─────────────────────────────────────────────────────────
|
|
private static string GetBTRoot()
|
|
{
|
|
string envRoot = System.Environment.GetEnvironmentVariable(BT_ROOT_ENV);
|
|
return string.IsNullOrEmpty(envRoot) ? BT_ROOT_FALLBACK : envRoot;
|
|
}
|
|
|
|
private static string GetSyncScriptPath()
|
|
{
|
|
return Path.Combine(GetBTRoot(), SYNC_SCRIPT_REL).Replace('\\', '/');
|
|
}
|
|
|
|
private static string GetBashPath()
|
|
{
|
|
// Windows Git Bash 우선 (PD 환경 실증)
|
|
if (File.Exists(GIT_BASH_FALLBACK)) return GIT_BASH_FALLBACK;
|
|
// PATH 검색 fallback (macOS/Linux 포함)
|
|
return "bash";
|
|
}
|
|
|
|
// ─────────────────────────────────────────────────────────
|
|
// bash 스크립트 호출
|
|
// ─────────────────────────────────────────────────────────
|
|
private static int RunSync(string action)
|
|
{
|
|
string scriptPath = GetSyncScriptPath();
|
|
if (!File.Exists(scriptPath))
|
|
{
|
|
Debug.LogWarning($"[GitAutoSync] 스크립트 부재: {scriptPath}\n" +
|
|
$"BT 본 레포 확인 필요 (환경변수 {BT_ROOT_ENV} 또는 {BT_ROOT_FALLBACK})");
|
|
return -1;
|
|
}
|
|
|
|
var psi = new ProcessStartInfo
|
|
{
|
|
FileName = GetBashPath(),
|
|
Arguments = $"\"{scriptPath}\" {action}",
|
|
UseShellExecute = false,
|
|
RedirectStandardOutput = true,
|
|
RedirectStandardError = true,
|
|
CreateNoWindow = true
|
|
};
|
|
|
|
try
|
|
{
|
|
using (var proc = Process.Start(psi))
|
|
{
|
|
string stdout = proc.StandardOutput.ReadToEnd();
|
|
string stderr = proc.StandardError.ReadToEnd();
|
|
proc.WaitForExit();
|
|
|
|
string combined = stdout + (string.IsNullOrEmpty(stderr) ? "" : "\n[stderr]\n" + stderr);
|
|
|
|
if (proc.ExitCode == 0)
|
|
{
|
|
Debug.Log($"[GitAutoSync] {action} 성공\n{combined}");
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError($"[GitAutoSync] {action} 실패 (exit {proc.ExitCode})\n{combined}");
|
|
// 수동 개입 필요한 케이스 (충돌 등)는 Dialog로 PD 알림
|
|
if (action == "pull" || action == "push")
|
|
{
|
|
EditorApplication.delayCall += () =>
|
|
EditorUtility.DisplayDialog(
|
|
"GitAutoSync 실패",
|
|
$"{action} 실패 (exit {proc.ExitCode}).\n\nConsole 로그 확인 후 수동 해결 필요.",
|
|
"확인");
|
|
}
|
|
}
|
|
return proc.ExitCode;
|
|
}
|
|
}
|
|
catch (System.Exception ex)
|
|
{
|
|
Debug.LogError($"[GitAutoSync] {action} 예외: {ex.Message}\n{ex.StackTrace}");
|
|
return -2;
|
|
}
|
|
}
|
|
|
|
// ─────────────────────────────────────────────────────────
|
|
// 자동 hook
|
|
// ─────────────────────────────────────────────────────────
|
|
private static void OnEditorStart()
|
|
{
|
|
if (EditorPrefs.GetBool(PREF_PULL_ON_LOAD, true))
|
|
{
|
|
Debug.Log("[GitAutoSync] Unity Editor 시작 — auto pull");
|
|
RunSync("pull");
|
|
}
|
|
}
|
|
|
|
private static void OnEditorQuit()
|
|
{
|
|
if (EditorPrefs.GetBool(PREF_PUSH_ON_QUIT, true))
|
|
{
|
|
Debug.Log("[GitAutoSync] Unity Editor 종료 — auto push");
|
|
RunSync("push");
|
|
}
|
|
}
|
|
|
|
// ─────────────────────────────────────────────────────────
|
|
// Menu 수동 발동
|
|
// ─────────────────────────────────────────────────────────
|
|
[MenuItem("Tools/Git/Pull Now %#g")]
|
|
private static void MenuPull() { RunSync("pull"); }
|
|
|
|
[MenuItem("Tools/Git/Push Now %#p")]
|
|
private static void MenuPush() { RunSync("push"); }
|
|
|
|
[MenuItem("Tools/Git/Status")]
|
|
private static void MenuStatus() { RunSync("status"); }
|
|
|
|
[MenuItem("Tools/Git/Init Repo (최초 1회)")]
|
|
private static void MenuInit()
|
|
{
|
|
if (EditorUtility.DisplayDialog(
|
|
"Unity 프로젝트 git 초기화",
|
|
"Unity 프로젝트 경로에 git 레포를 초기화합니다. 최초 1회만 수행하세요.\n\nGitea 레포 생성은 별도로 수동 집행 필요.",
|
|
"진행", "취소"))
|
|
{
|
|
RunSync("init");
|
|
}
|
|
}
|
|
|
|
[MenuItem("Tools/Git/Toggle Auto Pull On Load")]
|
|
private static void TogglePull()
|
|
{
|
|
bool next = !EditorPrefs.GetBool(PREF_PULL_ON_LOAD, true);
|
|
EditorPrefs.SetBool(PREF_PULL_ON_LOAD, next);
|
|
Debug.Log($"[GitAutoSync] Auto Pull On Load: {next}");
|
|
}
|
|
|
|
[MenuItem("Tools/Git/Toggle Auto Push On Quit")]
|
|
private static void TogglePush()
|
|
{
|
|
bool next = !EditorPrefs.GetBool(PREF_PUSH_ON_QUIT, true);
|
|
EditorPrefs.SetBool(PREF_PUSH_ON_QUIT, next);
|
|
Debug.Log($"[GitAutoSync] Auto Push On Quit: {next}");
|
|
}
|
|
}
|
|
#endif
|