/// <summary> /// Returns a list of relative Unity asset paths contained in <paramref name="assetFolder"/> /// where each path begins with the Assets folder. /// </summary> /// <param name="assetFolder"></param> /// <param name="packageManifest"></param> /// <returns></returns> private static List <string> GetAllAssetPathsRecursively(string assetFolder, PackageManifestConfig packageManifest) { var assetPaths = new List <string> { assetFolder, string.Format(EditorConstants.META_FORMAT, assetFolder) }; var fullProjectPath = Path.GetFullPath(EditorConstants.PROJECT_PATH); var allFilesFullPaths = FileTools.GetAllFilesRecursively(assetFolder); foreach (var fileFullPath in allFilesFullPaths) { // If any of the paths we're looking at match the ignore paths from the user, skip them if (packageManifest.packageIgnorePaths.Any(x => fileFullPath.Contains(Path.GetFullPath(Path.Combine(fullProjectPath, x))))) { continue; } var relativeAssetPath = fileFullPath.Replace(fullProjectPath, string.Empty); assetPaths.Add(relativeAssetPath); } return(assetPaths); }
public static void GenerateVersionConstants(PackageManifestConfig config) { if (string.IsNullOrEmpty(config.versionConstantsPath)) { Debug.LogWarning(NO_PATH_SPECIFIED); return; } // Create folder/file path info var folderPath = Path.GetFullPath(config.versionConstantsPath); var filePath = Path.Combine(folderPath, FILENAME); // Create file contents var template = string.IsNullOrEmpty(config.versionConstantsNamespace) ? GLOBAL_TEMPLATE : TEMPLATE; var fileContents = template .Replace("${namespace}", config.versionConstantsNamespace) .Replace("${version}", config.packageVersion) .Replace("${git_branch}", GitTools.GetBranch()) .Replace("${git_commit}", GitTools.GetLongHeadHash()) .Replace("${publish_date}", DateTime.UtcNow.ToLongDateString()) .Replace("${publish_utc_time}", DateTime.UtcNow.ToString(CultureInfo.InvariantCulture)); File.WriteAllText(filePath, fileContents); var importPath = Path.Combine(config.versionConstantsPath, FILENAME); AssetDatabase.ImportAsset(importPath); }
/// <summary> /// Gather all of the files/folders for the package and export them to the pre-defined location /// at <see cref="PackageManifestConfig.legacyPackageDestinationPath"/>. /// </summary> /// <param name="config"></param> public static void CompileLegacyPackage(PackageManifestConfig config) { // Gathers all of the files/folders for export as a legacy package. var assetPaths = new List <string>(GetAllAssetPathsRecursively(config)); var fileName = string.Format( EditorConstants.UNITY_PACKAGE_NAME_FORMAT, config.displayName.Replace(EditorConstants.EMPTY_SPACE, EditorConstants.UNDERSCORE), config.packageVersion); var finalFilePath = Path.GetFullPath(Path.Combine( Path.Combine( EditorConstants.PROJECT_PATH, config.legacyPackageDestinationPath), fileName)); // Show the UI and kick off the package export. if (!Application.isBatchMode) { EditorUtility.DisplayProgressBar( EditorConstants.PROGRESS_BAR_TITLE_LEGACY, EditorConstants.COMPILING_PROGRESS_MESSAGE, 0); } AssetDatabase.ExportPackage(assetPaths.ToArray(), finalFilePath); if (!Application.isBatchMode) { EditorUtility.RevealInFinder(finalFilePath); EditorUtility.ClearProgressBar(); } }
public static void GenerateVersionConstants(PackageManifestConfig config) { if (string.IsNullOrEmpty(config.versionConstantsPath)) { Debug.LogWarning(NO_PATH_SPECIFIED); return; } // Create folder/file path info var folderPath = Path.GetFullPath(config.versionConstantsPath); var filePath = Path.Combine(folderPath, FILENAME); // Create file contents. If we have a user-supplied template string template; if (!string.IsNullOrEmpty(config.versionTemplateGuid)) { var assetPath = AssetDatabase.GUIDToAssetPath(config.versionTemplateGuid); template = AssetDatabase.LoadAssetAtPath <TextAsset>(assetPath).text; } else if (string.IsNullOrEmpty(AssetDatabase.GUIDToAssetPath(VERSION_CONSTANTS_TEMPLATE_GUID))) { var assetPath = AssetDatabase.GUIDToAssetPath(VERSION_CONSTANTS_TEMPLATE_GUID); template = AssetDatabase.LoadAssetAtPath <TextAsset>(assetPath).text; } else { throw new FileNotFoundException(NO_TEMPLATE_SPECIFIED); } var fileContents = template .Replace("${version}", config.packageVersion) .Replace("${git_branch}", GitTools.GetBranch()) .Replace("${git_commit}", GitTools.GetLongHeadHash()) .Replace("${publish_date}", DateTime.UtcNow.ToLongDateString()) .Replace("${publish_utc_time}", DateTime.UtcNow.ToString(CultureInfo.InvariantCulture)); Debug.LogFormat(WRITE_FILE_LOG_FORMAT, config.versionConstantsPath); File.WriteAllText(filePath, fileContents); var importPath = Path.Combine(config.versionConstantsPath, FILENAME); AssetDatabase.ImportAsset(importPath); }
/// <summary> /// Returns a list of relative Unity asset paths contained in /// <see cref="PackageManifestConfig.packageSourcePaths"/> where each path begins with the Assets /// folder. /// </summary> /// <param name="packageManifest"></param> /// <returns></returns> private static List <string> GetAllAssetPathsRecursively(PackageManifestConfig packageManifest) { var assetPaths = new List <string>(); foreach (var assetFolder in packageManifest.packageSourcePaths) { // If any of the paths we're looking at match the ignore paths from the user, skip them if (packageManifest.packageIgnorePaths.Any(x => Path.GetFullPath(Path.Combine(EditorConstants.PROJECT_PATH, assetFolder)) .Contains(Path.GetFullPath(Path.Combine(EditorConstants.PROJECT_PATH, x))))) { continue; } assetPaths.AddRange(GetAllAssetPathsRecursively(assetFolder, packageManifest)); } return(assetPaths); }
/// <summary> /// Recursively copies all sub-folders and files in <see cref="DirectoryInfo"/> <paramref name="directoryInfo"/> /// from parent folder <see cref="sourcePath"/> to <paramref name="destinationPath"/>. /// </summary> /// <param name="packageManifest"></param> /// <param name="directoryInfo"></param> /// <param name="sourcePath"></param> /// <param name="destinationPath"></param> private static void RecursivelyCopyDirectoriesAndFiles( PackageManifestConfig packageManifest, DirectoryInfo directoryInfo, string sourcePath, string destinationPath) { var normalizedSourcePath = Path.GetFullPath(sourcePath); var normalizedDestinationPath = Path.GetFullPath(destinationPath); var subDirectoryInfo = directoryInfo.GetDirectories(EditorConstants.WILDCARD_FILTER); foreach (var sdi in subDirectoryInfo) { // If any of the paths we're looking at match the ignore paths from the user, skip them if (packageManifest.packageIgnorePaths.Any(x => sdi.FullName.Contains(Path.GetFullPath(Path.Combine(EditorConstants.PROJECT_PATH, x))))) { continue; } Directory.CreateDirectory(sdi.FullName.Replace(normalizedSourcePath, normalizedDestinationPath)); RecursivelyCopyDirectoriesAndFiles(packageManifest, sdi, normalizedSourcePath, normalizedDestinationPath); } var fileInfo = directoryInfo.GetFiles(EditorConstants.WILDCARD_FILTER); foreach (var fi in fileInfo) { // If any of the paths we're looking at match the ignore paths from the user, skip them if (packageManifest.packageIgnorePaths.Any(x => fi.FullName.Contains(Path.GetFullPath(Path.Combine(EditorConstants.PROJECT_PATH, x))))) { continue; } var newPath = Path.GetFullPath(fi.FullName).Replace(normalizedSourcePath, normalizedDestinationPath); File.Copy(fi.FullName, newPath); } }
/// <summary> /// Creates or updates the existing package contents of <see cref="PackageManifestConfig"/> /// <paramref name="packageManifest"/>. /// </summary> /// <param name="packageManifest"></param> public static void CreateOrUpdatePackageSource(PackageManifestConfig packageManifest) { if (!Application.isBatchMode) { EditorUtility.DisplayProgressBar(EditorConstants.PROGRESS_BAR_TITLE, string.Empty, 0f); } try { // Created the folders up to the package json path and then create/import the package.json file. // Its important to have the package.json in the Unity project so that it will have a meta file // Packages without meta files cause warnings/errors when imported. var packageManifestAssetPath = AssetDatabase.GetAssetPath(packageManifest); var parentManifestParentFolderAssetPath = packageManifestAssetPath .Replace(packageManifest.name, string.Empty) .Replace(EditorConstants.ASSET_EXTENSION, string.Empty); var generatedFolderAssetPath = Path.Combine(parentManifestParentFolderAssetPath, EditorConstants.GENERATED_FOLDER_NAME); var fullGeneratedFolderAssetPath = Path.GetFullPath(generatedFolderAssetPath); if (!Directory.Exists(fullGeneratedFolderAssetPath)) { Directory.CreateDirectory(fullGeneratedFolderAssetPath); } var packageJsonFolderAssetPath = Path.Combine(generatedFolderAssetPath, packageManifest.Id); var fullPackageJsonFolderAssetPath = Path.GetFullPath(packageJsonFolderAssetPath); if (!Directory.Exists(fullPackageJsonFolderAssetPath)) { Directory.CreateDirectory(fullPackageJsonFolderAssetPath); } var packageJsonAssetPath = Path.Combine(packageJsonFolderAssetPath, EditorConstants.PACKAGE_JSON_FILENAME); var fullPackageJsonAssetPath = Path.GetFullPath(packageJsonAssetPath); File.WriteAllText(fullPackageJsonAssetPath, packageManifest.GenerateJson()); AssetDatabase.ImportAsset(packageJsonAssetPath, ImportAssetOptions.ForceUpdate); // If the directory exists, delete its contents or make the directory. if (Directory.Exists(packageManifest.packageDestinationPath)) { RecursivelyDeleteDirectoryContents(new DirectoryInfo(packageManifest.packageDestinationPath)); } else { Directory.CreateDirectory(packageManifest.packageDestinationPath); } // Copy over the package json and meta file var destinationPackageJsonPath = Path.Combine(packageManifest.packageDestinationPath, EditorConstants.PACKAGE_JSON_FILENAME); File.Copy(fullPackageJsonAssetPath, destinationPackageJsonPath); var packageJsonMetaPath = string.Format(EditorConstants.META_FORMAT, fullPackageJsonAssetPath); File.Copy(packageJsonMetaPath, Path.Combine(packageManifest.packageDestinationPath, string.Format(EditorConstants.META_FORMAT, EditorConstants.PACKAGE_JSON_FILENAME))); // Copy over all directory and file content from source to destination. var normalizedDestinationPath = Path.GetFullPath(packageManifest.packageDestinationPath); foreach (var sourcePath in packageManifest.packageSourcePaths) { // If its a file, copy over it and its meta file if it exists. var normalizedSourcePath = Path.GetFullPath(sourcePath); if (IsFile(normalizedSourcePath) && File.Exists(normalizedSourcePath)) { var fileInfo = new FileInfo(normalizedSourcePath); if (fileInfo.Directory == null) { continue; } var parentDirectoryPath = fileInfo.Directory.FullName; var newPath = normalizedSourcePath.Replace(parentDirectoryPath, normalizedDestinationPath); File.Copy(normalizedSourcePath, newPath); var sourceMetaPath = string.Format(EditorConstants.META_FORMAT, normalizedSourcePath); if (File.Exists(sourceMetaPath)) { var newMetaPath = sourceMetaPath.Replace(parentDirectoryPath, normalizedDestinationPath); File.Copy(sourceMetaPath, newMetaPath); } } // Otherwise if this is a folder, copy it and all the contents over to the destination folder. else { RecursivelyCopyDirectoriesAndFiles( packageManifest, new DirectoryInfo(normalizedSourcePath), normalizedSourcePath, normalizedDestinationPath); } } Debug.LogFormat(EditorConstants.PACKAGE_UPDATE_SUCCESS_FORMAT, packageManifest.packageName); if (!Application.isBatchMode) { EditorUtility.RevealInFinder(destinationPackageJsonPath); } } catch (Exception ex) { Debug.LogErrorFormat(EditorConstants.PACKAGE_UPDATE_ERROR_FORMAT, packageManifest.packageName); Debug.LogErrorFormat(packageManifest, ex.ToString()); } finally { if (!Application.isBatchMode) { EditorUtility.DisplayProgressBar(EditorConstants.PROGRESS_BAR_TITLE, string.Empty, 1f); EditorUtility.ClearProgressBar(); } } }
/// <summary> /// Returns a Json <see cref="string"/> representation of the <see cref="PackageManifestConfig"/> /// <paramref name="packageManifest"/>. /// </summary> /// <param name="packageManifest"></param> /// <returns></returns> public static string GenerateJson(PackageManifestConfig packageManifest) { // Clear string builder JSON_STRING_BUILDER.Length = 0; JSON_STRING_BUILDER.Append(OPEN_BRACES); JSON_STRING_BUILDER.AppendFormat(NAME, packageManifest.packageName); JSON_STRING_BUILDER.Append(COMMA); JSON_STRING_BUILDER.AppendFormat(DISPLAY_NAME, packageManifest.displayName); JSON_STRING_BUILDER.Append(COMMA); JSON_STRING_BUILDER.AppendFormat(PACKAGE_VERSION, packageManifest.packageVersion); JSON_STRING_BUILDER.Append(COMMA); JSON_STRING_BUILDER.AppendFormat(UNITY_VERSION, packageManifest.unityVersion); JSON_STRING_BUILDER.Append(COMMA); JSON_STRING_BUILDER.AppendFormat(DESCRIPTION, packageManifest.description); JSON_STRING_BUILDER.Append(COMMA); // Add the keywords if any exist. if (packageManifest.keywords != null && packageManifest.keywords.Length > 0) { JSON_STRING_BUILDER.Append(KEYWORDS); JSON_STRING_BUILDER.Append(OPEN_BRACKET); for (var i = 0; i < packageManifest.keywords.Length; i++) { var keyword = packageManifest.keywords[i]; JSON_STRING_BUILDER.AppendFormat(KEYWORD_CHILD, keyword); if (i != packageManifest.keywords.Length - 1) { JSON_STRING_BUILDER.Append(COMMA); } } JSON_STRING_BUILDER.Append(CLOSED_BRACKET); JSON_STRING_BUILDER.Append(COMMA); } JSON_STRING_BUILDER.AppendFormat(CATEGORY, packageManifest.category); // If the required author field name is present, create an author block, otherwise skip if (!string.IsNullOrEmpty(packageManifest.author.name)) { JSON_STRING_BUILDER.Append(COMMA); JSON_STRING_BUILDER.Append(AUTHOR); JSON_STRING_BUILDER.Append(OPEN_BRACES); JSON_STRING_BUILDER.AppendFormat(AUTHOR_NAME, packageManifest.author.name); JSON_STRING_BUILDER.Append(COMMA); JSON_STRING_BUILDER.AppendFormat(AUTHOR_EMAIL, packageManifest.author.email); JSON_STRING_BUILDER.Append(COMMA); JSON_STRING_BUILDER.AppendFormat(AUTHOR_URL, packageManifest.author.url); JSON_STRING_BUILDER.Append(CLOSED_BRACES); } // Add the dependencies block if any exist. if (packageManifest.dependencies != null && packageManifest.dependencies.Length > 0) { JSON_STRING_BUILDER.Append(COMMA); JSON_STRING_BUILDER.Append(DEPENDENCIES); JSON_STRING_BUILDER.Append(OPEN_BRACES); for (var i = 0; i < packageManifest.dependencies.Length; i++) { var dependency = packageManifest.dependencies[i]; if (string.IsNullOrEmpty(dependency.packageName) || string.IsNullOrEmpty(dependency.packageVersion)) { continue; } JSON_STRING_BUILDER.AppendFormat( DEPENDENCY_CHILD_FORMAT, dependency.packageName, dependency.packageVersion); if (i != packageManifest.dependencies.Length - 1) { JSON_STRING_BUILDER.Append(COMMA); } } JSON_STRING_BUILDER.Append(CLOSED_BRACES); } JSON_STRING_BUILDER.Append(CLOSED_BRACES); return(JSON_STRING_BUILDER.ToString()); }
/// <summary> /// Returns a Json <see cref="string"/> representation of the <see cref="PackageManifestConfig"/> /// <paramref name="packageManifest"/>. /// </summary> /// <param name="packageManifest"></param> /// <returns></returns> public static string GenerateJson(PackageManifestConfig packageManifest) { // Clear string builder _jsonStringBuilder.Length = 0; _jsonStringBuilder.Append(OpenBraces); _jsonStringBuilder.AppendFormat(Name, packageManifest.packageName); _jsonStringBuilder.Append(Comma); _jsonStringBuilder.AppendFormat(DisplayName, packageManifest.displayName); _jsonStringBuilder.Append(Comma); _jsonStringBuilder.AppendFormat(PackageVersion, packageManifest.packageVersion); _jsonStringBuilder.Append(Comma); _jsonStringBuilder.AppendFormat(UnityVersion, packageManifest.unityVersion); _jsonStringBuilder.Append(Comma); _jsonStringBuilder.AppendFormat(Description, packageManifest.description); _jsonStringBuilder.Append(Comma); // Add the keywords if any exist. if (packageManifest.keywords != null && packageManifest.keywords.Length > 0) { _jsonStringBuilder.Append(Keywords); _jsonStringBuilder.Append(OpenBracket); for (var i = 0; i < packageManifest.keywords.Length; i++) { var keyword = packageManifest.keywords[i]; _jsonStringBuilder.AppendFormat(KeywordChild, keyword); if (i != packageManifest.keywords.Length - 1) { _jsonStringBuilder.Append(Comma); } } _jsonStringBuilder.Append(ClosedBracket); _jsonStringBuilder.Append(Comma); } _jsonStringBuilder.AppendFormat(Category, packageManifest.category); // Add the dependencies block if any exist. if (packageManifest.dependencies != null && packageManifest.dependencies.Length > 0) { _jsonStringBuilder.Append(Comma); _jsonStringBuilder.Append(Dependencies); _jsonStringBuilder.Append(OpenBraces); for (var i = 0; i < packageManifest.dependencies.Length; i++) { var dependency = packageManifest.dependencies[i]; if (string.IsNullOrEmpty(dependency.packageName) || string.IsNullOrEmpty(dependency.packageVersion)) { continue; } _jsonStringBuilder.AppendFormat( DependencyChildFormat, dependency.packageName, dependency.packageVersion); if (i != packageManifest.dependencies.Length - 1) { _jsonStringBuilder.Append(Comma); } } _jsonStringBuilder.Append(ClosedBraces); } _jsonStringBuilder.Append(ClosedBraces); return(_jsonStringBuilder.ToString()); }