public void JetifierMigratesIndividualLayoutFiles() { var migratedLayout = Utils.GetTempFilename(); var supportLayout = CreateFile("supportlayout.xml", @"<?xml version=""1.0"" encoding=""utf-8""?> <RelativeLayout xmlns:android=""http://schemas.android.com/apk/res/android"" android:orientation=""vertical"" android:layout_width=""match_parent"" android:layout_height=""match_parent""> <android.support.v7.widget.AppCompatButton android:id=""@+id/appcompatButton"" android:layout_width=""wrap_content"" android:layout_height=""wrap_content"" android:layout_centerInParent=""true"" android:text=""AppCompat Button"" /> </RelativeLayout>"); var jetifier = new Jetifier(); var result = jetifier.Jetify(supportLayout, migratedLayout); Assert.True(result); Assert.Equal( "androidx.appcompat.widget.AppCompatButton", XDocument.Load(migratedLayout).Root.Elements().FirstOrDefault().Name.LocalName); }
public void JavaTypesAreMigratedAfterJetifierWithIntermediate() { var migratedAar = Utils.GetTempFilename(); var jetifier = new Jetifier(); jetifier.UseIntermediateFile = true; var result = jetifier.Jetify(SupportAar, migratedAar); Assert.True(result); var jar = ReadAarEntry(migratedAar, "classes.jar"); var classPath = new ClassPath(); classPath.Load(jar); var packages = classPath.GetPackages(); Assert.True(packages.Count > 0); Assert.Equal("com.xamarin.aarxercise", packages.Keys.FirstOrDefault()); var classes = packages["com.xamarin.aarxercise"]; var simpleFragment = classes.FirstOrDefault(c => c.ThisClass.Name.Value == "com/xamarin/aarxercise/SimpleFragment"); Assert.Equal("androidx/fragment/app/Fragment", simpleFragment.SuperClass.Name.Value); }
public void JetifierMigratesIndividualProguardFiles() { var migratedLayout = Utils.GetTempFilename(); var supportLayout = CreateFile("proguard.txt", @" -keepclassmembers class android.support.v7.widget.AppCompatButton { public *; }"); var jetifier = new Jetifier(); var result = jetifier.Jetify(supportLayout, migratedLayout); Assert.True(result); Assert.Contains("androidx.appcompat.widget.AppCompatButton", File.ReadAllText(migratedLayout)); }
protected override bool OnInvoke(IEnumerable <string> extras) { var archivePairs = Archives.Select(a => new MigrationPair(a.Key, a.Value)).ToArray(); var jetifier = new Jetifier { Verbose = Program.Verbose, JavaPath = JavaPath, Parallel = Parallel, UseIntermediateFile = UseIntermediateFile, }; jetifier.MessageLogged += (sender, e) => LogToolMessage(e); return(jetifier.Jetify(archivePairs)); }
//[Fact] public async Task JetifierWrapperMigratesFacebookAar() { var facebookFilename = "facebook-android-sdk"; var facebookVersion = "4.40.0"; var facebookFullName = $"{facebookFilename}-{facebookVersion}"; var facebookTestUrl = $"https://origincache.facebook.com/developers/resources/?id={facebookFullName}.zip"; var workspace = Utils.GetTempFilename(); Directory.CreateDirectory(workspace); // download facebook var facebookZip = Path.Combine(workspace, "facebook.zip"); await Utils.DownloadFileAsync(facebookTestUrl, facebookZip); ZipFile.ExtractToDirectory(facebookZip, workspace); // run jetifier var aarFiles = Directory.GetFiles(workspace, "*.aar", SearchOption.AllDirectories); var pairs = aarFiles.Select(f => new MigrationPair(f, Path.ChangeExtension(f, "jetified.aar"))).ToArray(); var jetifier = new Jetifier(); var result = jetifier.Jetify(pairs); Assert.True(result); // read the classes var commonAar = pairs.FirstOrDefault(pair => Path.GetFileNameWithoutExtension(pair.Source) == "facebook-common"); var jar = ReadAarEntry(commonAar.Destination, "classes.jar"); var classPath = new ClassPath(); classPath.Load(jar); var packages = classPath.GetPackages(); // read the type var classes = packages["com.facebook"]; var activity = classes.FirstOrDefault(c => c.ThisClass.Name.Value == "com/facebook/FacebookActivity"); // read the layout var migratedLayout = ReadAarEntry(commonAar.Destination, "res/layout/com_facebook_device_auth_dialog_fragment.xml"); // check Assert.Equal("androidx/fragment/app/FragmentActivity", activity.SuperClass.Name.Value); Assert.Equal( "androidx.cardview.widget.CardView", XDocument.Load(migratedLayout).Root.Name.LocalName); }
public void JetifierMigratesLayoutFiles() { var migratedAar = Utils.GetTempFilename(); var jetifier = new Jetifier(); var result = jetifier.Jetify(SupportAar, migratedAar); Assert.True(result); var migratedLayout = ReadAarEntry(migratedAar, "res/layout/supportlayout.xml"); var androidxLayout = ReadAarEntry(AndroidXAar, "res/layout/supportlayout.xml"); Assert.Equal( "androidx.appcompat.widget.AppCompatButton", XDocument.Load(migratedLayout).Root.Elements().FirstOrDefault().Name.LocalName); Assert.Equal( "androidx.appcompat.widget.AppCompatButton", XDocument.Load(androidxLayout).Root.Elements().FirstOrDefault().Name.LocalName); }
public void CanReadJarFileAfterMigration() { var migratedAar = Utils.GetTempFilename(); var jetifier = new Jetifier(); var result = jetifier.Jetify(SupportAar, migratedAar); Assert.True(result); var jar = ReadAarEntry(migratedAar, "classes.jar"); var classPath = new ClassPath(); classPath.Load(jar); var packages = classPath.GetPackages(); Assert.True(packages.Count > 0); Assert.Equal("com.xamarin.aarxercise", packages.Keys.FirstOrDefault()); var classes = packages["com.xamarin.aarxercise"]; Assert.True(classes.Count > 0); }
public void JetifierMigratesIndividualManifestFiles() { var migratedLayout = Utils.GetTempFilename(); var supportLayout = CreateFile("AndroidManifest.xml", @"<?xml version=""1.0"" encoding=""utf-8""?> <manifest xmlns:android=""http://schemas.android.com/apk/res/android"" android:versionCode=""1"" android:versionName=""1.0"" package=""SimpleWidget.SimpleWidget""> <uses-sdk android:minSdkVersion=""8"" android:targetSdkVersion=""8"" /> <application android:name=""mono.android.app.Application"" android:debuggable=""true""> <service android:name=""android.arch.lifecycle.LifecycleService"" /> </application> </manifest>"); var jetifier = new Jetifier(); var result = jetifier.Jetify(supportLayout, migratedLayout); Assert.True(result); Assert.Contains("<service android:name=\"androidx.lifecycle.LifecycleService\" />", File.ReadAllText(migratedLayout)); }
public override bool Execute() { // make sure there is input if (Files == null || Files.Length == 0) { Log.LogError($"Nothing to jetify. No files were provided via the \"{nameof(Files)}\" attribute."); return(false); } // make sure the output files are valid if (JetifiedFiles?.Length > 0) { if (Files.Length != JetifiedFiles?.Length) { Log.LogError($"The length of {nameof(Files)} and {nameof(JetifiedFiles)} must be the same."); return(false); } if (!string.IsNullOrEmpty(JetifiedDirectory)) { Log.LogError($"The {nameof(JetifiedDirectory)} and {nameof(JetifiedFiles)} cannot both be set."); return(false); } } // make sure the intermediate file is valid if (UseIntermediateFile) { if (string.IsNullOrEmpty(IntermediateFilePath)) { Log.LogError($"Invalid intermediate path \"{IntermediateFilePath}\"."); return(false); } } try { var filesToJetify = CreateMigrationPairs().ToList(); foreach (var file in filesToJetify) { if (file.Source.Equals(file.Destination, StringComparison.OrdinalIgnoreCase)) { Log.LogMessage(MessageImportance.Low, $"Queuing jetification for {file.Source}."); } else { Log.LogMessage(MessageImportance.Low, $"Queuing jetification for {file.Source} to {file.Destination}."); } } var jetifier = new Jetifier { ConfigurationPath = ConfigurationPath, Verbose = Verbose, Dejetify = Dejetify, IsStrict = IsStrict, ShouldRebuildTopOfTree = ShouldRebuildTopOfTree, ShouldStripSignatures = ShouldStripSignatures, IsProGuard = IsProGuard, Parallel = Parallel, UseIntermediateFile = UseIntermediateFile, IntermediateFilePath = IntermediateFilePath, JavaPath = JavaPath, }; jetifier.MessageLogged += (sender, e) => LogToolMessage(e); if (!string.IsNullOrEmpty(JetifiedDirectory) && !Directory.Exists(JetifiedDirectory)) { Directory.CreateDirectory(JetifiedDirectory); } return(jetifier.Jetify(filesToJetify)); } catch (Exception ex) { Log.LogErrorFromException(ex, true); return(false); } }