/// <summary> /// Search for the POM file associated with the specified maven artifact and patch the /// packaging reference if the POM doesn't reference the artifact. /// file. /// </summary> /// <param name="artifactFilename">artifactFilename</param> /// <param name="sourceFilename">If artifactFilename is copied from a different location, /// pass the original location where POM file lives.</param> /// <returns>true if successful, false otherwise.</returns> public static bool PatchPomFile(string artifactFilename, string sourceFilename) { if (sourceFilename == null) { sourceFilename = artifactFilename; } if (FileUtils.IsUnderPackageDirectory(artifactFilename)) { // File under Packages folder is immutable. PlayServicesResolver.Log( String.Format("Cannot patch POM from Packages directory since it is immutable" + " ({0})", artifactFilename), level: LogLevel.Error); return(false); } var failureImpact = String.Format("{0} may not be included in your project", Path.GetFileName(artifactFilename)); var pomFilename = PathWithoutExtension(artifactFilename) + ".pom"; // Copy POM file if artifact has been copied from a different location as well. if (String.Compare(sourceFilename, artifactFilename) != 0 && !File.Exists(pomFilename)) { var sourcePomFilename = PathWithoutExtension(sourceFilename) + ".pom"; var error = PlayServicesResolver.CopyAssetAndLabel( sourcePomFilename, pomFilename); if (!String.IsNullOrEmpty(error)) { PlayServicesResolver.Log( String.Format("Failed to copy POM from {0} to {1} due to:\n{2}", sourcePomFilename, pomFilename, error), level: LogLevel.Error); return(false); } } var artifactPackaging = Path.GetExtension(artifactFilename).ToLower().Substring(1); var pom = new XmlDocument(); try { using (var stream = new StreamReader(pomFilename)) { pom.Load(stream); } } catch (Exception ex) { PlayServicesResolver.Log( String.Format("Unable to read maven POM {0} for {1} ({2}). " + failureImpact, pom, artifactFilename, ex), level: LogLevel.Error); return(false); } bool updatedPackaging = false; XmlNodeList packagingNode = pom.GetElementsByTagName("packaging"); foreach (XmlNode node in packagingNode) { if (node.InnerText != artifactPackaging) { PlayServicesResolver.Log(String.Format( "Replacing packaging of maven POM {0} {1} --> {2}", pomFilename, node.InnerText, artifactPackaging), level: LogLevel.Verbose); node.InnerText = artifactPackaging; updatedPackaging = true; } } if (!FileUtils.CheckoutFile(pomFilename, PlayServicesResolver.logger)) { PlayServicesResolver.Log( String.Format("Unable to checkout '{0}' to patch the file for inclusion in a " + "Gradle project.", pomFilename), LogLevel.Error); return(false); } if (updatedPackaging) { try { using (var xmlWriter = XmlWriter.Create(pomFilename, new XmlWriterSettings { Indent = true, IndentChars = " ", NewLineChars = "\n", NewLineHandling = NewLineHandling.Replace })) { pom.Save(xmlWriter); } } catch (Exception ex) { PlayServicesResolver.Log( String.Format("Unable to write patch maven POM {0} for {1} with " + "packaging {2} ({3}). " + failureImpact, pom, artifactFilename, artifactPackaging, ex)); return(false); } } return(true); }
/// <summary> /// Copy srcaar files to aar files that are excluded from Unity's build process. /// </summary> /// <param name="dependencies">Dependencies to inject.</param> /// <returns>true if successful, false otherwise.</returns> private static bool CopySrcAars(ICollection <Dependency> dependencies) { bool succeeded = true; var aarFiles = new List <KeyValuePair <string, string> >(); // Copy each .srcaar file to .aar while configuring the plugin importer to ignore the // file. foreach (var aar in LocalMavenRepository.FindAarsInLocalRepos(dependencies)) { // Only need to copy for .srcaar if (Path.GetExtension(aar).CompareTo(".srcaar") != 0) { continue; } var aarPath = aar; if (FileUtils.IsUnderPackageDirectory(aar)) { // Physical paths work better for copy operations than // logical Unity paths. var physicalPackagePath = FileUtils.GetPackageDirectory(aar, FileUtils.PackageDirectoryType.PhysicalPath); aarPath = FileUtils.ReplaceBaseAssetsOrPackagesFolder( aar, physicalPackagePath); } var dir = FileUtils.ReplaceBaseAssetsOrPackagesFolder( Path.GetDirectoryName(aar), GooglePlayServices.SettingsDialog.LocalMavenRepoDir); var filename = Path.GetFileNameWithoutExtension(aarPath); var targetFilename = Path.Combine(dir, filename + ".aar"); // Avoid situations where we can have a mix of file path // separators based on platform. aarPath = FileUtils.NormalizePathSeparators(aarPath); targetFilename = FileUtils.NormalizePathSeparators( targetFilename); bool configuredAar = File.Exists(targetFilename); if (!configuredAar) { var error = PlayServicesResolver.CopyAssetAndLabel( aarPath, targetFilename); if (String.IsNullOrEmpty(error)) { try { PluginImporter importer = (PluginImporter)AssetImporter.GetAtPath( targetFilename); importer.SetCompatibleWithAnyPlatform(false); importer.SetCompatibleWithPlatform(BuildTarget.Android, false); configuredAar = true; } catch (Exception ex) { PlayServicesResolver.Log(String.Format( "Failed to disable {0} from being included by Unity's " + "internal build. {0} has been deleted and will not be " + "included in Gradle builds. ({1})", aar, ex), level: LogLevel.Error); } } else { PlayServicesResolver.Log(String.Format( "Unable to copy {0} to {1}. {1} will not be included in Gradle " + "builds. Reason: {2}", aarPath, targetFilename, error), level: LogLevel.Error); } } if (configuredAar) { aarFiles.Add(new KeyValuePair <string, string>(aarPath, targetFilename)); // Some versions of Unity do not mark the asset database as dirty when // plugin importer settings change so reimport the asset to synchronize // the state. AssetDatabase.ImportAsset(targetFilename, ImportAssetOptions.ForceUpdate); } else { if (File.Exists(targetFilename)) { AssetDatabase.DeleteAsset(targetFilename); } succeeded = false; } } foreach (var keyValue in aarFiles) { succeeded &= LocalMavenRepository.PatchPomFile(keyValue.Value, keyValue.Key); } return(succeeded); }