* CSSG Incremental

* [tests] MSBuild integration tests for CssG
This commit is contained in:
Stephane Delcroix 2018-06-11 11:56:17 +02:00 коммит произвёл GitHub
Родитель 487b669aaf
Коммит 44182014ad
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 72 добавлений и 28 удалений

Просмотреть файл

@ -38,7 +38,7 @@
</GetTasksAbi >
<PropertyGroup>
<_XFTasksExpectedAbi>4</_XFTasksExpectedAbi>
<_XFTasksExpectedAbi>5</_XFTasksExpectedAbi>
</PropertyGroup>
<Error
@ -112,17 +112,23 @@
$(CoreCompileDependsOn);
</CoreCompileDependsOn>
</PropertyGroup>
<Target Name="CssG" BeforeTargets="BeforeCompile" DependsOnTargets="PrepareResourceNames" Condition="'$(_CssGAlreadyExecuted)'!='true'">
<PropertyGroup>
<_CssGAlreadyExecuted>true</_CssGAlreadyExecuted>
</PropertyGroup>
<Target Name="_FindCSSFiles" DependsOnTargets="PrepareResourceNames">
<ItemGroup>
<_CSSInputs Include="@(EmbeddedResource)" Condition="'%(Extension)' == '.css' AND '$(DefaultLanguageSourceExtension)' == '.cs' AND '%(TargetPath)' != ''" />
<_CSSOutputs Include="@(_CSSInputs->'$(IntermediateOutputPath)%(TargetPath).g.cs')" />
</ItemGroup>
</Target>
<Target Name="CssG" BeforeTargets="BeforeCompile" DependsOnTargets="_FindCSSFiles" Inputs="@(_CSSInputs)" Outputs="@(_CSSOutputs)">
<CssGTask
XamlFiles="@(EmbeddedResource)" Condition="'%(Extension)' == '.css' AND '$(DefaultLanguageSourceExtension)' == '.cs'"
CSSFiles="@(_CSSInputs)"
OutputFiles="@(_CSSOutputs)"
Language = "$(Language)"
AssemblyName = "$(AssemblyName)"
OutputPath = "$(IntermediateOutputPath)">
<Output ItemName="FileWrites" TaskParameter="GeneratedCodeFiles" />
<Output ItemName="Compile" TaskParameter="GeneratedCodeFiles" />
</CssGTask>
AssemblyName = "$(AssemblyName)" />
<ItemGroup>
<FileWrites Include="@(_CSSOutputs)" />
<Compile Include="@(_CSSOutputs)" />
</ItemGroup>
</Target>
</Project>

Просмотреть файл

