protected override Stream LoadResource(string resourceFullPath, string assemblyName) { var fileStream = base.LoadResource(resourceFullPath, assemblyName); var resourceFileName = Path.GetFileName(resourceFullPath); //HACK: CFBundleExecutable is invalid in bundle plists but some downloaded libraries contain it. remove it. if (resourceFileName == "Info.plist") { var po = PObject.FromStream(fileStream) as PDictionary; if (po != null && po.Remove("CFBundleExecutable")) { var memoryStream = new MemoryStream(); using (var ctx = PropertyListFormat.Binary.StartWriting(memoryStream)) ctx.WriteObject(po); fileStream.Dispose(); memoryStream.Position = 0; return(memoryStream); } } return(fileStream); }
public void TestResourcesAdded() { var engine = new ProjectCollection(); var prel = ProjectRootElement.Create(Path.Combine(TempDir, "project.csproj"), engine); var asm = AssemblyDefinition.CreateAssembly( new AssemblyNameDefinition("Foo", new System.Version(1, 0, 0, 0)), "Main", ModuleKind.Dll ); var dll = Path.Combine(TempDir, "Foo.dll"); asm.Write(dll); var unpackDir = GetTempPath("unpacked"); prel.SetProperty("XamarinBuildDownloadDir", unpackDir); prel.SetProperty("TargetFrameworkIdentifier", "Xamarin.iOS"); prel.SetProperty("OutputType", "Exe"); prel.SetProperty("IntermediateOutputPath", Path.Combine(TempDir, "obj")); prel.AddItem( "XamarinBuildDownload", "AppInvites-1.0.2", new Dictionary <string, string> { { "Url", "https://www.gstatic.com/cpdc/278f79fcd3b365e3-AppInvites-1.0.2.tar.gz" }, { "Kind", "Tgz" } }); prel.AddItem( "ReferencePath", dll ); var plist = Path.Combine(unpackDir, "AppInvites-1.0.2", "Frameworks", "GINInvite.framework", "Versions", "A", "Resources", "GINInviteResources.bundle", "Info.plist"); const string resourceName = "monotouch_content_GINInviteResources.bundle_fInfo.plist"; prel.AddItem( "RestoreAssemblyResource", plist, new Dictionary <string, string> { { "AssemblyName", "Foo" }, { "LogicalName", resourceName } } ); AddCoreTargets(prel); var project = new ProjectInstance(prel); var log = new MSBuildTestLogger(); var success = BuildProject(engine, project, "_XamariniOSBuildResourceRestore", log); AssertNoMessagesOrWarnings(log); Assert.IsTrue(success); Assert.IsTrue(File.Exists(plist)); //check the referencepath has been replaced by the processed one var items = project.GetItems("ReferencePath"); var mergedItem = items.FirstOrDefault(i => !string.IsNullOrEmpty(i.EvaluatedInclude) && i.EvaluatedInclude != dll); Assert.IsTrue(mergedItem != null); var itemPath = mergedItem.EvaluatedInclude; Assert.AreNotEqual(dll, itemPath); //check the assembly has the processed resource var processedAsm = AssemblyDefinition.ReadAssembly(itemPath); var resource = processedAsm.MainModule.Resources.FirstOrDefault() as EmbeddedResource; Assert.NotNull(resource); Assert.AreEqual(resourceName, resource.Name); var ps = PObject.FromStream(resource.GetResourceStream()) as PDictionary; Assert.IsFalse(ps.ContainsKey("CFBundleExecutable")); Assert.Greater(ps.Count, 0); var processedAsmMtime = File.GetLastWriteTime(itemPath); // check incremental build works project = new ProjectInstance(prel); log = new MSBuildTestLogger(); var newSuccess = BuildProject(engine, project, "_XamariniOSBuildResourceRestore", log); AssertNoMessagesOrWarnings(log); Assert.IsTrue(success); var newItems = project.GetItems("ReferencePath"); var newItem = newItems.FirstOrDefault(i => !string.IsNullOrEmpty(i.EvaluatedInclude) && i.EvaluatedInclude != dll); var newItemPath = newItem.EvaluatedInclude; Assert.AreEqual(itemPath, newItemPath); Assert.AreEqual(processedAsmMtime, File.GetLastWriteTime(newItemPath)); }