Skip to content

Commit fa1b143

Browse files
committed
Change GetPackageDirectory() to support different type of Package path.
* FileUtils.GetPackageDirectory() is now able to convert package folders between physical path and logical path only recognizable by AssetDatabase. * Added FileUtils.GetPackageDirectoryType() * Added unit tests for these functions Change-Id: I8664321be355e5940edf8c5253f79ca758e214bd
1 parent e5b12e0 commit fa1b143

File tree

5 files changed

+323
-31
lines changed

5 files changed

+323
-31
lines changed

source/AndroidResolver/src/GradleResolver.cs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -163,21 +163,20 @@ internal static string RepoPathToUri(string repoPath, string sourceLocation=null
163163

164164
if (FileUtils.IsUnderDirectory(repoPath, FileUtils.ASSETS_FOLDER)) {
165165
trimmedRepoPath = repoPath.Substring(FileUtils.ASSETS_FOLDER.Length + 1);
166-
} else if (FileUtils.IsUnderDirectory(repoPath, FileUtils.PACKAGES_FOLDER)) {
166+
} else if (FileUtils.IsUnderPackageDirectory(repoPath)) {
167167
// Trim the Packages/package-id/ part
168-
string packageFolder =
169-
FileUtils.GetPackageDirectory(repoPath, actualPath: false);
168+
string packageFolder = FileUtils.GetPackageDirectory(repoPath);
170169
if (!String.IsNullOrEmpty(packageFolder)) {
171170
trimmedRepoPath = repoPath.Substring(packageFolder.Length + 1);
172171
}
173172
}
174173

175174
// Search under Packages/package-id first if Dependencies.xml is from a UPM package.
176-
if (FileUtils.IsUnderDirectory(sourceLocation, FileUtils.PACKAGES_FOLDER)) {
175+
if (FileUtils.IsUnderPackageDirectory(sourceLocation)) {
177176
// Get the physical package directory.
178177
// Ex. Library/PackageCache/[email protected]/
179-
string packageFolder =
180-
FileUtils.GetPackageDirectory(sourceLocation, actualPath: true);
178+
string packageFolder = FileUtils.GetPackageDirectory(
179+
sourceLocation, FileUtils.PackageDirectoryType.PhysicalPath);
181180
if (!String.IsNullOrEmpty(packageFolder)) {
182181
string repoPathUnderPackages =
183182
packageFolder + Path.DirectorySeparatorChar + trimmedRepoPath;

source/VersionHandlerImpl/src/FileUtils.cs

Lines changed: 94 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ namespace Google {
1818
using System;
1919
using System.IO;
2020
using System.Collections.Generic;
21+
using System.Text.RegularExpressions;
2122
using UnityEditor;
2223

2324
/// <summary>
@@ -37,7 +38,19 @@ internal class FileUtils {
3738
/// <summary>
3839
/// The name of Packages folder
3940
/// </summary>
40-
public readonly static string PACKAGES_FOLDER = "Packages";
41+
private readonly static string PACKAGES_FOLDER = "Packages";
42+
43+
/// <summary>
44+
/// Regex to match packages folder like "Packages/com.company.pkg"
45+
/// </summary>
46+
private static Regex PACKAGES_ASSETDB_PATH_REGEX =
47+
new Regex(@"^(Packages[/\\][^/\\]+)([/\\].*)?$");
48+
49+
/// <summary>
50+
/// Regex to match packages folder like "Library/PackageCache/com.company.pkg"
51+
/// </summary>
52+
private static Regex PACKAGES_PHYSICAL_PATH_REGEX =
53+
new Regex(@"^(Library[/\\]PackageCache[/\\])([^/\\]+)(@[^/\\]+)([/\\].*)?$");
4154

4255
/// <summary>
4356
/// Returns the project directory (e.g contains the Assets folder).
@@ -352,42 +365,99 @@ public static bool CheckoutFile(string path, Logger logger) {
352365
/// <param name="directory">Directory to check whether the path is under.</param>
353366
/// <returns>True if the path is under the directory.</returns>
354367
public static bool IsUnderDirectory(string path, string directory) {
368+
if (String.IsNullOrEmpty(directory)) {
369+
return false;
370+
}
355371
if (!directory.EndsWith(Path.DirectorySeparatorChar.ToString())) {
356372
directory = directory + Path.DirectorySeparatorChar;
357373
}
358374
return NormalizePathSeparators(path.ToLower()).StartsWith(directory.ToLower());
359375
}
360376

377+
/// <summary>
378+
/// Enum of different types of package directory.
379+
/// </summary>
380+
public enum PackageDirectoryType {
381+
None = 0,
382+
// Package path like "Packages/package-id", which is logical path only AssetDatabase
383+
// can recognize.
384+
AssetDatabasePath = 1,
385+
// Package path like "Library/PackageCache/package-id@version", which is the physical
386+
// path on the disk.
387+
PhysicalPath = 2
388+
}
389+
390+
/// <summary>
391+
/// Checks if the given path is under the Package directory.
392+
/// </summary>
393+
/// <param name="path">Path to the file/directory.</param>
394+
/// <returns>
395+
/// PackageDirectoryType.None if the path is not under Package directory.
396+
/// PackageDirectoryType.AssetDatabasePath if path matches "Packages/package-id".
397+
/// PackageDirectoryType.PhysicalPath if path matches "Library/PackageCache/package-id".
398+
/// </returns>
399+
public static PackageDirectoryType GetPackageDirectoryType(string path) {
400+
if (PACKAGES_ASSETDB_PATH_REGEX.IsMatch(path)) {
401+
return PackageDirectoryType.AssetDatabasePath;
402+
}
403+
if (PACKAGES_PHYSICAL_PATH_REGEX.IsMatch(path)) {
404+
return PackageDirectoryType.PhysicalPath;
405+
}
406+
return PackageDirectoryType.None;
407+
}
408+
409+
/// <summary>
410+
/// Checks if the given path is under the Package directory.
411+
/// </summary>
412+
/// <param name="path">Path to the file/directory.</param>
413+
/// <returns> True if the path is under package directory.</returns>
414+
public static bool IsUnderPackageDirectory(string path) {
415+
return GetPackageDirectoryType(path) != PackageDirectoryType.None;
416+
}
417+
361418
/// <summary>
362419
/// Get the package directory from the path.
363420
/// The package directory should look like "Packages/package-id", where package id is
364421
/// the Unity Package Manager package name.
365-
/// Ex. "Packages/com.google.unity-jar-resolver" if actualPath is false, or
366-
/// "Library/PackageCache/[email protected]/" if true.
367-
/// Logical path is
368422
/// Note that there is no way to get physical path if the package is installed from disk.
369423
/// </summary>
370424
/// <param name="path">Path to the file/directory.</param>
371-
/// <param name="actualPath">If false, return logical path only recognizable by
372-
/// AssetDatabase. Otherwise, return physical path of the package.</param>
373-
/// <returns>Package directory part of the given path. Empty string if the path is not valid
374-
/// .</returns>
375-
public static string GetPackageDirectory(string path, bool actualPath) {
376-
if (!IsUnderDirectory(path, PACKAGES_FOLDER)) {
377-
return "";
378-
}
379-
380-
string[] components = SplitPathIntoComponents(path);
381-
if (components.Length < 2) {
382-
return "";
383-
}
384-
385-
string packageDir = components[0] + Path.DirectorySeparatorChar + components[1];
386-
if (actualPath) {
387-
// This only works if the package is NOT installed from disk. That is, it should
388-
// work if the package is installed from a local tarball or from a registry server.
389-
string absolutePath = Path.GetFullPath(packageDir);
390-
packageDir = absolutePath.Substring(ProjectDirectory.Length + 1);
425+
/// <param name="directoryType">
426+
/// If PackageDirectoryType.None, return package directoy as it is in the path.
427+
/// If PackageDirectoryType.AssetDatabasePath, return package directory like
428+
/// "Packages/package-id".
429+
/// If PackageDirectoryType.PhysicalPath, return package directory like
430+
/// "Library/PackageCache/package-id@version".
431+
/// </param>
432+
/// <returns>Package directory part of the given path. Empty string if the path is not under
433+
/// package directory.</returns>
434+
public static string GetPackageDirectory(
435+
string path,
436+
PackageDirectoryType directoryType = PackageDirectoryType.None) {
437+
string packageDir = null;
438+
var nameMatch = PACKAGES_ASSETDB_PATH_REGEX.Match(path);
439+
if (nameMatch.Success) {
440+
packageDir = nameMatch.Groups[1].Value;
441+
if (directoryType == PackageDirectoryType.PhysicalPath) {
442+
// This only works if the package is NOT installed from disk. That is, it should
443+
// work if the package is installed from a local tarball or from a registry
444+
// server.
445+
string absolutePath = Path.GetFullPath(packageDir);
446+
packageDir = absolutePath.Substring(ProjectDirectory.Length + 1);
447+
}
448+
} else {
449+
nameMatch = PACKAGES_PHYSICAL_PATH_REGEX.Match(path);
450+
if (nameMatch.Success) {
451+
if (directoryType == PackageDirectoryType.AssetDatabasePath) {
452+
packageDir = Path.Combine(PACKAGES_FOLDER, nameMatch.Groups[2].Value);
453+
} else {
454+
packageDir = nameMatch.Groups[1].Value +
455+
nameMatch.Groups[2].Value +
456+
nameMatch.Groups[3].Value;
457+
}
458+
} else {
459+
packageDir = "";
460+
}
391461
}
392462

393463
return packageDir;

source/VersionHandlerImpl/src/VersionHandlerImpl.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ public string ManifestName {
359359
/// false otherwise.</return>
360360
public bool IsReadOnly {
361361
get {
362-
return FileUtils.IsUnderDirectory(filename, FileUtils.PACKAGES_FOLDER);
362+
return FileUtils.IsUnderPackageDirectory(filename);
363363
}
364364
}
365365

source/VersionHandlerImpl/unit_tests/VersionHandlerImplTests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
<ItemGroup>
4444
<Compile Include="src\EditorMeasurementTest.cs" />
4545
<Compile Include="src\ProjectSettingsTest.cs" />
46+
<Compile Include="src\FileUtilsTest.cs" />
4647
</ItemGroup>
4748
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
4849
<ItemGroup>

0 commit comments

Comments
 (0)