@ -10,41 +10,47 @@ namespace Xamarin.Forms.Build.Tasks
{
public class CssGTask : Task
{
readonly List<ITaskItem> _generatedCodeFiles = new List<ITaskItem>();
[Required]
public ITaskItem[] CSSFiles { get; set; }
[Required]
public ITaskItem[] XamlFiles { get; set; }
[Output]
public ITaskItem[] GeneratedCodeFiles => _generatedCodeFiles.ToArray();
public ITaskItem[] OutputFiles { get; set; }
public string Language { get; set; }
public string AssemblyName { get; set; }
public string OutputPath { get; set; }
public override bool Execute()
{
bool success = true;
Log.LogMessage(MessageImportance.Normal, "Generating assembly attributes for CSS files");
if (XamlFiles == null) {
if (CSSFiles == null || OutputFiles == null) {
Log.LogMessage(MessageImportance.Low, "Skipping CssG");
return true;
}
foreach (var xamlFile in XamlFiles) {
var outputFile = Path.Combine(OutputPath, $"{xamlFile.GetMetadata("TargetPath")}.g.cs");
var generator = new CssGenerator(xamlFile, Language, AssemblyName, outputFile, Log);
if (CSSFiles.Length != OutputFiles.Length) {
Log.LogError("\"{2}\" refers to {0} item(s), and \"{3}\" refers to {1} item(s). They must have the same number of items.", CSSFiles.Length, OutputFiles.Length, "CSSFiles", "OutputFiles");
return false;
}
for (var i = 0; i < CSSFiles.Length;i++) {
var cssFile = CSSFiles[i];
var outputFile = OutputFiles[i].ItemSpec;
var generator = new CssGenerator(cssFile, Language, AssemblyName, outputFile, Log);
try {
if (generator.Execute())
_generatedCodeFiles.Add(new TaskItem(Microsoft.Build.Evaluation.ProjectCollection.Escape(outputFile)));
if (!generator.Execute()) {
//If Execute() fails, the file still needs to exist because it is added to the <Compile/> ItemGroup
File.WriteAllText(outputFile, string.Empty);
}
}
catch (XmlException xe) {
Log.LogError(null, null, null, xamlFile.ItemSpec, xe.LineNumber, xe.LinePosition, 0, 0, xe.Message, xe.HelpLink, xe.Source);
Log.LogError(null, null, null, cssFile.ItemSpec, xe.LineNumber, xe.LinePosition, 0, 0, xe.Message, xe.HelpLink, xe.Source);
success = false;
}
catch (Exception e) {
Log.LogError(null, null, null, xamlFile.ItemSpec, 0, 0, 0, 0, e.Message, e.HelpLink, e.Source);
Log.LogError(null, null, null, cssFile.ItemSpec, 0, 0, 0, 0, e.Message, e.HelpLink, e.Source);
success = false;
}
}

Просмотреть файл

@ -6,7 +6,7 @@ namespace Xamarin.Forms.Build.Tasks
public class GetTasksAbi : Task
{
[Output]
public string AbiVersion { get; } = "4";
public string AbiVersion { get; } = "5";
public override bool Execute()
=> true;

Просмотреть файл

@ -45,6 +45,15 @@ namespace Xamarin.Forms.Xaml.UnitTests
</ContentView>";
}
class Css
{
public const string Foo = @"
label {
color: azure;
background-color: aliceblue;
}";
}
string testDirectory;
string tempDirectory;
string intermediateDirectory;
@ -139,6 +148,9 @@ namespace Xamarin.Forms.Xaml.UnitTests
//Let's enable XamlC assembly-wide
project.Add (AddFile ("AssemblyInfo.cs", "Compile", "[assembly: Xamarin.Forms.Xaml.XamlCompilation (Xamarin.Forms.Xaml.XamlCompilationOptions.Compile)]"));
//Add a single CSS file
project.Add (AddFile ("Foo.css", "EmbeddedResource", Css.Foo));
if (!sdkStyle)
project.Add (NewElement ("Import").WithAttribute ("Project", @"$(MSBuildBinPath)\Microsoft.CSharp.targets"));
@ -229,6 +241,7 @@ namespace Xamarin.Forms.Xaml.UnitTests
AssertExists (Path.Combine (intermediateDirectory, "test.dll"), nonEmpty: true);
AssertExists (Path.Combine (intermediateDirectory, "MainPage.xaml.g.cs"), nonEmpty: true);
AssertExists (Path.Combine (intermediateDirectory, "Foo.css.g.cs"), nonEmpty: true);
AssertExists (Path.Combine (intermediateDirectory, "XamlC.stamp"));
}
@ -246,11 +259,14 @@ namespace Xamarin.Forms.Xaml.UnitTests
Build (projectFile);
var mainPageXamlG = Path.Combine (intermediateDirectory, "MainPage.xaml.g.cs");
var fooCssG = Path.Combine (intermediateDirectory, "Foo.css.g.cs");
var xamlCStamp = Path.Combine (intermediateDirectory, "XamlC.stamp");
AssertExists (mainPageXamlG, nonEmpty: true);
AssertExists (fooCssG, nonEmpty: true);
AssertExists (xamlCStamp);
var expectedXamlG = new FileInfo (mainPageXamlG).LastWriteTimeUtc;
var expectdCssG = new FileInfo (fooCssG).LastWriteTimeUtc;
var expectedXamlC = new FileInfo (xamlCStamp).LastWriteTimeUtc;
//Build again
@ -259,8 +275,10 @@ namespace Xamarin.Forms.Xaml.UnitTests
AssertExists (xamlCStamp);
var actualXamlG = new FileInfo (mainPageXamlG).LastWriteTimeUtc;
var actualCssG = new FileInfo (fooCssG).LastWriteTimeUtc;
var actualXamlC = new FileInfo (xamlCStamp).LastWriteTimeUtc;
Assert.AreEqual (expectedXamlG, actualXamlG, $"Timestamps should match for {mainPageXamlG}.");
Assert.AreEqual (expectdCssG, actualCssG, $"Timestamps should match for {fooCssG}.");
Assert.AreEqual (expectedXamlC, actualXamlC, $"Timestamps should match for {xamlCStamp}.");
}
@ -278,13 +296,16 @@ namespace Xamarin.Forms.Xaml.UnitTests
Build (projectFile);
var mainPageXamlG = Path.Combine (intermediateDirectory, "MainPage.xaml.g.cs");
var fooCssG = Path.Combine (intermediateDirectory, "Foo.css.g.cs");
var xamlCStamp = Path.Combine (intermediateDirectory, "XamlC.stamp");
AssertExists (mainPageXamlG, nonEmpty: true);
AssertExists (fooCssG, nonEmpty: true);
AssertExists (xamlCStamp);
//Clean
Build (projectFile, "Clean");
AssertDoesNotExist (mainPageXamlG);
AssertDoesNotExist (fooCssG);
AssertDoesNotExist (xamlCStamp);
}
@ -328,25 +349,31 @@ namespace Xamarin.Forms.Xaml.UnitTests
var assembly = Path.Combine (intermediateDirectory, "test.dll");
var mainPageXamlG = Path.Combine (intermediateDirectory, "Pages", "MainPage.xaml.g.cs");
var fooCssG = Path.Combine (intermediateDirectory, "Foo.css.g.cs");
var xamlCStamp = Path.Combine (intermediateDirectory, "XamlC.stamp");
//The assembly should not be compiled
AssertDoesNotExist (assembly);
AssertExists (mainPageXamlG, nonEmpty: true);
AssertExists (fooCssG, nonEmpty: true);
AssertExists (xamlCStamp);
var expectedXamlG = new FileInfo (mainPageXamlG).LastWriteTimeUtc;
var expectedCssG = new FileInfo (fooCssG).LastWriteTimeUtc;
var expectedXamlC = new FileInfo (xamlCStamp).LastWriteTimeUtc;
//Build again, a full build
Build (projectFile);
AssertExists (assembly, nonEmpty: true);
AssertExists (mainPageXamlG, nonEmpty: true);
AssertExists (fooCssG, nonEmpty: true);
AssertExists (xamlCStamp);
var actualXamlG = new FileInfo (mainPageXamlG).LastWriteTimeUtc;
var actualCssG = new FileInfo (fooCssG).LastWriteTimeUtc;
var actualXamlC = new FileInfo (xamlCStamp).LastWriteTimeUtc;
Assert.AreEqual (expectedXamlG, actualXamlG, $"Timestamps should match for {mainPageXamlG}.");
Assert.AreEqual (expectedCssG, actualCssG, $"Timestamps should match for {fooCssG}.");
Assert.AreNotEqual (expectedXamlC, actualXamlC, $"Timestamps should *not* match for {xamlCStamp}.");
}
@ -362,6 +389,7 @@ namespace Xamarin.Forms.Xaml.UnitTests
Build (projectFile, "UpdateDesignTimeXaml");
AssertExists (Path.Combine (intermediateDirectory, "Pages", "MainPage.xaml.g.cs"), nonEmpty: true);
AssertDoesNotExist (Path.Combine (intermediateDirectory, "Foo.css.g.cs"));
AssertDoesNotExist (Path.Combine (intermediateDirectory, "XamlC.stamp"));
}
@ -377,14 +405,16 @@ namespace Xamarin.Forms.Xaml.UnitTests
var mainPageXamlG = Path.Combine (intermediateDirectory, "MainPage.xaml.g.cs");
var customViewXamlG = Path.Combine (intermediateDirectory, "CustomView.xaml.g.cs");
var fooCssG = Path.Combine (intermediateDirectory, "Foo.css.g.cs");
var xamlCStamp = Path.Combine (intermediateDirectory, "XamlC.stamp");
AssertExists (mainPageXamlG, nonEmpty: true);
AssertExists (xamlCStamp);
var expectedXamlG = new FileInfo (mainPageXamlG).LastWriteTimeUtc;
var expectedCssG = new FileInfo (fooCssG).LastWriteTimeUtc;
var expectedXamlC = new FileInfo (xamlCStamp).LastWriteTimeUtc;
//Build again, after adding a file, this triggers a full XamlG and XamlC
//Build again, after adding a file, this triggers a full XamlG and XamlC -- *not* CssG
project.Add (AddFile ("CustomView.xaml", "EmbeddedResource", Xaml.CustomView));
project.Save (projectFile);
Build (projectFile);
@ -393,10 +423,12 @@ namespace Xamarin.Forms.Xaml.UnitTests
AssertExists (xamlCStamp);
var actualXamlG = new FileInfo (mainPageXamlG).LastWriteTimeUtc;
var actualCssG = new FileInfo (fooCssG).LastWriteTimeUtc;
var actualXamlC = new FileInfo (xamlCStamp).LastWriteTimeUtc;
var actualNewFile = new FileInfo (customViewXamlG).LastAccessTimeUtc;
Assert.AreNotEqual (expectedXamlG, actualXamlG, $"Timestamps should *not* match for {mainPageXamlG}.");
Assert.AreNotEqual (expectedXamlG, actualNewFile, $"Timestamps should *not* match for {actualNewFile}.");
Assert.AreNotEqual (expectedXamlG, actualNewFile, $"Timestamps should *not* match for {customViewXamlG}.");
Assert.AreEqual (expectedCssG, actualCssG, $"Timestamps should match for {fooCssG}.");
Assert.AreNotEqual (expectedXamlC, actualXamlC, $"Timestamps should *not* match for {xamlCStamp}.");
}