[Unity]Mac调用SVN更新

        其实之前有过一篇关于SVN更新的,但那是在Windows上的,Windows上bat之后也没有用,用的是小乌龟工具。用了一年多没啥大问题。现在来写Mac的主要是本人在用Mac的SVN更新的时候,有点累,一直用命令行更新,写烦了cd xxx,然后svn update,再接着svn revert --depth=infinity .这些命令。

        也用过一些SVN工具,Mac上好像没啥好的工具,没有小乌龟的过滤更新功能(主要是AB包是在Window上打,Mac上是直接打ipa,不需要更新某些目录),那些工具对我来说跟输入命令行也没啥区别。因此写了个简单的SVN工具。大致实现了两种方式,最后还是选择第一种。其实两种方式都是类似的,只是输出不一样,一个输出在Unity的Console,另一个则是输出在Terminal。

        先来说第一种:

        先写个sh脚本:svnupdate.sh

#!/bin/bash

tempProjectDirectory=$1

echo $tempProjectDirectory

# 需要更新的目录
updatePath[0]=$tempProjectDirectory"/Assets/Editor"
updatePath[1]=$tempProjectDirectory"/Assets/IngameDebugConsole"
updatePath[2]=$tempProjectDirectory"/Assets/MA"
updatePath[3]=$tempProjectDirectory"/Assets/Midas"
updatePath[4]=$tempProjectDirectory"/Assets/Msdk"
updatePath[5]=$tempProjectDirectory"/Assets/Plugins"
updatePath[6]=$tempProjectDirectory"/Assets/PostProcessing"
updatePath[7]=$tempProjectDirectory"/Assets/Resources/chuangjue"
updatePath[8]=$tempProjectDirectory"/Assets/Scripts"
updatePath[9]=$tempProjectDirectory"/Assets/StreamingAssets/iOS"
updatePath[10]=$tempProjectDirectory"/PlatformSDKPlugin"
updatePath[11]=$tempProjectDirectory"/ProjectSettings"
updatePath[12]=$tempProjectDirectory"/Shell"


for var in ${updatePath[@]};
do
	echo "Now is updating "$var
	# 判断目录是否存在
	if [ -d $var ]; then
		cd $var
		svn update --accept theirs-full
		svn revert --depth=infinity .
	fi
done

echo "svn update finish"

        然后在之前的c#代码上进行修改:

    /// <summary>
    /// 调用小乌龟SVN
    /// </summary>
    /// <param name="commandType"></param>
    /// <param name="path"></param>
    private static void SVNCommandAndRun(SVN_COMMAND_TYPE commandType, string path = null)
    {
#if UNITY_EDITOR_WIN
        WindowCMD(commandType, path);
#elif UNITY_EDITOR_OSX
        MacCMD(commandType, path);
#endif
    }

    private static void MacCMD(SVN_COMMAND_TYPE commandType, string path = null)
    {
        // Application.dataPath 只能在主线程中获取
        int lastIndex = Application.dataPath.LastIndexOf("/");
        string sourcePath = Application.dataPath.Substring(0, lastIndex);
        // 获取sh文件存放目录
        string shellCmd = sourcePath + "/Shell/";
        switch (commandType)
        {
            case SVN_COMMAND_TYPE.UPDATE:
                shellCmd += "svnupdate.sh " + sourcePath;
                break;
            case SVN_COMMAND_TYPE.REVERT:
                shellCmd += "svnrevert.sh " + sourcePath;
                break;
        }
        UnityEngine.Debug.Log("shellCmd: " + shellCmd);

        // 新开线程防止锁死
        Thread newThread = new Thread(new ParameterizedThreadStart(SVNCmdThread));
        newThread.Start(shellCmd);
    }

    private static void WindowCMD(SVN_COMMAND_TYPE commandType, string path = null)
    {
        #region 拼接小乌龟svn命令
        string command = "TortoiseProc.exe /command:";
        switch (commandType)
        {
            case SVN_COMMAND_TYPE.UPDATE:
                command += "update /path:\"";
                break;
            case SVN_COMMAND_TYPE.COMMIT:
                command += "commit /path:\"";
                break;
            case SVN_COMMAND_TYPE.REVERT:
                command += "revert /path:\"";
                break;
            case SVN_COMMAND_TYPE.CLEANUP:
                command += "cleanup /path:\"";
                break;
            case SVN_COMMAND_TYPE.LOG:
            default:
                command += "log /path:\"";
                break;
        }
        if (path == null || path == "")
        {
            command += Application.dataPath;
            command = command.Substring(0, command.Length - 6);
        }
        else
            command += path;
        command += "\"";
        command += " /closeonend:0";
        //UnityEngine.Debug.LogError("command: " + command);
        #endregion

        // 新开线程防止锁死
        Thread newThread = new Thread(new ParameterizedThreadStart(SVNCmdThread));
        newThread.Start(command);
    }

    private static void SVNCmdThread(object obj)
    {
        Process p = new Process();
#if UNITY_EDITOR_WIN
        p.StartInfo.FileName = "cmd.exe";
        //UnityEngine.Debug.LogError("command: " + obj.ToString());
        p.StartInfo.Arguments = "/c " + obj.ToString();
#elif UNITY_EDITOR_OSX
        p.StartInfo.FileName = "/bin/bash";
        p.StartInfo.Arguments = obj.ToString();
#endif
        p.StartInfo.UseShellExecute = false;
        p.StartInfo.RedirectStandardInput = true;
        p.StartInfo.RedirectStandardOutput = true;
        p.StartInfo.RedirectStandardError = true;
        p.StartInfo.CreateNoWindow = true;
        p.Start();

        while (!p.StandardOutput.EndOfStream)
        {
            UnityEngine.Debug.Log(p.StandardOutput.ReadLine());
        }

        p.WaitForExit();
        p.Close();
    }

        效果如下:

