@@ -461,7 +461,7 @@ public class BundleIdChangedEventArgs : EventArgs {
461461 /// <summary>
462462 /// Asset label applied to files managed by this plugin.
463463 /// </summary>
464- private const string ManagedAssetLabel = "gpsr" ;
464+ internal const string ManagedAssetLabel = "gpsr" ;
465465
466466 /// <summary>
467467 /// Get a boolean property from UnityEditor.EditorUserBuildSettings.
@@ -1436,12 +1436,23 @@ private static void ResolveOnAndroidSdkRootChange(
14361436 /// </summary>
14371437 /// <param name="filenames">Files or directories to delete.</param>
14381438 /// <returns>true if files are deleted, false otherwise.</returns>
1439- private static bool DeleteFiles ( IEnumerable < string > filenames )
1440- {
1439+ private static bool DeleteFiles ( IEnumerable < string > filenames ) {
14411440 if ( filenames == null ) return false ;
14421441 var failedToDelete = new List < string > ( ) ;
14431442 foreach ( string artifact in filenames ) {
14441443 failedToDelete . AddRange ( FileUtils . DeleteExistingFileOrDirectory ( artifact ) ) ;
1444+ // Attempt to remove empty parent folders.
1445+ var folder = Path . GetDirectoryName ( artifact ) ;
1446+ while ( ! String . IsNullOrEmpty ( folder ) &&
1447+ ! Path . IsPathRooted ( folder ) &&
1448+ String . Compare ( folder , FileUtils . ASSETS_FOLDER ) != 0 ) {
1449+ if ( Directory . GetFiles ( folder ) . Length != 0 ||
1450+ Directory . GetDirectories ( folder ) . Length != 0 ) {
1451+ break ;
1452+ }
1453+ failedToDelete . AddRange ( FileUtils . DeleteExistingFileOrDirectory ( folder ) ) ;
1454+ folder = Path . GetDirectoryName ( folder ) ;
1455+ }
14451456 }
14461457 var deleteError = FileUtils . FormatError ( "Failed to delete files:" , failedToDelete ) ;
14471458 if ( ! String . IsNullOrEmpty ( deleteError ) ) {
@@ -1937,20 +1948,36 @@ internal static IList<string> GradleMavenReposLines(ICollection<Dependency> depe
19371948 lines . Add ( " maven {" ) ;
19381949 lines . Add ( " url \" https://maven.google.com\" " ) ;
19391950 lines . Add ( " }" ) ;
1951+
1952+ // Consolidate repos url from Packages folders like
1953+ // "Packages/com.company.pkg1/Path/To/m2repository" and
1954+ // "Packages/com.company.pkg2/Path/To/m2repository"
1955+ Dictionary < string , List < string > > repoUriToSources =
1956+ new Dictionary < string , List < string > > ( ) ;
19401957 foreach ( var repoAndSources in GetRepos ( dependencies : dependencies ) ) {
19411958 string repoUri ;
19421959 if ( repoAndSources . Key . StartsWith ( projectFileUri ) && ! exportEnabled ) {
1943- repoUri = String . Format (
1944- "(unityProjectPath + \" /{0}\" )" ,
1945- repoAndSources . Key . Substring ( projectFileUri . Length + 1 ) ) ;
1960+ var repoPath = repoAndSources . Key . Substring ( projectFileUri . Length + 1 ) ;
1961+ repoPath = FileUtils . ReplaceBaseAssetsOrPackagesFolder (
1962+ repoPath , GooglePlayServices . SettingsDialog . LocalMavenRepoDir ) ;
1963+ repoUri = String . Format ( "(unityProjectPath + \" /{0}\" )" , repoPath ) ;
19461964 } else {
19471965 repoUri = String . Format ( "\" {0}\" " , repoAndSources . Key ) ;
19481966 }
1967+ List < string > sources ;
1968+ if ( ! repoUriToSources . TryGetValue ( repoUri , out sources ) ) {
1969+ sources = new List < string > ( ) ;
1970+ repoUriToSources [ repoUri ] = sources ;
1971+ }
1972+ sources . Add ( repoAndSources . Value ) ;
1973+ }
1974+ foreach ( var kv in repoUriToSources ) {
19491975 lines . Add ( " maven {" ) ;
1950- lines . Add ( String . Format ( " url {0} // {1}" , repoUri ,
1951- repoAndSources . Value ) ) ;
1976+ lines . Add ( String . Format ( " url {0} // {1}" , kv . Key ,
1977+ String . Join ( ", " , kv . Value . ToArray ( ) ) ) ) ;
19521978 lines . Add ( " }" ) ;
19531979 }
1980+
19541981 lines . Add ( " mavenLocal()" ) ;
19551982 lines . Add ( " jcenter()" ) ;
19561983 lines . Add ( " mavenCentral()" ) ;
@@ -2168,6 +2195,66 @@ internal static void LabelAssets(IEnumerable<string> assetPaths,
21682195 } , synchronous : synchronous ) ;
21692196 }
21702197
2198+ /// <summary>
2199+ /// Copy asset to target location and apply labels to be managed by this plugin.
2200+ /// </summary>
2201+ /// <param name="sourceLocation">Location to copy from.</param>
2202+ /// <param name="targetLocation">Location to copy to.</param>
2203+ /// <param name="force">If true, this will attempt to delete existing file at target
2204+ /// location. If false, this will return error if target file exists.</param>
2205+ /// <returns>Error message. Empty if no error occurs.</returns>
2206+ internal static string CopyAssetAndLabel ( string sourceLocation , string targetLocation ,
2207+ bool force = false ) {
2208+ if ( String . Compare ( sourceLocation , targetLocation ) == 0 ) {
2209+ return "" ;
2210+ }
2211+ if ( ! File . Exists ( sourceLocation ) ) {
2212+ return String . Format ( "Source file {0} not found." ,
2213+ sourceLocation ) ;
2214+ }
2215+ if ( File . Exists ( targetLocation ) ) {
2216+ if ( force ) {
2217+ if ( FileUtils . DeleteExistingFileOrDirectory ( targetLocation , true ) . Count != 0 ) {
2218+ return String . Format (
2219+ "Failed to remove existing target file {0}." ,
2220+ targetLocation ) ;
2221+ }
2222+ } else {
2223+ return String . Format ( "Target file {0} exists." ,
2224+ targetLocation ) ;
2225+ }
2226+ }
2227+
2228+ var targetDir = Path . GetDirectoryName ( targetLocation ) ;
2229+ if ( ! FileUtils . CreateFolder ( targetDir ) ) {
2230+ return String . Format ( "Failed to create folders at {0}" , targetDir ) ;
2231+ }
2232+
2233+ PlayServicesResolver . Log ( String . Format ( "Copying {0} to {1}" ,
2234+ sourceLocation , targetLocation ) ,
2235+ level : LogLevel . Verbose ) ;
2236+
2237+ if ( ! AssetDatabase . CopyAsset ( sourceLocation , targetLocation ) ) {
2238+ return String . Format ( "Failed to copy {0} to {1}." ,
2239+ sourceLocation , targetLocation ) ;
2240+ }
2241+
2242+ var unlabeledAssets = new HashSet < string > ( ) ;
2243+ LabelAssets (
2244+ new [ ] { targetLocation } ,
2245+ complete : ( unlabeled ) => { unlabeledAssets . UnionWith ( unlabeled ) ; } ) ;
2246+ if ( unlabeledAssets . Count != 0 ) {
2247+ return String . Format ( "Cannot label {0} properly." , targetLocation ) ;
2248+ }
2249+
2250+ if ( ! File . Exists ( targetLocation ) ) {
2251+ return String . Format ( "Cannot find the file at target location {0} after copy." ,
2252+ targetLocation ) ;
2253+ }
2254+
2255+ return "" ;
2256+ }
2257+
21712258 /// <summary>
21722259 /// Find the set of assets managed by this plugin.
21732260 /// </summary>
@@ -2209,6 +2296,7 @@ internal static Dictionary<string, string> GetResolutionSettings() {
22092296 { "explodeAars" , SettingsDialogObj . ExplodeAars . ToString ( ) } ,
22102297 { "patchAndroidManifest" , SettingsDialogObj . PatchAndroidManifest . ToString ( ) } ,
22112298 { "patchMainTemplateGradle" , SettingsDialogObj . PatchMainTemplateGradle . ToString ( ) } ,
2299+ { "localMavenRepoDir" , SettingsDialogObj . LocalMavenRepoDir . ToString ( ) } ,
22122300 { "useJetifier" , SettingsDialogObj . UseJetifier . ToString ( ) } ,
22132301 { "bundleId" , GetAndroidApplicationId ( ) } ,
22142302 { "gradleBuildEnabled" , buildSystemSettings . GradleBuildEnabled . ToString ( ) } ,
@@ -2224,6 +2312,7 @@ internal static Dictionary<string, string> GetResolutionSettings() {
22242312 "explodeAars" ,
22252313 "patchAndroidManifest" ,
22262314 "patchMainTemplateGradle" ,
2315+ "localMavenRepoDir" ,
22272316 "useJetifier" ,
22282317 "gradleBuildEnabled" ,
22292318 "gradleTemplateEnabled" ,
0 commit comments