Skip to content

Commit

Permalink
resolving image collection - adding tests
Browse files Browse the repository at this point in the history
  • Loading branch information
dansiegel committed Mar 5, 2020
1 parent d906cbe commit c423013
Show file tree
Hide file tree
Showing 22 changed files with 837 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,28 @@ protected override IEnumerable<OutputImage> GetOutputImages(ResourceDefinition r
}
}

protected override ResourceDefinition GetPlatformResourceDefinition(string filePath)
{
var fi = new FileInfo(filePath);
if (fi.Name != "Contents.json")
throw new Exception($"File not supported. {filePath}");

var parentDirectory = fi.Directory.Name;
if (Path.GetExtension(parentDirectory) != ".appiconset")
throw new Exception($"The Contents.json must be located within an appiconset. '{filePath}");

return new ResourceDefinition
{
InputFilePath = filePath,
Ignore = false,
Name = Path.GetFileNameWithoutExtension(parentDirectory),
Scale = 1
};
}

private IEnumerable<OutputImage> GetAppIconSet(ResourceDefinition resource, string basePath, string outputFileName, double masterScale)
{
var contentsJson = Path.Combine(basePath, "Contents.json");
var contentsJson = Path.Combine(Build.ProjectDirectory, basePath, "Contents.json");
imageResourcePaths.Add(contentsJson);
var iconset = JsonConvert.DeserializeObject<AppleIconSet>(
File.ReadAllText(contentsJson));
Expand All @@ -90,16 +109,21 @@ private IEnumerable<OutputImage> GetAppIconSet(ResourceDefinition resource, stri
var scale = int.Parse(x.Scale[0].ToString());
var size = x.Size.Split('x');
Log.LogMessage($"Found App Icon Set image {resource.InputFilePath} -> {basePath}/{x.FileName}");
var outputFile = Path.Combine(Build.IntermediateOutputPath, basePath, x.FileName);
var outputLink = Path.Combine(basePath, x.FileName);
var watermarkFilePath = GetWatermarkFilePath(resource);
var width = (int)(double.Parse(size[0]) * scale * masterScale);
var height = (int)(double.Parse(size[1]) * scale * masterScale);
return new OutputImage
{
InputFile = resource.InputFilePath,
OutputFile = Path.Combine(Build.IntermediateOutputPath, basePath, x.FileName),
OutputLink = Path.Combine(basePath, x.FileName),
Width = (int)(int.Parse(size[0]) * scale * masterScale),
Height = (int)(int.Parse(size[1]) * scale * masterScale),
OutputFile = outputFile,
OutputLink = outputLink,
Width = width,
Height = height,
RequiresBackgroundColor = outputFileName == "AppIcon",
ShouldBeVisible = false,
WatermarkFilePath = GetWatermarkFilePath(resource)
WatermarkFilePath = watermarkFilePath
};
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,18 @@ protected override void ExecuteInternal()
}
}

// HACK: Error thrown that source is modified while iterating.
//var input = imageInputFiles.Select(x => x.Clone() as string);
//foreach (var file in input)
for(var i = 0; i < imageResourcePaths.Count; i++)
var inputList = imageResourcePaths.ToArray();
foreach(var path in inputList)
{
// We need to iterate a second time so we can be sure we are
// tracking all of the image files
// TODO: Add json config to File Inputs
var resource = GetResourceDefinition(imageResourcePaths.ElementAt(i));
ResourceDefinition resource = null;
var ext = Path.GetExtension(path);
if(ext != ".png" && ext != ".jpg")
resource = GetPlatformResourceDefinition(path);
else
resource = GetResourceDefinition(path);

if (resource.ShouldIgnore(Build.Platform))
continue;

Expand Down Expand Up @@ -117,6 +120,8 @@ private string GetImageConfigurationPath(string filePath)
throw new FileNotFoundException(configFileName);
}

protected virtual ResourceDefinition GetPlatformResourceDefinition(string filePath) => throw new NotImplementedException();

