[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();
}
效果如下:
第二种方式和第一种类似,实际上也是用到了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窗口前。效果如下:
在研究这玩意的时候,随便看了下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