#if (UNITY_4 || UNITY_4_1 || UNITY_4_2 || UNITY_4_3 || UNITY_4_4 || UNITY_4_5 || UNITY_4_6 || UNITY_5 || UNITY_2017_1_OR_NEWER)
#define UNITY_4_AND_GREATER
#endif
using UnityEngine;
using UnityEditor;
using System;
using System.Globalization;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
namespace BuildReportTool
{
public static class Util
{
public static int GetUnityMajorVersion(string unityVersion)
{
string majorVersion = string.Empty;
int len;
int majorIdx;
for (majorIdx = 0, len = unityVersion.Length; majorIdx < len; ++majorIdx)
{
if (System.Char.IsDigit(unityVersion[majorIdx]) && unityVersion[majorIdx] != '.')
{
majorVersion += unityVersion[majorIdx];
}
if (unityVersion[majorIdx] == '.')
{
break;
}
}
return int.Parse(majorVersion);
}
public static bool UnityMajorVersionUsedIsAtMost(int versionAtMost, string unityVersionName)
{
int majorVersion = GetUnityMajorVersion(unityVersionName);
return (majorVersion <= versionAtMost);
}
public static bool UnityMajorVersionUsedIsAtLeast(int versionAtLeast, string unityVersionName)
{
int majorVersion = GetUnityMajorVersion(unityVersionName);
return (majorVersion >= versionAtLeast);
}
// care should be taken when using ShouldGetBuildReportNow and ShouldSaveGottenBuildReportNow
// as they are effectively global variables
// unfortunately this is the only way I can ensure persistence of bool variables in between recompilations
// SerializeField seems to fail at times
public static BuildPlatform GetBuildPlatformBasedOnUnityBuildTarget(BuildTarget b)
{
switch (b)
{
// -----------------------------------
// Web Builds
#if !UNITY_5_4_OR_NEWER
// Unity Web Build was up to Unity 5.3
case BuildTarget.WebPlayer:
return BuildPlatform.Web;
case BuildTarget.WebPlayerStreamed:
return BuildPlatform.Web;
#endif
#if UNITY_4
// NaCl and Flash build support was up to Unity 4
case BuildTarget.NaCl:
return BuildPlatform.Web;
case BuildTarget.FlashPlayer:
return BuildPlatform.Flash;
#endif
case BuildTarget.WebGL:
return BuildPlatform.WebGL;
// -----------------------------------
// Mobile builds
#if UNITY_4
case BuildTarget.iPhone:
#else
case BuildTarget.iOS:
#endif
return BuildPlatform.iOS;
case BuildTarget.Android:
return BuildPlatform.Android;
// -----------------------------------
// Console builds
#if !UNITY_5_5_OR_NEWER
// 7th gen console support was up to Unity 5.4
case BuildTarget.XBOX360:
return BuildPlatform.XBOX360;
case BuildTarget.PS3:
return BuildPlatform.PS3;
#endif
// 8th gen
case BuildTarget.XboxOne:
return BuildPlatform.XBOXOne;
case BuildTarget.PS4:
return BuildPlatform.PS4;
#if UNITY_5_2_OR_NEWER && !UNITY_2018_1_OR_NEWER
// WiiU support was from Unity 5.2 to Unity 2017.4
case BuildTarget.WiiU:
return BuildPlatform.WiiU;
#endif
#if UNITY_5_6_OR_NEWER || UNITY_2017_1_OR_NEWER
case BuildTarget.Switch:
return BuildPlatform.Switch;
#endif
// -----------------------------------
// Windows builds
case BuildTarget.StandaloneWindows:
return BuildPlatform.Windows32;
case BuildTarget.StandaloneWindows64:
return BuildPlatform.Windows64;
case BuildTarget.WSAPlayer:
return BuildPlatform.WindowsStoreApp;
// -----------------------------------
// Linux builds
#if UNITY_4_AND_GREATER
case BuildTarget.StandaloneLinux:
return BuildPlatform.Linux32;
case BuildTarget.StandaloneLinux64:
return BuildPlatform.Linux64;
case BuildTarget.StandaloneLinuxUniversal: // note: universal will be removed in a future version
return BuildPlatform.LinuxUniversal;
#endif
// -----------------------------------
// Mac OS X builds
#if UNITY_2017_3_OR_NEWER
// in Unity 2017.3, OSX builds are now only Intel 64-bit builds
case BuildTarget.StandaloneOSX:
return BuildPlatform.MacOSX64;
#else
case BuildTarget.StandaloneOSXIntel:
return BuildPlatform.MacOSX32;
case BuildTarget.StandaloneOSXIntel64:
return BuildPlatform.MacOSX64;
case BuildTarget.StandaloneOSXUniversal:
return BuildPlatform.MacOSXUniversal;
#endif
}
return BuildPlatform.None;
}
// note: we store these in EditorPrefs so that they easily persist after any recompiling or assembly reload,
// which normally occur before and after a build is done.
public static bool ShouldGetBuildReportNow
{
get { return EditorPrefs.GetBool("BRT_ShouldGetBuildReportNow", false); }
set { EditorPrefs.SetBool("BRT_ShouldGetBuildReportNow", value); }
}
public static bool ShouldSaveGottenBuildReportNow
{
get { return EditorPrefs.GetBool("BRT_ShouldSaveGottenBuildReportNow", false); }
set { EditorPrefs.SetBool("BRT_ShouldSaveGottenBuildReportNow", value); }
}
public static BuildTarget BuildTargetOfLastBuild
{
get
{
int gotBuildTargetIdx = EditorPrefs.GetInt("BRT_BuildTargetOfLastBuild", 0);
return (BuildTarget) gotBuildTargetIdx;
}
set
{
int buildTargetIdx = Convert.ToInt32(value);
EditorPrefs.SetInt("BRT_BuildTargetOfLastBuild", buildTargetIdx);
}
}
public static bool IsAScriptDLL(string filename)
{
return filename.StartsWith("Assembly-", StringComparison.OrdinalIgnoreCase);
}
public static bool IsAUnityEngineDLL(string filename)
{
return filename.StartsWith("UnityEngine.", StringComparison.OrdinalIgnoreCase);
}
public static bool IsAKnownSystemDLL(string filename)
{
return filename.Equals("system.dll", StringComparison.OrdinalIgnoreCase) ||
filename.Equals("system.core.dll", StringComparison.OrdinalIgnoreCase) ||
filename.Equals("mscorlib.dll", StringComparison.OrdinalIgnoreCase) ||
filename.Equals("mono.security.dll", StringComparison.OrdinalIgnoreCase) ||
filename.Equals("boo.lang.dll", StringComparison.OrdinalIgnoreCase);
}
public static string RemovePrefix(string prefix, string val)
{
if (val.StartsWith(prefix))
{
return val.Substring(prefix.Length, val.Length - prefix.Length);
}
return val;
}
public static string RemoveSuffix(string suffix, string val, int offset = 0)
{
if (val.EndsWith(suffix, StringComparison.OrdinalIgnoreCase))
{
return val.Substring(0, val.Length - suffix.Length + offset);
}
return val;
}
static string GetLastFolder(string inFolder)
{
inFolder = inFolder.Replace('\\', '/');
//Debug.Log("folder: " + inFolder);
//string folderName = System.IO.Path.GetDirectoryName(folderEntries[n]);
int lastSlashIdx = inFolder.LastIndexOf('/');
if (lastSlashIdx == -1)
{
return "";
}
return inFolder.Substring(lastSlashIdx + 1, inFolder.Length - lastSlashIdx - 1);
}
public static string FindAssetFolder(string folderToStart, string desiredFolderName)
{
string[] folderEntries = Directory.GetDirectories(folderToStart);
for (int n = 0, len = folderEntries.Length; n < len; ++n)
{
string folderName = GetLastFolder(folderEntries[n]);
//Debug.Log("folderName: " + folderName);
if (folderName == desiredFolderName)
{
return folderEntries[n];
}
else
{
string recursed = FindAssetFolder(folderEntries[n], desiredFolderName);
string recursedFolderName = GetLastFolder(recursed);
if (recursedFolderName == desiredFolderName)
{
return recursed;
}
}
}
return "";
}
static string GetPathParentFolder(string path)
{
if (string.IsNullOrEmpty(path))
{
return string.Empty;
}
return System.IO.Path.GetDirectoryName(path);
}
public static string GetBuildSizePathDescription(BuildInfo buildReport)
{
if (string.IsNullOrEmpty(buildReport.BuildFilePath))
{
return string.Empty;
}
BuildReportTool.BuildPlatform buildPlatform =
BuildReportTool.ReportGenerator.GetBuildPlatformFromString(buildReport.BuildType,
buildReport.BuildTargetUsed);
if (buildPlatform == BuildPlatform.Windows32 ||
buildPlatform == BuildPlatform.Windows64 ||
buildPlatform == BuildPlatform.Linux32 ||
buildPlatform == BuildPlatform.Linux64)
{
// in windows builds, `buildFilePath` is the executable file
// we additionaly need to get the size of the Data folder
// in 32 bit builds, `buildFilePath` is the executable file (.x86 file). we still need the Data folder
// in 64 bit builds, `buildFilePath` is the executable file (.x86_64 file). we still need the Data folder
var exeFile = System.IO.Path.GetFileName(buildReport.BuildFilePath);
var dataFolder = BuildReportTool.Util.ReplaceFileType(exeFile, "_Data");
var buildParentFolder = GetPathParentFolder(buildReport.BuildFilePath);
return string.Format("File size of {0} and the {1} folder in {2}", exeFile, dataFolder,
buildParentFolder);
}
if (buildPlatform == BuildPlatform.LinuxUniversal)
{
// in universal builds, `buildFilePath` is the 32-bit executable. we still need the 64-bit executable and the Data folder
var exe32File = System.IO.Path.GetFileName(buildReport.BuildFilePath);
var exe64File = BuildReportTool.Util.ReplaceFileType(exe32File, ".x86_64");
var dataFolder = BuildReportTool.Util.ReplaceFileType(exe32File, "_Data");
var buildParentFolder = GetPathParentFolder(buildReport.BuildFilePath);
return string.Format("File size of {0}, {1}, and the {2} folder in {3}", exe32File, exe64File,
dataFolder, buildParentFolder);
}
return string.Format("File size of {0}", buildReport.BuildFilePath);
}
public static double GetObbSizeInEclipseProject(string eclipseProjectPath)
{
if (string.IsNullOrEmpty(eclipseProjectPath) || !Directory.Exists(eclipseProjectPath))
{
return 0;
}
double obbSize = 0;
foreach (string file in DldUtil.TraverseDirectory.Do(eclipseProjectPath))
{
if (IsFileOfType(file, ".main.obb"))
{
obbSize += GetFileSizeInBytes(file);
break;
}
}
return obbSize;
}
public static string GetObbSizeInEclipseProjectReadable(string eclipseProjectPath)
{
if (string.IsNullOrEmpty(eclipseProjectPath) || !Directory.Exists(eclipseProjectPath))
{
return string.Empty;
}
return GetBytesReadable(GetObbSizeInEclipseProject(eclipseProjectPath));
}
public static string GetPathSizeReadable(string fileOrFolder)
{
if (string.IsNullOrEmpty(fileOrFolder))
{
return string.Empty;
}
return GetBytesReadable(GetPathSizeInBytes(fileOrFolder));
}
public static double GetPathSizeInBytes(string fileOrFolder)
{
if (Directory.Exists(fileOrFolder))
{
return GetFolderSizeInBytes(fileOrFolder);
}
if (File.Exists(fileOrFolder))
{
return GetFileSizeInBytes(fileOrFolder);
}
return 0;
}
public static double GetFolderSizeInBytes(string folderPath)
{
if (string.IsNullOrEmpty(folderPath) || !Directory.Exists(folderPath))
{
return 0;
}
double totalBytesOfFilesInFolder = 0;
foreach (string file in DldUtil.TraverseDirectory.Do(folderPath))
{
totalBytesOfFilesInFolder += GetFileSizeInBytes(file);
}
return totalBytesOfFilesInFolder;
}
public static string GetFolderSizeReadable(string folderPath)
{
if (string.IsNullOrEmpty(folderPath) || !Directory.Exists(folderPath))
{
return string.Empty;
}
return GetBytesReadable(GetFolderSizeInBytes(folderPath));
}
public static string GetStreamingAssetsSizeReadable()
{
return GetFolderSizeReadable(Application.dataPath + "/StreamingAssets");
}
public static string GetProjectPath(string appDataPath)
{
const int ASSETS_FOLDER_NAME_LENGTH = 6; // "Assets"
return appDataPath.Remove(appDataPath.Length - ASSETS_FOLDER_NAME_LENGTH);
}
// expects filename given to be full path
public static long GetFileSizeInBytes(string filename)
{
if (string.IsNullOrEmpty(filename) || !File.Exists(filename))
{
return 0;
}
FileInfo fi = new FileInfo(filename);
return fi.Length;
}
public static string GetFileSizeReadable(string filename)
{
if (string.IsNullOrEmpty(filename))
{
return string.Empty;
}
return GetBytesReadable(GetFileSizeInBytes(filename));
}
const double ONE_TERABYTE = 1099511627776.0;
const double ONE_GIGABYTE = 1073741824.0;
const double ONE_MEGABYTE = 1048576.0;
const double ONE_KILOBYTE = 1024.0;
public static string GetBytesReadable(double bytes)
{
//return EditorUtility.FormatBytes(bytes);
return MyFileSizeReadable(bytes);
}
static string MyFileSizeReadable(double bytes)
{
if (bytes < 0)
{
return "N/A";
}
double converted = bytes;
string units = "B";
if (bytes >= ONE_TERABYTE)
{
converted = bytes / ONE_TERABYTE;
units = "TB";
}
else if (bytes >= ONE_GIGABYTE)
{
converted = bytes / ONE_GIGABYTE;
units = "GB";
}
else if (bytes >= ONE_MEGABYTE)
{
converted = bytes / ONE_MEGABYTE;
units = "MB";
}
else if (bytes >= ONE_KILOBYTE)
{
converted = bytes / ONE_KILOBYTE;
units = "KB";
}
return String.Format("{0:0.##} {1}", converted, units);
}
public static double GetApproxSizeFromString(string size)
{
if (string.IsNullOrEmpty(size) || size == "N/A" || size.Length <= 2)
{
return 0;
}
// units is expected to be in the last two letters of the string
string units = size.Substring(size.Length - 2, 2);
// therefore, everything except the last two letters is expected to be a number
string numOnly = size.Substring(0, size.Length - 2);
double num;
var success = double.TryParse(numOnly, NumberStyles.Number, CultureInfo.InvariantCulture, out num);
if (!success)
{
return 0;
}
//Debug.Log(size + " " + num);
// convert the number to bytes
switch (units)
{
case "KB":
return num * ONE_KILOBYTE;
case "MB":
return num * ONE_MEGABYTE;
case "GB":
return num * ONE_GIGABYTE;
case "TB":
return num * ONE_TERABYTE;
}
return 0;
}
static bool TextFileHasContents(string filepath, string contents)
{
FileStream fs = new FileStream(filepath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
StreamReader sr = new StreamReader(fs);
bool ret = false;
string line;
while ((line = sr.ReadLine()) != null)
{
if (line.IndexOf(contents, StringComparison.OrdinalIgnoreCase) != -1)
{
ret = true;
break;
}
}
fs.Close();
return ret;
}
public static bool FileHasContents(string filepath, string contents)
{
return TextFileHasContents(filepath, contents);
}
public static string GetTextFileContents(string file)
{
// thanks to http://answers.unity3d.com/questions/167518/reading-editorlog-in-the-editor.html
FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
StreamReader sr = new StreamReader(fs);
string contents = sr.ReadToEnd();
fs.Close();
return contents;
}
public static void DeleteSizePartFile(SizePart file)
{
//Debug.Log("going to delete " + file.Name);
DeleteFile(file.Name);
}
static void DeleteFile(string file)
{
string projectFolder = RemoveSuffix("Assets", Application.dataPath);
DeleteFile(projectFolder, file);
}
public static bool HaveToUseSystemForDelete(string file)
{
return IsFileAUnixHiddenFile(file) || IsFileInVersionControlMetadataFolder(file);
}
static void DeleteFile(string projectFolder, string file)
{
//Debug.Log("will delete " + file);
if (HaveToUseSystemForDelete(file))
{
string fileAbsPath = System.IO.Path.Combine(projectFolder, file);
//Debug.Log("will system delete " + fileAbsPath);
SystemDeleteFile(fileAbsPath);
}
else
{
// AssetDatabase.MoveAssetToTrash also deletes .meta file if it exists
AssetDatabase.MoveAssetToTrash(file);
}
}
static void SystemDeleteFile(string file)
{
File.Delete(file);
}
public static string ReplaceFileType(string filename, string newFileType)
{
int idxOfDot = filename.LastIndexOf(".", StringComparison.Ordinal);
if (idxOfDot < 0)
{
// dot is not found
return string.Empty;
}
string newFile = filename.Remove(idxOfDot);
newFile += newFileType;
return newFile;
}
// low-level filename checks
public static bool IsFileInAPath(string filepath, string pathToCheck)
{
if (string.IsNullOrEmpty(filepath))
{
return false;
}
return filepath.IndexOf(pathToCheck, StringComparison.OrdinalIgnoreCase) != -1;
}
public static bool IsFileInAnEditorFolder(string filepath)
{
return IsFileInAPath(filepath, "/Editor/") ||
DoesFileStartIn(filepath, "Editor/");
}
public static bool DoesFileStartIn(string filepath, string pathToCheck)
{
if (string.IsNullOrEmpty(filepath))
{
return false;
}
return filepath.StartsWith(pathToCheck, StringComparison.OrdinalIgnoreCase);
}
public static bool IsFileOfType(string filepath, string typeExtenstion)
{
if (string.IsNullOrEmpty(filepath))
{
return false;
}
return filepath.EndsWith(typeExtenstion, StringComparison.OrdinalIgnoreCase);
}
public static bool IsFileName(string filepath, string filenameToCheck)
{
return string.Equals(System.IO.Path.GetFileName(filepath), filenameToCheck,
StringComparison.OrdinalIgnoreCase);
}
public static bool IsFileAUnixHiddenFile(string filepath)
{
if (string.IsNullOrEmpty(filepath))
{
return false;
}
return System.IO.Path.GetFileName(filepath).StartsWith(".");
}
public static bool DoesFileBeginWith(this string filepath, string stringToCheck)
{
if (string.IsNullOrEmpty(filepath))
{
return false;
}
return System.IO.Path.GetFileName(filepath).StartsWith(stringToCheck, StringComparison.OrdinalIgnoreCase);
}
///
/// Does string end in ".mat"?
///
///
///
public static bool IsMaterialFile(this string me)
{
return me.EndsWith(".mat", StringComparison.OrdinalIgnoreCase);
}
///
/// Does string contain "/Resources/"?
///
///
///
public static bool IsInResourcesFolder(this string me)
{
return me.IndexOf("/Resources/", StringComparison.OrdinalIgnoreCase) > -1;
}
///
/// Does string start with "Assets/"?
///
///
///
public static bool IsInAssetsFolder(this string me)
{
return me.StartsWith("Assets/", StringComparison.OrdinalIgnoreCase);
}
public static bool IsInStreamingAssetsFolder(this string me)
{
return me.StartsWith("Assets/StreamingAssets/", StringComparison.OrdinalIgnoreCase);
}
public static bool IsInPackagesFolder(this string me)
{
return me.StartsWith("Packages/", StringComparison.OrdinalIgnoreCase);
}
public static bool IsInAssetsOrPackagesFolder(this string me)
{
return me.StartsWith("Assets/", StringComparison.OrdinalIgnoreCase) ||
me.StartsWith("Packages/", StringComparison.OrdinalIgnoreCase);
}
///
/// Does string end in ".unity"?
///
///
///
public static bool IsSceneFile(this string me)
{
return me.EndsWith(".unity", StringComparison.OrdinalIgnoreCase);
}
///
/// Does string end in an image file type that Unity supports?
/// (psd, jpg, gif, png, tif, tga, bmp, dds, exr, iff, pict)
///
///
///
public static bool IsTextureFile(this string file)
{
return IsFileOfType(file, ".psd") ||
IsFileOfType(file, ".jpg") ||
IsFileOfType(file, ".jpeg") ||
IsFileOfType(file, ".gif") ||
IsFileOfType(file, ".png") ||
IsFileOfType(file, ".tiff") ||
IsFileOfType(file, ".tif") ||
IsFileOfType(file, ".tga") ||
IsFileOfType(file, ".bmp") ||
IsFileOfType(file, ".dds") ||
IsFileOfType(file, ".exr") ||
IsFileOfType(file, ".iff") ||
IsFileOfType(file, ".pict");
}
///
/// Does string end in a mesh file type that Unity supports?
/// (fbx, dae, mb, ma, max, blend, obj, 3ds, dxf)
///
///
///
public static bool IsMeshFile(this string file)
{
return IsFileOfType(file, ".fbx") ||
IsFileOfType(file, ".dae") ||
IsFileOfType(file, ".mb") ||
IsFileOfType(file, ".ma") ||
IsFileOfType(file, ".max") ||
IsFileOfType(file, ".blend") ||
IsFileOfType(file, ".obj") ||
IsFileOfType(file, ".3ds") ||
IsFileOfType(file, ".dxf");
}
///
/// Does string end in a sound file type that Unity supports?
/// (wav, mp3, ogg, aif, xm, mod, it, s3m)
///
///
///
public static bool IsSoundFile(this string file)
{
return IsFileOfType(file, ".wav") ||
IsFileOfType(file, ".mp3") ||
IsFileOfType(file, ".ogg") ||
IsFileOfType(file, ".aif") ||
IsFileOfType(file, ".xm") ||
IsFileOfType(file, ".mod") ||
IsFileOfType(file, ".it") ||
IsFileOfType(file, ".s3m");
}
///
/// Does string end in a Unity animation file type?
/// (anim, controller, mask)
///
///
///
public static bool IsAnimationFile(this string file)
{
return IsFileOfType(file, ".anim") || // animation file
IsFileOfType(file, ".controller") || // animator controller (mecanim state machine)
IsFileOfType(file, ".mask"); // avatar mask
}
///
/// Does string end in a Unity asset file type?
/// (unity, prefab, asset, mat, flare, physicMaterial, guiskin, mixer, anim, controller, mask)
///
///
///
public static bool IsUnityAssetFile(this string file)
{
return IsFileOfType(file, ".unity") || // scene files
IsFileOfType(file, ".prefab") ||
IsFileOfType(file, ".asset") || // scriptable objects, terrain files
IsFileOfType(file, ".mat") || // materials
IsFileOfType(file, ".flare") ||
IsFileOfType(file, ".physicMaterial") ||
IsFileOfType(file, ".guiskin") || // IMGUI skins
IsFileOfType(file, ".mixer") || // audio mixer
IsAnimationFile(file);
}
// high-level filename checks
public static bool IsFileInBuildReportFolder(string filepath)
{
return filepath.DoesFileBeginWith("BRT_") || filepath.DoesFileBeginWith("DldUtil_") ||
IsFileInAPath(filepath, "/BuildReport/");
}
public static bool IsUselessFile(string filepath)
{
return IsFileName(filepath, "Thumbs.db") || IsFileName(filepath, ".DS_Store") ||
IsFileName(filepath, "._.DS_Store");
}
public static bool IsFileInEditorFolder(string filepath)
{
return IsFileInAPath(filepath, "/Editor/");
}
public static bool IsFileInVersionControlMetadataFolder(string filepath)
{
return IsFileInAPath(filepath, "/.svn/") ||
IsFileInAPath(filepath, "/.git/") ||
IsFileInAPath(filepath, "/.cvs/");
}
public static bool IsFileStreamingAsset(string filepath)
{
return IsFileInAPath(filepath, "/StreamingAssets/");
}
public static bool IsFileOkForDeleteAllOperation(string filepath)
{
return IsUselessFile(filepath) ||
(!IsFileInBuildReportFolder(filepath) &&
!IsFileInEditorFolder(filepath) &&
!IsFileInVersionControlMetadataFolder(filepath) &&
!IsFileAUnixHiddenFile(filepath));
}
// ----------------------------------------------------------------------------------------------------------------------------------------
public static string GetAssetPath(string assetPath)
{
if (IsBuiltInAsset(assetPath))
{
return GetBuiltInAssetHeader(assetPath);
}
return System.IO.Path.GetDirectoryName(assetPath);
}
public static string GetAssetFilename(string assetPath)
{
if (IsBuiltInAsset(assetPath))
{
return GetBuiltInAssetFilename(assetPath);
}
return System.IO.Path.GetFileName(assetPath);
}
static bool IsBuiltInAsset(string assetPath)
{
return assetPath.StartsWith("Built-in ");
}
static string GetBuiltInAssetHeader(string assetPath)
{
bool hasSlash = assetPath.IndexOf("/", StringComparison.Ordinal) > 0;
if (hasSlash)
{
return System.IO.Path.GetDirectoryName(assetPath);
}
return assetPath.Substring(0, assetPath.IndexOf(":", StringComparison.Ordinal));
}
static string GetBuiltInAssetFilename(string assetPath)
{
bool hasSlash = assetPath.IndexOf("/", StringComparison.Ordinal) > 0;
if (hasSlash)
{
return System.IO.Path.GetFileName(assetPath);
}
int idxOfColon = assetPath.IndexOf(":", StringComparison.Ordinal);
if (idxOfColon > -1)
{
if (idxOfColon >= assetPath.Length - 2)
{
// there's nothing else after the colon
// filename is empty
return string.Empty;
}
return assetPath.Substring(idxOfColon + 2, assetPath.Length - idxOfColon - 2); // -2 to get rid of ": "
}
return assetPath;
}
public static string GetAssetPathToNameSeparator(string assetPath)
{
bool hasSlash = assetPath.IndexOf("/", StringComparison.Ordinal) > 0;
if (hasSlash)
{
return "/";
}
return ": ";
}
// ----------------------------------------------------------------------------------------------------------------------------------------
public static string GetPackageFileContents(string filename)
{
// try default path first
string defaultBuildReportToolFullPath =
Application.dataPath + "/" + BuildReportTool.Options.BUILD_REPORT_TOOL_DEFAULT_FOLDER_NAME;
string filePath = defaultBuildReportToolFullPath + "/" + filename;
if (File.Exists(filePath))
{
return GetTextFileContents(filePath);
}
// not in default path
// search for it
#if BRT_SHOW_MINOR_WARNINGS
Debug.LogWarning(BuildReportTool.Options.BUILD_REPORT_PACKAGE_MOVED_MSG);
#endif
string folderPath = BuildReportTool.Util.FindAssetFolder(Application.dataPath,
BuildReportTool.Options.BUILD_REPORT_TOOL_DEFAULT_FOLDER_NAME);
if (!string.IsNullOrEmpty(folderPath))
{
filePath = folderPath + "/" + filename;
if (File.Exists(filePath))
{
return GetTextFileContents(filePath);
}
}
// could not find it
// giving up
Debug.LogError(BuildReportTool.Options.BUILD_REPORT_PACKAGE_MISSING_MSG);
return "";
}
public static bool ShowFileDeleteProgress(int deletedSoFar, int totalToDelete, string filepath,
bool showRecoverableMsg)
{
float progress = (deletedSoFar + 1) / (float) totalToDelete;
if (EditorUtility.DisplayCancelableProgressBar(
"Deleting file " + (deletedSoFar + 1) + " of " + totalToDelete + " (" + (totalToDelete - deletedSoFar - 1) +
" left)",
filepath,
progress))
{
EditorUtility.ClearProgressBar();
string filesReallyDeletedPlural = deletedSoFar > 1 ? "s" : "";
string cancelTitle = "Delete operation canceled";
string cancelMsg;
if (deletedSoFar > 0)
{
cancelMsg = "Only " + deletedSoFar + " file" + filesReallyDeletedPlural + " (of " + totalToDelete +
") deleted.";
if (showRecoverableMsg)
{
cancelMsg += " Those files can be recovered from your " + BuildReportTool.Util.NameOfOSTrashFolder +
".";
}
}
else
{
cancelMsg = "No files deleted.";
}
EditorApplication.Beep();
EditorUtility.DisplayDialog(cancelTitle, cancelMsg, "OK");
Debug.LogWarning(cancelTitle + ". " + cancelMsg);
return true;
}
return false;
}
// thanks to http://answers.unity3d.com/questions/16804/retrieving-project-name.html
public static string GetProjectName(string projectAssetsFolderPath)
{
var dp = projectAssetsFolderPath;
string[] s = dp.Split("/"[0]);
return s[s.Length - 2];
}
// we have two ways of getting user home folder here:
// from http://stackoverflow.com/questions/1143706/getting-the-path-of-the-home-directory-in-c
public static string UserHomePath
{
get
{
string homePath = (System.Environment.OSVersion.Platform == PlatformID.Unix ||
System.Environment.OSVersion.Platform == PlatformID.MacOSX)
? System.Environment.GetEnvironmentVariable("HOME")
: System.Environment.ExpandEnvironmentVariables("%HOMEDRIVE%%HOMEPATH%");
return homePath;
}
}
//[MenuItem("Window/Test 3")]
public static string GetUserHomeFolder()
{
var ret = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
//Debug.Log("GetUserHomeFolder: " + ret);
ret = ret.Replace("\\", "/");
return ret;
}
//[MenuItem("Window/Test 4")]
public static void OpenInFileBrowserTest()
{
//string path = "/Users/Ferds/Unity Projects/BuildReportTool/BuildReportUnityProject/Assets/BuildReportDebug";
//string path = "/Users/Ferds/Unity Projects/BuildReportTool/BuildReportUnityProject/Assets/BuildReportDebug/EditorMorel.log.txt";
//string path = "/Users/Ferds/UnityBuildReports/";
string path = "/Users/Ferds/UnityBuildReports/test4.xml";
OpenInFileBrowser(path);
}
public static void OpenInMacFileBrowser(string path)
{
bool openInsidesOfFolder = false;
// try mac
string macPath = path.Replace("\\", "/"); // mac finder doesn't like backward slashes
if (Directory.Exists(macPath)) // if path requested is a folder, automatically open insides of that folder
{
openInsidesOfFolder = true;
}
//Debug.Log("macPath: " + macPath);
//Debug.Log("openInsidesOfFolder: " + openInsidesOfFolder);
if (!macPath.StartsWith("\""))
{
macPath = "\"" + macPath;
}
if (!macPath.EndsWith("\""))
{
macPath = macPath + "\"";
}
string arguments = (openInsidesOfFolder ? "" : "-R ") + macPath;
//Debug.Log("arguments: " + arguments);
try
{
System.Diagnostics.Process.Start("open", arguments);
}
catch (System.ComponentModel.Win32Exception e)
{
// tried to open mac finder in windows
// just silently skip error
// we currently have no platform define for the current OS we are in, so we resort to this
e.HelpLink = ""; // do anything with this variable to silence warning about not using it
}
}
public static void OpenInWinFileBrowser(string path)
{
bool openInsidesOfFolder = false;
// try windows
string winPath = path.Replace("/", "\\"); // windows explorer doesn't like forward slashes
if (Directory.Exists(winPath)) // if path requested is a folder, automatically open insides of that folder
{
openInsidesOfFolder = true;
}
try
{
System.Diagnostics.Process.Start("explorer.exe", (openInsidesOfFolder ? "/root," : "/select,") + winPath);
}
catch (System.ComponentModel.Win32Exception e)
{
// tried to open win explorer in mac
// just silently skip error
// we currently have no platform define for the current OS we are in, so we resort to this
e.HelpLink = ""; // do anything with this variable to silence warning about not using it
}
}
public static void OpenInFileBrowser(string path)
{
if (IsInWinOS)
{
OpenInWinFileBrowser(path);
}
else if (IsInMacOS)
{
OpenInMacFileBrowser(path);
}
else // couldn't determine OS
{
OpenInWinFileBrowser(path);
OpenInMacFileBrowser(path);
}
}
public static bool IsInMacOS
{
get { return SystemInfo.operatingSystem.IndexOf("Mac OS", StringComparison.Ordinal) != -1; }
}
public static bool IsInWinOS
{
get { return SystemInfo.operatingSystem.IndexOf("Windows", StringComparison.Ordinal) != -1; }
}
public static string NameOfOSFileBrowser
{
get { return (IsInMacOS) ? "Finder" : "Explorer"; }
}
public static string NameOfOSTrashFolder
{
get { return (IsInMacOS) ? "Trash folder" : "Recycle Bin"; }
}
static string GetEditorLogFileInWindows(string editorFilename = "Editor.log")
{
string editorLogSubPath = "/Unity/Editor/" + editorFilename;
// try getting from LOCALAPPDATA
// this is the one used from after Windows XP
string localAppDataVar = System.Environment.GetEnvironmentVariable("LOCALAPPDATA");
if (!string.IsNullOrEmpty(localAppDataVar))
{
string nonXpStyleAppDataPath = localAppDataVar.Replace("\\", "/");
if (Directory.Exists(nonXpStyleAppDataPath))
{
return nonXpStyleAppDataPath + editorLogSubPath;
}
}
// didn't find it in LOCALAPPDATA
// try USERPROFILE (WinXP style)
string userProfileVar = System.Environment.GetEnvironmentVariable("USERPROFILE");
if (!string.IsNullOrEmpty(userProfileVar))
{
string xpStyleAppDataPath = userProfileVar.Replace("\\", "/") + "/Local Settings/Application Data";
if (Directory.Exists(xpStyleAppDataPath))
{
return xpStyleAppDataPath + editorLogSubPath;
}
}
Debug.LogError("Could not find path to Unity Editor log!");
return "";
}
public static string EditorLogDefaultPath
{
get
{
if (System.Environment.OSVersion.Platform == PlatformID.Unix ||
System.Environment.OSVersion.Platform == PlatformID.MacOSX)
{
return UserHomePath + "/Library/Logs/Unity/Editor.log";
}
return GetEditorLogFileInWindows();
}
}
public static string EditorPrevLogPath
{
get
{
if (System.Environment.OSVersion.Platform == PlatformID.Unix ||
System.Environment.OSVersion.Platform == PlatformID.MacOSX)
{
return UserHomePath + "/Library/Logs/Unity/Editor-prev.log";
}
return GetEditorLogFileInWindows("Editor-prev.log");
}
}
public static string UsedEditorLogPath
{
get
{
if (IsDefaultEditorLogPathOverridden)
{
return BuildReportTool.Options.EditorLogOverridePath;
}
return EditorLogDefaultPath;
}
}
public static string EditorLogPathOverrideMessage
{
get
{
if (IsDefaultEditorLogPathOverridden)
{
return "(Overridden)";
}
return "(Default)";
}
}
public static bool IsDefaultEditorLogPathOverridden
{
get { return !string.IsNullOrEmpty(BuildReportTool.Options.EditorLogOverridePath); }
}
public static bool UsedEditorLogExists
{
get { return File.Exists(UsedEditorLogPath); }
}
public static string GetBuildManagedFolder(string buildFilePath)
{
string buildFolder = buildFilePath;
const string WINDOWS_APP_FILE_TYPE = ".exe";
const string LINUX_32_APP_FILE_TYPE = ".x86";
const string LINUX_64_APP_FILE_TYPE = ".x86_64";
const string MAC_APP_FILE_TYPE = ".app";
if (buildFolder.EndsWith(WINDOWS_APP_FILE_TYPE, StringComparison.OrdinalIgnoreCase)) // Windows Standalone
{
//
// example:
// "/Users/Ferds/Unity Projects/BuildReportTool/testwin64.exe"
//
// need to remove ".exe" at end
// then append "_Data" at end
//
buildFolder = buildFolder.Substring(0, buildFolder.Length - WINDOWS_APP_FILE_TYPE.Length);
buildFolder += "_Data/Managed";
}
else if (buildFolder.EndsWith(LINUX_32_APP_FILE_TYPE, StringComparison.OrdinalIgnoreCase)
) // Linux 32-bit Standalone
{
//
// example:
// "/Users/Ferds/Unity Projects/BuildReportTool/test.x86"
//
// need to remove ".x86" at end
// then append "_Data" at end
//
buildFolder = buildFolder.Substring(0, buildFolder.Length - LINUX_32_APP_FILE_TYPE.Length);
buildFolder += "_Data/Managed";
}
else if (buildFolder.EndsWith(LINUX_64_APP_FILE_TYPE, StringComparison.OrdinalIgnoreCase)
) // Linux 64-bit Standalone
{
//
// example:
// "/Users/Ferds/Unity Projects/BuildReportTool/test.x86_64"
//
// need to remove ".x86_64" at end
// then append "_Data" at end
//
buildFolder = buildFolder.Substring(0, buildFolder.Length - LINUX_64_APP_FILE_TYPE.Length);
buildFolder += "_Data/Managed";
}
else if (buildFolder.EndsWith(MAC_APP_FILE_TYPE, StringComparison.OrdinalIgnoreCase)) // Mac OS X
{
//
// example:
// "/Users/Ferds/Unity Projects/BuildReportTool/testmac.app"
//
// .app is really just a folder.
//
buildFolder += "/Contents/Data/Managed";
}
else if (Directory.Exists(buildFolder + "/Data/Managed/")) // iOS
{
buildFolder += "/Data/Managed";
}
else if (!Directory.Exists(buildFolder))
{
// happens with users who use custom build scripts
//Debug.LogWarning("Folder \"" + buildFolder + "\" does not exist.");
return "";
}
buildFolder += "/";
return buildFolder;
}
public static string GetBuildDataFolder(string buildFilePath)
{
string buildFolder = buildFilePath;
const string WINDOWS_APP_FILE_TYPE = ".exe";
const string LINUX_32_APP_FILE_TYPE = ".x86";
const string LINUX_64_APP_FILE_TYPE = ".x86_64";
const string MAC_APP_FILE_TYPE = ".app";
if (buildFolder.EndsWith(WINDOWS_APP_FILE_TYPE, StringComparison.OrdinalIgnoreCase)) // Windows
{
//
// example:
// "/Users/Ferds/Unity Projects/BuildReportTool/testwin64.exe"
//
// need to remove ".exe" at end
// then append "_Data" at end
//
buildFolder = buildFolder.Substring(0, buildFolder.Length - WINDOWS_APP_FILE_TYPE.Length);
buildFolder += "_Data";
}
else if (buildFolder.EndsWith(LINUX_32_APP_FILE_TYPE, StringComparison.OrdinalIgnoreCase)
) // Linux 32-bit Standalone
{
//
// example:
// "/Users/Ferds/Unity Projects/BuildReportTool/test.x86"
//
// need to remove ".x86" at end
// then append "_Data" at end
//
buildFolder = buildFolder.Substring(0, buildFolder.Length - LINUX_32_APP_FILE_TYPE.Length);
buildFolder += "_Data";
}
else if (buildFolder.EndsWith(LINUX_64_APP_FILE_TYPE, StringComparison.OrdinalIgnoreCase)
) // Linux 64-bit Standalone
{
//
// example:
// "/Users/Ferds/Unity Projects/BuildReportTool/test.x86_64"
//
// need to remove ".x86_64" at end
// then append "_Data" at end
//
buildFolder = buildFolder.Substring(0, buildFolder.Length - LINUX_64_APP_FILE_TYPE.Length);
buildFolder += "_Data";
}
else if (buildFolder.EndsWith(MAC_APP_FILE_TYPE, StringComparison.OrdinalIgnoreCase)) // Mac OS X
{
//
// example:
// "/Users/Ferds/Unity Projects/BuildReportTool/testmac.app"
//
// .app is really just a folder.
//
buildFolder += "/Contents/Data";
}
else if (Directory.Exists(buildFolder + "/Data")) // iOS
{
buildFolder += "/Data";
}
else if (!Directory.Exists(buildFolder))
{
// happens with users who use custom builders
//Debug.LogWarning("Folder \"" + buildFolder + "\" does not exist.");
return string.Empty;
}
buildFolder += "/";
return buildFolder;
}
static string GetProjectTempStagingArea(string projectDataPath)
{
string tempFolder = projectDataPath;
const string ASSETS = "Assets";
tempFolder = tempFolder.Substring(0, tempFolder.Length - ASSETS.Length);
tempFolder += "Temp/StagingArea";
return tempFolder;
}
public static bool AttemptGetWebTempStagingArea(string projectDataPath, out string path)
{
string tempFolder = GetProjectTempStagingArea(projectDataPath) + "/Data/Managed/";
if (Directory.Exists(tempFolder))
{
path = tempFolder;
return true;
}
path = "";
return false;
}
public static bool AttemptGetAndroidTempStagingArea(string projectDataPath, out string path)
{
string tempFolder = GetProjectTempStagingArea(projectDataPath) + "/assets/bin/Data/Managed/";
//Debug.Log(tempFolder);
if (Directory.Exists(tempFolder))
{
path = tempFolder;
return true;
}
path = "";
return false;
}
public static bool AttemptGetUnityFolderMonoDLLs(bool wasWebBuild, bool wasAndroidApkBuild,
string editorAppContentsPath, ApiCompatibilityLevel monoLevel, StrippingLevel codeStrippingLevel,
out string path, out string higherPriorityPath)
{
bool success = false;
// more hackery
// attempt to get DLL size info
// from Unity install folder
//
// this only happens in:
// 1. Web build
// 2. Android build
// 3. Custom builders
//
string[] pathTries = new string[]
{
editorAppContentsPath + "/Frameworks/Mono/lib/mono",
editorAppContentsPath + "/Mono/lib/mono",
"/Applications/Unity/Unity.app/Contents/Frameworks/Mono/lib/mono",
"C:/Program Files (x86)/Unity/Data/Mono/lib/mono",
"C:/Program Files (x86)/Unity/Editor/Data/Mono/lib/mono",
#if UNITY_3_5
"/Applications/Unity3/Unity.app/Contents/Frameworks/Mono/lib/mono",
"/Applications/Unity 3/Unity.app/Contents/Frameworks/Mono/lib/mono",
"/Applications/Unity3.5/Unity.app/Contents/Frameworks/Mono/lib/mono",
"/Applications/Unity 3.5/Unity.app/Contents/Frameworks/Mono/lib/mono",
"C:/Program Files (x86)/Unity3/Data/Mono/lib/mono",
"C:/Program Files (x86)/Unity 3/Data/Mono/lib/mono",
"C:/Program Files (x86)/Unity3.5/Data/Mono/lib/mono",
"C:/Program Files (x86)/Unity 3.5/Data/Mono/lib/mono",
"C:/Program Files (x86)/Unity3/Editor/Data/Mono/lib/mono",
"C:/Program Files (x86)/Unity 3/Editor/Data/Mono/lib/mono",
#endif
#if UNITY_4_AND_GREATER
"/Applications/Unity4/Unity.app/Contents/Frameworks/Mono/lib/mono",
"/Applications/Unity 4/Unity.app/Contents/Frameworks/Mono/lib/mono",
"C:/Program Files (x86)/Unity4/Data/Mono/lib/mono",
"C:/Program Files (x86)/Unity 4/Data/Mono/lib/mono",
"C:/Program Files (x86)/Unity4/Editor/Data/Mono/lib/mono",
"C:/Program Files (x86)/Unity 4/Editor/Data/Mono/lib/mono",
#endif
};
string tryPath = "";
for (int n = 0, len = pathTries.Length; n < len; ++n)
{
tryPath = pathTries[n];
if (Directory.Exists(tryPath))
{
break;
}
tryPath = "";
}
if (!string.IsNullOrEmpty(tryPath))
{
success = true;
// "unity_web" is obviously for the web build. Presumably, this one has DLLs removed that can compromise web security.
// "2.0" is likely the full featured Mono libraries
// "unity" is most likely the one used when selecting 2.0 subset in the player settings. this is the setting by default.
// "micro" is probably the one used in StrippingLevel.UseMicroMSCorlib. only makes sense to be here when building on Android.
// since in iOS, we already have the DLL files. No need for this hackery in iOS. But since in Android we do not have a project folder,
// we resort to this.
if (wasWebBuild)
{
path = tryPath + "/unity_web/";
}
else if (monoLevel == ApiCompatibilityLevel.NET_2_0_Subset)
{
path = tryPath + "/unity/";
}
else
{
path = tryPath + "/2.0/";
}
#if !UNITY_2018_3_OR_NEWER
if (wasAndroidApkBuild && codeStrippingLevel == StrippingLevel.UseMicroMSCorlib)
{
higherPriorityPath = tryPath + "/micro/";
}
else
#endif
{
higherPriorityPath = "";
}
}
else
{
path = "";
higherPriorityPath = "";
}
return success;
}
public static EditorBuildSettingsScene[] GetAllScenesInBuild()
{
return EditorBuildSettings.scenes;
}
public static BuildReportTool.SizePart CreateSizePartFromFile(string filename, string fileFullPath,
bool getRawSize = true)
{
BuildReportTool.SizePart outPart = new BuildReportTool.SizePart();
outPart.Name = System.Security.SecurityElement.Escape(filename);
if (File.Exists(fileFullPath))
{
if (getRawSize)
{
long fileSizeBytes = GetFileSizeInBytes(fileFullPath);
outPart.RawSizeBytes = fileSizeBytes;
outPart.RawSize = GetBytesReadable(fileSizeBytes);
}
else
{
outPart.RawSizeBytes = -1;
outPart.RawSize = "N/A";
}
long importedSizeBytes = -1;
outPart.ImportedSizeBytes = importedSizeBytes;
outPart.ImportedSize = BuildReportTool.Util.GetBytesReadable(importedSizeBytes);
}
else
{
outPart.RawSizeBytes = -1;
outPart.RawSize = "???";
}
// todo perhaps compute percentage: file size of this DLL out of total build size (would need to convert string of total build size into an int of bytes)
outPart.Percentage = -1;
return outPart;
}
static void SaveTextFile(string saveFilePath, string data)
{
string folder = System.IO.Path.GetDirectoryName(saveFilePath);
if (!string.IsNullOrEmpty(folder))
{
System.IO.Directory.CreateDirectory(folder);
}
#if UNITY_WEBPLAYER && !UNITY_EDITOR
Debug.LogError("Current build target is set to Web Player. Cannot perform file input/output when in Web Player.");
#else
System.IO.StreamWriter
write = new System.IO.StreamWriter(saveFilePath, false,
System.Text.Encoding.UTF8); // Unity's TextAsset.text borks when encoding used is UTF8 :(
write.Write(data);
write.Flush();
write.Close();
write.Dispose();
#endif
}
static string FixXmlBuildReportFile(string serializedBuildInfoFilePath)
{
string xmlData = GetTextFileContents(serializedBuildInfoFilePath);
if (string.IsNullOrEmpty(xmlData))
{
return string.Empty;
}
xmlData = xmlData.Replace("BuildSizePart", "SizePart");
// quick and dirty fix for invalid XML characters in filenames
xmlData = xmlData.Replace("", "");
xmlData = xmlData.Replace("", "");
xmlData = xmlData.Replace("", "");
xmlData = xmlData.Replace("", "");
xmlData = xmlData.Replace("", "");
xmlData = xmlData.Replace("", "");
xmlData = xmlData.Replace("", "");
xmlData = xmlData.Replace("", "");
xmlData = xmlData.Replace("", "");
xmlData = xmlData.Replace("", "");
xmlData = xmlData.Replace("", "");
xmlData = xmlData.Replace("", "");
xmlData = xmlData.Replace("", "");
xmlData = xmlData.Replace("", "");
xmlData = xmlData.Replace("", "");
xmlData = xmlData.Replace("", "");
xmlData = xmlData.Replace("", "");
xmlData = xmlData.Replace("", "");
xmlData = xmlData.Replace("", "");
xmlData = xmlData.Replace("", "");
xmlData = xmlData.Replace("", "");
xmlData = xmlData.Replace("", "");
xmlData = xmlData.Replace("", "");
xmlData = xmlData.Replace("", "");
xmlData = xmlData.Replace("", "");
xmlData = xmlData.Replace("", "");
xmlData = xmlData.Replace("", "");
xmlData = xmlData.Replace("", "");
xmlData = xmlData.Replace("", "");
xmlData = xmlData.Replace("", "");
SaveTextFile(serializedBuildInfoFilePath, xmlData);
return xmlData;
}
public static string MyHtmlDecode(string input)
{
input = input.Replace("<", "<");
input = input.Replace(">", ">");
input = input.Replace("&", "&");
input = input.Replace("'", "'");
input = input.Replace(""", "\"");
input = input.Replace("ñ", "ñ");
input = input.Replace("Ñ", "Ñ");
input = input.Replace("©", "©");
input = input.Replace("®", "®");
input = input.Replace("™", "™");
return input;
}
public static BuildInfo OpenSerializedBuildInfo(string serializedBuildInfoFilePath, bool fromMainThread = true)
{
BuildInfo ret = null;
XmlSerializer x = new XmlSerializer(typeof(BuildInfo));
string correctedXmlData = FixXmlBuildReportFile(serializedBuildInfoFilePath);
try
{
// when the string has contents, it means there were corrections to the xml data
// and we should load that updated content instead of reading the file
if (!string.IsNullOrEmpty(correctedXmlData))
{
TextReader reader = new StringReader(correctedXmlData);
ret = (BuildInfo) x.Deserialize(reader);
}
else
{
// no corrections in the xml file
// proceed to open the file normally
using (FileStream fs = new FileStream(serializedBuildInfoFilePath, FileMode.Open))
{
XmlReader reader = new XmlTextReader(fs);
ret = (BuildInfo) x.Deserialize(reader);
fs.Close();
}
}
}
catch (Exception e)
{
Debug.LogError(e);
}
if (fromMainThread)
{
if (BuildInfoHasContents(ret))
{
ret.OnDeserialize();
ret.SetSavedPath(serializedBuildInfoFilePath);
}
else
{
Debug.LogError("Build Report Tool: Invalid data in build info file: " + serializedBuildInfoFilePath);
}
}
return ret;
}
public static bool BuildInfoHasContents(BuildInfo n)
{
return n != null && n.HasContents;
}
// ---------------------------------
public static string GetBuildInfoDefaultFilename(string projectName, string buildType, System.DateTime timeGot)
{
return string.Format("{0}-{1}-{2}.xml", projectName, buildType, timeGot.ToString("yyyyMMMdd-HHmmss"));
}
public static string GetAssetDependenciesDefaultFilename(string projectName, string buildType, System.DateTime timeGot)
{
return string.Format("DEP-{0}-{1}-{2}.xml", projectName, buildType, timeGot.ToString("yyyyMMMdd-HHmmss"));
}
public static string GetAssetDependenciesFilenameFromBuildInfo(string filepath)
{
var folderPath = System.IO.Path.GetDirectoryName(filepath);
var filename = System.IO.Path.GetFileName(filepath);
return string.Format("{0}/DEP-{1}", folderPath, filename);
}
// ---------------------------------
public static string SerializeBuildInfoAtFolder(BuildInfo buildInfo, string folderPathToSaveTo)
{
string filePath = folderPathToSaveTo;
if (!string.IsNullOrEmpty(folderPathToSaveTo))
{
if (!Directory.Exists(folderPathToSaveTo))
{
Directory.CreateDirectory(folderPathToSaveTo);
}
filePath += "/";
}
//Debug.Log("built folder");
filePath = string.Format("{0}{1}", filePath, buildInfo.GetDefaultFilename());
//Debug.Log("built filepath " + filePath);
SerializeBuildInfo(buildInfo, filePath);
return filePath;
}
public static void SerializeBuildInfo(BuildInfo buildInfo, string xmlFileFullPathToSaveTo)
{
XmlSerializer x = new XmlSerializer(typeof(BuildInfo));
TextWriter writer = new StreamWriter(xmlFileFullPathToSaveTo);
x.Serialize(writer, buildInfo);
writer.Close();
buildInfo.SetSavedPath(xmlFileFullPathToSaveTo);
Debug.Log("Build Report Tool: Saved build info at \"" + buildInfo.SavedPath + "\"");
}
// ---------------------------------
public static AssetDependencies OpenSerializedAssetDependencies(string serializedAssetDependenciesFilePath)
{
AssetDependencies ret = null;
XmlSerializer x = new XmlSerializer(typeof(AssetDependencies));
try
{
// no corrections in the xml file
// proceed to open the file normally
using (FileStream fs = new FileStream(serializedAssetDependenciesFilePath, FileMode.Open))
{
XmlReader reader = new XmlTextReader(fs);
ret = (AssetDependencies) x.Deserialize(reader);
fs.Close();
}
}
catch (Exception e)
{
Debug.LogError(e);
}
if (ret != null)
{
ret.OnAfterLoad();
ret.SetSavedPath(serializedAssetDependenciesFilePath);
}
return ret;
}
public static string SerializeAssetDependenciesAtFolder(AssetDependencies assetDependencies, string folderPathToSaveTo)
{
string filePath = folderPathToSaveTo;
if (!string.IsNullOrEmpty(folderPathToSaveTo))
{
if (!Directory.Exists(folderPathToSaveTo))
{
Directory.CreateDirectory(folderPathToSaveTo);
}
filePath += "/";
}
//Debug.Log("built folder");
filePath = string.Format("{0}{1}", filePath, assetDependencies.GetDefaultFilename());
//Debug.Log("built filepath " + filePath);
SerializeAssetDependencies(assetDependencies, filePath);
return filePath;
}
public static void SerializeAssetDependencies(AssetDependencies assetDependencies, string xmlFileFullPathToSaveTo)
{
assetDependencies.OnBeforeSave();
XmlSerializer x = new XmlSerializer(typeof(AssetDependencies));
TextWriter writer = new StreamWriter(xmlFileFullPathToSaveTo);
x.Serialize(writer, assetDependencies);
writer.Close();
assetDependencies.SetSavedPath(xmlFileFullPathToSaveTo);
Debug.Log("Build Report Tool: Saved asset dependencies at \"" + assetDependencies.SavedPath + "\"");
}
}
} // namespace BuildReportTool