private ResourceDefinition GetResourceDefinition(string filePath)
{
var fileName = GetImageConfigurationPath(filePath);
Expand Down
3 changes: 2 additions & 1 deletion src/Mobile.BuildTools/ImageResize.targets
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
SolutionDirectory="$(SolutionDir)"
IntermediateOutputPath="$(IntermediateOutputPath)"
TargetFrameworkIdentifier="$(TargetFrameworkIdentifier)"
AdditionalSearchPaths="$(BuildToolsImageSearchPath)">
AdditionalSearchPaths="$(BuildToolsImageSearchPath)"
IgnoreDefaultSearchPaths="$(BuildToolsIgnoreDefaultSearchPath)">
<Output ItemName="UnifiedImageAsset"
TaskParameter="GeneratedImages" />
<Output ItemName="UnifiedImageAssetSource"
Expand Down
1 change: 1 addition & 0 deletions src/Mobile.BuildTools/Mobile.BuildTools.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<RepositoryUrl>https://github.com/dansiegel/Mobile.BuildTools.git</RepositoryUrl>
<NeutralLanguage>en</NeutralLanguage>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<LangVersion>latest</LangVersion>
</PropertyGroup>

<ItemGroup>
Expand Down
45 changes: 36 additions & 9 deletions src/Mobile.BuildTools/Tasks/CollectImageAssetsTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ public class CollectImageAssetsTask : BuildToolsTaskBase
{
public string AdditionalSearchPaths { get; set; }

public bool? IgnoreDefaultSearchPaths { get; set; }

[Output]
public ITaskItem[] GeneratedImages { get; private set; }

Expand Down Expand Up @@ -68,21 +70,31 @@ private IEnumerable<string> GetSearchPaths(IBuildConfiguration config)
{
var searchPaths = new List<string>();
var imageConfig = config.Configuration.Images;
if(imageConfig.Directories?.Any() ?? false)
var cliSearchPaths = !string.IsNullOrEmpty(AdditionalSearchPaths) ? AdditionalSearchPaths.Split(';') : Array.Empty<string>();
if (cliSearchPaths.Any())
{
searchPaths.AddRange(imageConfig.Directories.Select(GetSearchPath));
searchPaths.AddRange(AdditionalSearchPaths.Split(';').Select(GetSearchPath));
}

if(AdditionalSearchPaths?.Split(';')?.Any() ?? false)
if(cliSearchPaths.Any() && IgnoreDefaultSearchPaths.HasValue && IgnoreDefaultSearchPaths.Value)
{
searchPaths.AddRange(AdditionalSearchPaths.Split(';').Select(GetSearchPath));
return searchPaths.Distinct();
}

var monoandroidKey = imageConfig.ConditionalDirectories.Keys.FirstOrDefault(x => x.Equals("monoandroid", StringComparison.InvariantCultureIgnoreCase));
var xamariniOSKey = imageConfig.ConditionalDirectories.Keys.FirstOrDefault(x => x.Equals("xamarin.ios", StringComparison.InvariantCultureIgnoreCase) || x.Equals("xamarinios", StringComparison.InvariantCultureIgnoreCase));
var xamarinMacKey = imageConfig.ConditionalDirectories.Keys.FirstOrDefault(x => x.Equals("xamarin.mac", StringComparison.InvariantCultureIgnoreCase) || x.Equals("xamarinmac", StringComparison.InvariantCultureIgnoreCase));

switch(config.Platform)
if (imageConfig.Directories?.Any() ?? false)
{
searchPaths.AddRange(imageConfig.Directories.Select(GetSearchPath));
}

var monoandroidKey = GetKey(imageConfig.ConditionalDirectories.Keys, "monoandroid", "android", "droid");
var xamariniOSKey = GetKey(imageConfig.ConditionalDirectories.Keys, "xamarin.ios", "xamarinios", "ios", "apple");
var xamarinMacKey = GetKey(imageConfig.ConditionalDirectories.Keys, "xamarin.mac", "xamarinmac", "mac", "apple");
var xamarinTVOSKey = GetKey(imageConfig.ConditionalDirectories.Keys, "xamarin.tvos", "xamarintvos", "tvos", "apple");

var platformKeys = new[] { monoandroidKey, xamariniOSKey, xamarinMacKey, xamarinTVOSKey }.Where(x => x != null);

switch (config.Platform)
{
case Platform.Android:
if (!string.IsNullOrEmpty(monoandroidKey))
Expand All @@ -96,10 +108,14 @@ private IEnumerable<string> GetSearchPaths(IBuildConfiguration config)
if (!string.IsNullOrEmpty(xamarinMacKey))
searchPaths.AddRange(imageConfig.ConditionalDirectories[xamarinMacKey].Select(GetSearchPath));
break;
case Platform.TVOS:
if (!string.IsNullOrEmpty(xamarinTVOSKey))
searchPaths.AddRange(imageConfig.ConditionalDirectories[xamarinTVOSKey].Select(GetSearchPath));
break;
}

// TODO: Make this even smarter with conditions like `Release || Store`... perhaps we also should consider evaluating the defined constants.
var keys = imageConfig.ConditionalDirectories.Keys.Where(k => !k.StartsWith("mono") && !k.StartsWith("xamarin") && (k.Equals(config.BuildConfiguration) || !k.Equals($"!{config.BuildConfiguration}")));
var keys = imageConfig.ConditionalDirectories.Keys.Where(k => !platformKeys.Any(x => x == k) && (k.Equals(config.BuildConfiguration) || !k.Equals($"!{config.BuildConfiguration}")));
foreach(var validCondition in keys)
{
searchPaths.AddRange(imageConfig.ConditionalDirectories[validCondition].Select(GetSearchPath));
Expand All @@ -108,6 +124,17 @@ private IEnumerable<string> GetSearchPaths(IBuildConfiguration config)
return searchPaths.Distinct();
}

private string GetKey(IEnumerable<string> conditionalKeys, params string[] possibleNames)
{
foreach(var name in possibleNames)
{
if (conditionalKeys.Any(x => x.Equals(name, StringComparison.InvariantCultureIgnoreCase)))
return name;
}

return null;
}

private string GetSearchPath(string directory)
{
if (Uri.TryCreate(directory, UriKind.RelativeOrAbsolute, out var result) && result.IsAbsoluteUri)
Expand Down
1 change: 1 addition & 0 deletions src/Mobile.BuildTools/Utils/Platform.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ public enum Platform
UWP,
macOS,
Tizen,
TVOS,
Unsupported
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System.IO;
using Mobile.BuildTools.Build;
using Mobile.BuildTools.Generators.Images;
using Xunit.Abstractions;

namespace Mobile.BuildTools.Tests.Fixtures
{

public class AndroidImageCollectionGeneratorFixture : ImageCollectionGeneratorFixture
{
public AndroidImageCollectionGeneratorFixture(ITestOutputHelper testOutputHelper)
: base(Path.Join(ImageDirectory, "MonoAndroid"), testOutputHelper)
{
}

internal override ImageCollectionGeneratorBase CreateGenerator(IBuildConfiguration config, params string[] searchFolders) =>
new AndroidImageCollectionGenerator(config)
{
SearchFolders = searchFolders
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System.IO;
using Mobile.BuildTools.Build;
using Mobile.BuildTools.Generators.Images;
using Xunit.Abstractions;

namespace Mobile.BuildTools.Tests.Fixtures
{
public class AppleImageCollectionGeneratorFixture : ImageCollectionGeneratorFixture
{
public AppleImageCollectionGeneratorFixture(ITestOutputHelper testOutputHelper)
: base(Path.Join(ImageDirectory, "Xamarin.iOS"), Path.Combine("Templates", "Apple"), testOutputHelper)
{
PlatformOffset = 1;
}

internal override ImageCollectionGeneratorBase CreateGenerator(IBuildConfiguration config, params string[] searchFolders) =>
new AppleImageCollectionGenerator(config)
{
SearchFolders = searchFolders
};
}
}
70 changes: 63 additions & 7 deletions tests/Mobile.BuildTools.Tests/Fixtures/FixtureBase.cs
Original file line number Diff line number Diff line change
@@ -1,25 +1,81 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.IO;
using Mobile.BuildTools.Tests.Mocks;
using Xunit.Abstractions;

namespace Mobile.BuildTools.Tests.Fixtures
{
public class FixtureBase
public abstract class FixtureBase
{
protected ITestOutputHelper _testOutputHelper { get; }
protected string ProjectDirectory { get; }

public FixtureBase(ITestOutputHelper testOutputHelper)
protected FixtureBase(ITestOutputHelper testOutputHelper)
{
_testOutputHelper = testOutputHelper;
}

protected TestBuildConfiguration GetConfiguration() =>
new TestBuildConfiguration
protected FixtureBase(string projectDirectory, ITestOutputHelper testOutputHelper)
: this(testOutputHelper)
{
ProjectDirectory = projectDirectory;
}

protected TestBuildConfiguration GetConfiguration()
{
var stackTrace = new StackTrace();
var testOutput = Path.Combine("Tests", stackTrace.GetFrame(1).GetMethod().Name);
if(Directory.Exists(testOutput))
{
Directory.Delete(testOutput, true);
}

Directory.CreateDirectory(testOutput);
return new TestBuildConfiguration
{
Logger = new XunitLog(_testOutputHelper),
Platform = Tasks.Utils.Platform.Unsupported,
IntermediateOutputPath = testOutput,
ProjectDirectory = ProjectDirectory
};
}

protected static void DirectoryCopy(string sourceDirName, string destDirName)
{
// Get the subdirectories for the specified directory.
var dir = new DirectoryInfo(sourceDirName);

if (!dir.Exists)
{
throw new DirectoryNotFoundException(
"Source directory does not exist or could not be found: "
+ sourceDirName);
}

var dirs = dir.GetDirectories();
// If the destination directory doesn't exist, create it.
if (!Directory.Exists(destDirName))
{
Directory.CreateDirectory(destDirName);
}

// Get the files in the directory and copy them to the new location.
var files = dir.GetFiles();
foreach (var file in files)
{
if (file.Name == ".DS_Store")
continue;

var temppath = Path.Combine(destDirName, file.Name);
file.CopyTo(temppath, false);
}

// copy subdirectories, copy them and their contents to new location.
foreach (var subdir in dirs)
{
var temppath = Path.Combine(destDirName, subdir.Name);
DirectoryCopy(subdir.FullName, temppath);
}
}
}
}
Loading

0 comments on commit c423013

Please sign in to comment.