[Unity]Mac调用SVN更新

        第二种方式和第一种类似,实际上也是用到了sh脚本,直接看代码:

    private static void MacCMD(SVN_COMMAND_TYPE commandType, string path = null)
    {
        // Application.dataPath 只能在主线程中获取
        int lastIndex = Application.dataPath.LastIndexOf("/");
        string sourcePath = Application.dataPath.Substring(0, lastIndex);
        // 获取sh文件存放目录
        string shellPath = sourcePath + "/Shell/";
        switch (commandType)
        {
            case SVN_COMMAND_TYPE.UPDATE:
                shellPath += "svnupdate.sh";
                break;
            case SVN_COMMAND_TYPE.REVERT:
                shellPath += "svnrevert.sh";
                break;
        }
        string argument = shellPath + "|" + sourcePath;
        UnityEngine.Debug.Log("shellCmd: " + argument);

        // 新开线程防止锁死
        Thread newThread = new Thread(new ParameterizedThreadStart(MacSVNCmdThread));
        newThread.Start(argument);
    }

    private static void MacSVNCmdThread(object obj)
    {
        try
        {
            var argument = obj.ToString();
            var strArray = argument.Split('|');
            var shellPath = strArray[0];
            var sourcePath = strArray[1];
            if (File.Exists(shellPath))
                File.Delete(shellPath);

            StreamWriter sw = new StreamWriter(shellPath, false, System.Text.Encoding.UTF8);
            sw.WriteLine("#!/bin/sh");
            sw.WriteLine("tempProjectDirectory=" + sourcePath);
            sw.WriteLine("echo $tempProjectDirectory");
            sw.WriteLine("cd $tempProjectDirectory");
            sw.WriteLine("svn update");
            sw.WriteLine("svn revert --depth=infinity .");
            sw.WriteLine("exit");
            sw.Close();

            Process chmod = new Process();
            chmod.StartInfo.FileName = @"/bin/bash";
            chmod.StartInfo.Arguments = string.Format("-c \"chmod 777 {0}\"", shellPath);
            chmod.StartInfo.UseShellExecute = false;
            chmod.StartInfo.CreateNoWindow = true;
            chmod.Start();
            chmod.WaitForExit();

            Process svnProcess = new Process();
            svnProcess.StartInfo.FileName = @"/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal";
            svnProcess.StartInfo.Arguments = shellPath;

            svnProcess.StartInfo.UseShellExecute = false;
            svnProcess.StartInfo.CreateNoWindow = true;

            svnProcess.Start();
            svnProcess.WaitForExit(); 
            svnProcess.Close();
        }
        catch(Exception e)
        {
            UnityEngine.Debug.LogError("MacSVNCmdThread: " + e.ToString());
        }
    }

        跟第一种很类似吧,就是动态创建sh,修改sh脚本属性,改成可读,可写和可执行,再调用Mac的控制台来执行sh脚本。只写了个简单的SVN Update的,因为没有满足自己的需要,弃用了,因为会卡进程,需要自己手动关闭Mac的控制台。其实这种方式还有其他问题,不会自动关闭控制台通过偏好设置可以设置,但还是需要手动关闭,没有达到自己的需求,还有就是弹出的控制台不在Unity窗口前。效果如下:

[Unity]Mac调用SVN更新

        在研究这玩意的时候,随便看了下bat的数组处理方式,相对来说,还是shell简单点:

@echo off

:: 第一种数组实现方式
set array="Array_0" "Array_1" "Array_2"

:: 第二种数组实现方式
rem set array="Array_0"
rem set array=%array%;"Array_1"
rem set array=%array%;"Array_2"

(for %%b in (%array%) do (
	echo %%b
))

set list=1 2 3 4 
(for %%a in (%list%) do ( 
   echo %%a 
))

pause
exit