Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/Microsoft.Android.Build.BaseTasks/Files.cs
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,15 @@ public static void DeleteFile (string filename, object log)
}
}

public static void TryDeleteFile (string filename, Action<string> log)
{
try {
File.Delete (filename);
} catch (Exception ex) {
log ($"Could not delete '{filename}': {ex}");
}
}

const uint ppdb_signature = 0x424a5342;

public static bool IsPortablePdb (string filename)
Expand Down
35 changes: 24 additions & 11 deletions src/Xamarin.Android.Build.Tasks/Tasks/Aapt2Compile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using System.Text.RegularExpressions;
using System.Collections.Generic;
using Xamarin.Android.Tools;
using Xamarin.Tools.Zip;
using Microsoft.Android.Build.Tasks;

namespace Xamarin.Android.Tasks {
Expand All @@ -22,6 +23,7 @@ public class Aapt2Compile : Aapt2 {

List<ITaskItem> archives = new List<ITaskItem> ();
List<ITaskItem> files = new List<ITaskItem> ();
List<string> temporaryArchives = new List<string> ();

public string? ExtraArgs { get; set; }

Expand All @@ -43,14 +45,21 @@ protected override int GetRequiredDaemonInstances ()

public async override System.Threading.Tasks.Task RunTaskAsync ()
{
await this.WhenAllWithLock (ResourcesToCompile ?? ResourceDirectories ?? [], ProcessDirectory);
try {
await this.WhenAllWithLock (ResourcesToCompile ?? ResourceDirectories ?? [], ProcessDirectory);

ProcessOutput ();
ProcessOutput ();

for (int i = archives.Count -1; i > 0; i-- ) {
if (!File.Exists (archives[i].ItemSpec)) {
archives.RemoveAt (i);
for (int i = archives.Count -1; i > 0; i-- ) {
if (!File.Exists (archives[i].ItemSpec)) {
archives.RemoveAt (i);
}
}
} finally {
foreach (var archive in temporaryArchives) {
Files.TryDeleteFile (archive, LogDebugMessage);
}
temporaryArchives.Clear ();
}
}

Expand Down Expand Up @@ -80,6 +89,16 @@ void ProcessDirectory (ITaskItem item, object lockObject)
outputArchive = GetFullPath (targetDir);
}
Directory.CreateDirectory (outputArchive);
if (isDirectory && OS.IsWindows && !IsPathOnlyASCII (fileOrDirectory)) {
var temporaryArchive = Path.Combine (outputArchive, $"{Path.GetRandomFileName ()}.zip");
lock (lockObject)
temporaryArchives.Add (temporaryArchive);
using (var zip = new ZipArchiveEx (temporaryArchive, FileMode.CreateNew)) {
zip.AddDirectory (fileOrDirectory, "res");
}
fileOrDirectory = temporaryArchive;
isArchive = true;
}
string expectedOutputFile;
if (isDirectory) {
if (flatFile.IsNullOrEmpty ())
Expand All @@ -89,12 +108,6 @@ void ProcessDirectory (ITaskItem item, object lockObject)
filename = $"{filename}.flata";
outputArchive = Path.Combine (outputArchive, filename);
expectedOutputFile = outputArchive;
string archive = item.GetMetadata (ResolveLibraryProjectImports.ResourceDirectoryArchive);
if (!archive.IsNullOrEmpty () && File.Exists (archive)) {
LogDebugMessage ($"Found Compressed Resource Archive '{archive}'.");
fileOrDirectory = archive;
isArchive = true;
}
} else {
if (IsInvalidFilename (fileOrDirectory)) {
LogDebugMessage ($"Invalid filename, ignoring: {fileOrDirectory}");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@ public override bool RunTask ()
}
var fileTaskItem = new TaskItem (file, new Dictionary<string, string> () {
{ "ResourceDirectory", directory.ItemSpec },
{ ResolveLibraryProjectImports.ResourceDirectoryArchive, directory.GetMetadata (ResolveLibraryProjectImports.ResourceDirectoryArchive) },
{ "StampFile", generateArchive ? stampFile : file },
{ "FilesCache", filesCache},
{ "Hash", stampFile },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,16 +71,13 @@ public class ResolveLibraryProjectImports : AndroidTask
internal const string OriginalFile = "OriginalFile";
internal const string AndroidSkipResourceProcessing = "AndroidSkipResourceProcessing";

internal const string ResourceDirectoryArchive = "ResourceDirectoryArchive";

internal const string NuGetPackageVersion = "NuGetPackageVersion";

internal const string NuGetPackageId = "NuGetPackageId";

internal static readonly string [] KnownMetadata = new [] {
OriginalFile,
AndroidSkipResourceProcessing,
ResourceDirectoryArchive,
NuGetPackageId,
NuGetPackageVersion,
};
Expand Down Expand Up @@ -121,12 +118,14 @@ public override bool RunTask ()
.Select (s => new TaskItem (Path.GetFullPath (Path.Combine (s.ItemSpec, "../..")) + ".stamp"))
.ToArray ();

foreach (var directory in ResolvedResourceDirectories) {
Files.SetDirectoryWriteable (directory.ItemSpec);
}
if (OS.IsWindows) {
foreach (var directory in ResolvedResourceDirectories) {
Files.SetDirectoryWriteable (directory.ItemSpec);
}

foreach (var directory in ResolvedAssetDirectories) {
Files.SetDirectoryWriteable (directory.ItemSpec);
foreach (var directory in ResolvedAssetDirectories) {
Files.SetDirectoryWriteable (directory.ItemSpec);
}
}

if (!CacheFile.IsNullOrEmpty ()) {
Expand Down Expand Up @@ -204,7 +203,6 @@ void Extract (
string importsDir = Path.Combine (outDirForDll, ImportsDirectory);
string nativeimportsDir = Path.Combine (outDirForDll, NativeImportsDirectory);
string resDir = Path.Combine (importsDir, "res");
string resDirArchive = Path.Combine (resDir, "..", "res.zip");
string assetsDir = Path.Combine (importsDir, "assets");
string nuGetPackageId = assemblyItem.GetMetadata (NuGetPackageId) ?? "";
string nuGetPackageVersion = assemblyItem.GetMetadata (NuGetPackageVersion) ?? "";
Expand All @@ -229,7 +227,6 @@ void Extract (
if (Directory.Exists (resDir)) {
var taskItem = new TaskItem (Path.GetFullPath (resDir), new Dictionary<string, string> {
[OriginalFile] = assemblyPath,
[ResourceDirectoryArchive] = Path.GetFullPath (resDirArchive),
[NuGetPackageId] = nuGetPackageId,
[NuGetPackageVersion] = nuGetPackageVersion,
});
Expand Down Expand Up @@ -327,10 +324,8 @@ void Extract (
// which resulted in missing resource issue.
// Here we replaced copy with use of '-S' option and made it to work.
if (Directory.Exists (resDir)) {
CreateResourceArchive (resDir, resDirArchive);
var taskItem = new TaskItem (Path.GetFullPath (resDir), new Dictionary<string, string> {
[OriginalFile] = assemblyPath,
[ResourceDirectoryArchive] = Path.GetFullPath (resDirArchive),
[NuGetPackageId] = nuGetPackageId,
[NuGetPackageVersion] = nuGetPackageVersion,
});
Expand Down Expand Up @@ -378,7 +373,6 @@ void Extract (
string outDirForDll = Path.Combine (OutputImportDirectory, aarIdentityName);
string importsDir = Path.Combine (outDirForDll, ImportsDirectory);
string resDir = Path.Combine (importsDir, "res");
string resDirArchive = Path.Combine (resDir, "..", "res.zip");
string rTxt = Path.Combine (importsDir, "R.txt");
string assetsDir = Path.Combine (importsDir, "assets");
string proguardFile = Path.Combine (importsDir, "proguard.txt");
Expand Down Expand Up @@ -410,7 +404,6 @@ void Extract (
resolvedResourceDirectories.Add (new TaskItem (Path.GetFullPath (resDir), new Dictionary<string, string> {
[OriginalFile] = Path.GetFullPath (aarFile.ItemSpec),
[AndroidSkipResourceProcessing] = skipProcessing,
[ResourceDirectoryArchive] = Path.GetFullPath (resDirArchive),
[NuGetPackageId] = nuGetPackageId,
[NuGetPackageVersion] = nuGetPackageVersion,
}));
Expand Down Expand Up @@ -466,16 +459,13 @@ void Extract (
}
}
if (Directory.Exists (resDir) || File.Exists (rTxt)) {
if (Directory.Exists (resDir))
CreateResourceArchive (resDir, resDirArchive);
var skipProcessing = aarFile.GetMetadata (AndroidSkipResourceProcessing);
if (skipProcessing.IsNullOrEmpty ()) {
skipProcessing = "True";
}
resolvedResourceDirectories.Add (new TaskItem (Path.GetFullPath (resDir), new Dictionary<string, string> {
[OriginalFile] = aarFullPath,
[AndroidSkipResourceProcessing] = skipProcessing,
[ResourceDirectoryArchive] = Path.GetFullPath (resDirArchive),
[NuGetPackageId] = nuGetPackageId,
[NuGetPackageVersion] = nuGetPackageVersion,
}));
Expand All @@ -496,16 +486,6 @@ void Extract (
}
}

void CreateResourceArchive (string resDir, string outputFile)
{
var fileMode = File.Exists (outputFile) ? FileMode.Open : FileMode.CreateNew;
Files.ArchiveZipUpdate (outputFile, f => {
using (var zip = new ZipArchiveEx (f, fileMode)) {
zip.AddDirectory (resDir, "res");
}
});
}

static void AddJar (IDictionary<string, ITaskItem> jars, string destination, string path, string? originalFile = null, string? nuGetPackageId = null, string? nuGetPackageVersion = null)
{
var fullPath = Path.GetFullPath (Path.Combine (destination, path));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,10 +185,11 @@ public void Aapt2Link ([Values (true, false)] bool compilePerFile)
Directory.Delete (Path.Combine (Root, path), recursive: true);
}

[Test]
public void Aapt2Compile ()
[TestCase ("Aapt2Compile")]
[TestCase ("Aapt2CompileÜmläüt")]
public void Aapt2Compile (string directoryName)
{
var path = Path.Combine (Root, "temp", "Aapt2Compile");
var path = Path.Combine (Root, "temp", directoryName);
Directory.CreateDirectory (path);
var resPath = Path.Combine (path, "res");
var archivePath = Path.Combine(path, "flata");
Expand Down Expand Up @@ -220,6 +221,7 @@ public void Aapt2Compile ()
using (var apk = ZipHelper.OpenZip (flatArchive)) {
Assert.AreEqual (2, apk.EntryCount, $"{flatArchive} should have 2 entries.");
}
Assert.AreEqual (0, Directory.GetFiles (path, "*.zip", SearchOption.AllDirectories).Length, "Temporary resource archives should have been deleted.");
Directory.Delete (Path.Combine (Root, path), recursive: true);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,6 @@ This file is used by all project types, including binding projects.
<Output TaskParameter="ProguardConfigFiles" ItemName="ProguardConfiguration" />
<Output TaskParameter="ExtractedDirectories" ItemName="_ExtractedDirectories" />
</ReadLibraryProjectImportsCache>
<ItemGroup>
<FileWrites Include="@(ResolvedResourceDirectories->'%(ResourceDirectoryArchive)')"
Condition=" '%(ResolvedResourceDirectories.ResourceDirectoryArchive)' != '' And Exists ('%(ResolvedResourceDirectories.ResourceDirectoryArchive)')" />
</ItemGroup>
</Target>

<Target Name="_BuildLibraryImportsCache"
Expand Down
11 changes: 11 additions & 0 deletions tests/Microsoft.Android.Build.BaseTasks-Tests/FilesTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -815,5 +815,16 @@ public void DeleteFile_NonTaskLoggingHelperLog_DoesNotThrow ()
Directory.CreateDirectory (path);
Assert.DoesNotThrow (() => Files.DeleteFile (path, "not a TaskLoggingHelper"));
}

[Test]
public void TryDeleteFile_LogsFailure ()
{
var path = Path.Combine (tempDir, "directory-instead-of-file-try-delete");
Directory.CreateDirectory (path);
string message = "";

Assert.DoesNotThrow (() => Files.TryDeleteFile (path, value => message = value));
Assert.That (message, Does.Contain (path));
}
}
}
Loading