Skip to content

Commit

Permalink
Merge pull request #175 from mono/targets-improvements
Browse files Browse the repository at this point in the history
Targets improvements
  • Loading branch information
mhutch authored Jan 23, 2024
2 parents 274037f + 18ca3f2 commit 9b6fc72
Show file tree
Hide file tree
Showing 14 changed files with 172 additions and 54 deletions.
20 changes: 10 additions & 10 deletions Mono.TextTemplating.Build/Mono.TextTemplating.Build.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net48;net6.0</TargetFrameworks>
Expand All @@ -14,15 +14,15 @@
<PackageReadmeFile>readme.md</PackageReadmeFile>
</PropertyGroup>

<Target Name="AddTargetsFilesToPack" BeforeTargets="GenerateNuspec">
<ItemGroup>
<_PackageFiles Include="T4.BuildTools.props" PackagePath="build\$(PackageId).props" Pack="true" />
<_PackageFiles Include="T4.BuildTools.targets" PackagePath="build\$(PackageId).targets" Pack="true" />
<_PackageFiles Include="multitargeting.props" PackagePath="buildMultiTargeting\$(PackageId).props" Pack="true" />
<_PackageFiles Include="multitargeting.targets" PackagePath="buildMultiTargeting\$(PackageId).targets" Pack="true" />
<_PackageFiles Include="T4.BuildTools.targets.buildschema.json" PackagePath="build\$(PackageId).targets.buildschema.json" Pack="true" />
</ItemGroup>
</Target>
<ItemGroup>
<None Update="T4.BuildTools.props" PackagePath="build\$(PackageId).props" Pack="true" />
<None Update="T4.BuildTools.targets" PackagePath="build\$(PackageId).targets" Pack="true" />
<None Update="multitargeting.props" PackagePath="buildMultiTargeting\$(PackageId).props" Pack="true" />
<None Update="multitargeting.targets" PackagePath="buildMultiTargeting\$(PackageId).targets" Pack="true" />
<None Update="T4.BuildTools.targets.buildschema.json" PackagePath="build\$(PackageId).targets.buildschema.json" Pack="true" />
<None Update="T4PropertyPage.xaml" PackagePath="build\T4PropertyPage.xaml" Pack="true" />
<None Update="T4PropertySchema.xaml" PackagePath="build\T4PropertyPageSchema.xaml" Pack="true" />
</ItemGroup>

<Target Name="AddCopyLocalToPack" BeforeTargets="_GetBuildOutputFilesWithTfm" DependsOnTargets="ReferenceCopyLocalPathsOutputGroup">
<ItemGroup>
Expand Down
29 changes: 18 additions & 11 deletions Mono.TextTemplating.Build/T4.BuildTools.props
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
<Project>
<PropertyGroup>
<TransformOnBuild Condition="'$(TransformOnBuild)'==''">false</TransformOnBuild>
<TransformOutOfDateOnly Condition="'$(TransformOutOfDateOnly)'==''">true</TransformOutOfDateOnly>
</PropertyGroup>

<!-- hide T4 key/value pairs and other non-file items from the solution tree -->
<ItemDefinitionGroup>
<!-- hide T4 key/value pairs and other non-file items from the solution tree -->
<T4ParameterValues>
<Visible>False</Visible>
</T4ParameterValues>
Expand All @@ -24,18 +19,30 @@
<T4AssemblyReference>
<Visible>False</Visible>
</T4AssemblyReference>
<!-- transform on save in VS -->
</ItemDefinitionGroup>

<!-- transform on save in VS -->
<ItemDefinitionGroup>
<T4Transform>
<Generator>MSBuild:TransformAll</Generator>
<Generator>MSBuild:TransformTemplates</Generator>
</T4Transform>
<T4Preprocess>
<Generator>MSBuild:TransformAll</Generator>
<Generator>MSBuild:TransformTemplates</Generator>
</T4Preprocess>
</ItemDefinitionGroup>

<!-- make these items show up as a build action in VS -->
<!--
Make these items show up as a build action in VS.
The PropertyPageSchema also seems to be necessary to make Generator metadata work.
-->
<ItemGroup>
<AvailableItemName Include="T4Transform" />
<PropertyPageSchema Include="$(MSBuildThisFileDirectory)T4PropertyPage.xaml">
<Context>Project</Context>
</PropertyPageSchema>
<PropertyPageSchema Include="$(MSBuildThisFileDirectory)T4PropertySchema.xaml">
<Context>File;BrowseObject</Context>
</PropertyPageSchema>
<AvailableItemName Include="T4Preprocess" />
<AvailableItemName Include="T4Transform" />
</ItemGroup>
</Project>
37 changes: 22 additions & 15 deletions Mono.TextTemplating.Build/T4.BuildTools.targets.buildschema.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
}
},
"T4Argument": {
"description": "T4 template argument, optionally scoped to a directive and/or directive processor. The value, processor and directive may be provided using the `Value, `Processor` and `Directive metadata, or encoded into the `Include` with the syntax `name=value`, `directive!name!value` or `processor!directive!name!value`.",
"description": "T4 template argument, optionally scoped to a directive and/or directive processor. The value, processor and directive may be provided using the `Value, `Processor` and `Directive metadata, or encoded into the `Include` with the format `name=value`, `directive!name!value` or `processor!directive!name!value`.",
"includeDescription": "T4 argument name",
"metadata": {
"Value": "The T4 argument value. Overrides any value encoded in the `Include`.",
Expand Down Expand Up @@ -55,15 +55,15 @@
"type": "file"
},
"T4RequiredAssemblies": {
"description": "After running the TransformTemplates target, the assemblies that must be referenced to compile the preprocessed templates",
"description": "After running the `TransformTemplates` target, the assemblies that must be referenced to compile the preprocessed templates",
"type": "file"
},
"GeneratedTemplates": {
"description": "After running the TransformTemplates target, the output of all transformed templates",
"description": "After running the `TransformTemplates` target, the output of all transformed templates",
"type": "file"
},
"PreprocessedTemplates": {
"description": "After running the TransformTemplates target, the output of all preprocessed templates",
"description": "After running the `TransformTemplates` target, the output of all preprocessed templates",
"type": "file"
}
},
Expand All @@ -79,6 +79,18 @@
"description": "Overrides the output filename for a T4 template. Note that Visual Studio does not respect this.",
"type": "file"
}
},
{
"$appliesTo": [ "GeneratedTemplates", "PreprocessedTemplates" ],
"InputFile": {
"description": "The original template file that generated this file",
"type": "file"
},
"Dependencies": {
"description": "The files that the template depends on",
"type": "file",
"isList": true
}
}
],
"properties": {
Expand All @@ -93,20 +105,20 @@
"defaultValue": "true"
},
"TransformFile": {
"description": "The T4 files to transform when running the Transform target",
"description": "The T4 files to transform when running the `Transform` target",
"type": "file",
"isList": true
},
"BeforeTransform": {
"description": "Targets to run before the T4 Transform target",
"type": "target-name",
"deprecationMessage": "Use `BeforeTargets=\"TransformTemplatesCore\" for target ordering`",
"deprecationMessage": "Use `BeforeTargets=\"TransformTemplatesCore\"` for target ordering.",
"isList": true
},
"AfterTransform": {
"description": "Targets to run after the T4 Transform target",
"type": "target-name",
"deprecationMessage": "Use `AfterTargets=\"TransformTemplatesCore\" for target ordering`",
"deprecationMessage": "Use `AfterTargets=\"TransformTemplatesCore\"` for target ordering.",
"isList": true
},
"IncludeFolders": {
Expand All @@ -122,20 +134,15 @@
"PreprocessTemplateDefaultNamespace": {
"description": "Default namespace for preprocessed templates",
"defaultValue": "$(RootNamespace)",
"deprecationMessage": "Legacy alternative to`$(T4DefaultNamespace)`"
"deprecationMessage": "Legacy alternative to `$(T4DefaultNamespace)`"
},
"UseLegacyT4Preprocessing": {
"description": "Place preprocessed templates beside the templates instead of dynamically injecting them into the build.",
"type": "bool"
},
"T4Arguments": {
"description": "Semicolon-separated list of values to convert to `@(T4Argument)` items. Intended to be used from command-line invocations only.",
"isList": true,
"type": {
"description": "Key-value pair",
"allowUnknownValues": true,
"values": {}
}
"description": "Used to pass arguments when invoking on the CLI. This is a semicolon-separated list and uses the same format as encoded `T4Argument` items: `name=value`, `directive!name!value` or `processor!directive!name!value`.",
"isList": true
}
},
"targets": {
Expand Down
39 changes: 39 additions & 0 deletions Mono.TextTemplating.Build/T4PropertyPage.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8" ?>
<Rule Name="Build"
OverrideMode="Extend"
Description="Specifies properties that control how the project builds."
DisplayName="Build"
PageTemplate="generic"
xmlns="http://schemas.microsoft.com/build/2009/properties">

<Rule.Categories>
<Category Name="T4Templates"
DisplayName="T4 Templates" />
</Rule.Categories>

<Rule.DataSource>
<DataSource Persistence="ProjectFile"
SourceOfDefaultValue="AfterContext"
HasConfigurationCondition="False" />
</Rule.DataSource>

<BoolProperty Name="TransformOnBuild"
DisplayName="Transform on build"
Description="Transform T4 templates when building the project."
Category="T4Templates" />

<StringProperty Name="T4DefaultNamespace"
DisplayName="T4 Default Namespace"
Description="Default namespace for preprocessed T4 templates."
Category="T4Templates" />

<BoolProperty Name="TransformOutOfDateOnly"
DisplayName="Transform out-of-date templates only"
Description="When transforming T4 templates, skip ones that are already up to date."
Category="T4Templates" />

<BoolProperty Name="UseLegacyT4Preprocessing"
DisplayName="Use legacy T4 preprocessing"
Description="Place the output files of preprocessed templates beside the template files instead of dynamically injecting them into the build."
Category="T4Templates" />
</Rule>
23 changes: 23 additions & 0 deletions Mono.TextTemplating.Build/T4PropertySchema.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<ProjectSchemaDefinitions xmlns="http://schemas.microsoft.com/build/2009/properties">

<ContentType
Name="T4Transform"
DisplayName="T4 template"
ItemType="T4Transform">
<NameValuePair Name="DefaultMetadata_Generator" Value="MSBuild:TransformTemplates" />
</ContentType>

<ContentType
Name="T4Preprocess"
DisplayName="T4 runtime template"
ItemType="T4Preprocess">
<NameValuePair Name="DefaultMetadata_Generator" Value="MSBuild:TransformTemplates" />
</ContentType>

<ItemType Name="T4Transform" DisplayName="T4 template"/>
<ItemType Name="T4Preprocess" DisplayName="T4 runtime template"/>

<FileExtension Name=".tt" ContentType="T4 template" />

</ProjectSchemaDefinitions>
18 changes: 16 additions & 2 deletions Mono.TextTemplating.Build/TextTransform.cs
Original file line number Diff line number Diff line change
Expand Up @@ -135,14 +135,16 @@ public override bool Execute ()
if (buildState.TransformTemplates != null) {
TransformTemplateOutput = new ITaskItem[buildState.TransformTemplates.Count];
for (int i = 0; i < buildState.TransformTemplates.Count; i++) {
TransformTemplateOutput[i] = new TaskItem (buildState.TransformTemplates[i].OutputFile);
var template = buildState.TransformTemplates[i];
TransformTemplateOutput[i] = ConstructOutputItem (template.OutputFile, template.InputFile, template.Dependencies);
}
}

if (buildState.PreprocessTemplates != null) {
PreprocessedTemplateOutput = new ITaskItem[buildState.PreprocessTemplates.Count];
for (int i = 0; i < buildState.PreprocessTemplates.Count; i++) {
PreprocessedTemplateOutput[i] = new TaskItem (buildState.PreprocessTemplates[i].OutputFile);
var template = buildState.PreprocessTemplates[i];
PreprocessedTemplateOutput[i] = ConstructOutputItem (template.OutputFile, template.InputFile, template.Dependencies);
}
}

Expand All @@ -159,6 +161,18 @@ public override bool Execute ()
return success;
}

static TaskItem ConstructOutputItem (string outputFile, string inputFile, List<string> itemDependencies)
{
var item = new TaskItem (outputFile);
item.SetMetadata ("InputFile", inputFile);

if (itemDependencies?.Count > 0) {
item.SetMetadata ("Dependencies", string.Join (";", itemDependencies));
}

return item;
}

bool AddParameters (TemplateBuildState buildState)
{
bool success = true;
Expand Down
5 changes: 3 additions & 2 deletions Mono.TextTemplating.Build/TextTransformProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ public static bool Process (TaskLoggingHelper taskLog, TemplateBuildState previo
var pt = LoadTemplate (generator, inputFile, out var inputContent);
TemplateSettings settings = TemplatingEngine.GetSettings (generator, pt);
settings.RelativeLinePragmas = true;
settings.RelativeLinePragmasBaseDirectory = Path.GetDirectoryName (preprocess.OutputFile);
settings.CodeGenerationOptions.UseRemotingCallContext = buildState.PreprocessTargetRuntimeIdentifier == ".NETFramework";
// FIXME: make these configurable, take relative path into account
Expand Down Expand Up @@ -208,8 +211,6 @@ static MSBuildTemplateGenerator CreateGenerator (TemplateBuildState buildState)
}
}

generator.UseRelativeLinePragmas = true;

return generator;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@ enum CSharpLangVersion
v10_0,
v11_0,
v12_0,
v13_0,
Latest = 1024 // make sure value doesn't change as we add new C# versions
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public static bool IsLangVersionArg (string arg) =>
//https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-version-history
public static CSharpLangVersion FromNetCoreSdkVersion (SemVersion sdkVersion)
=> sdkVersion switch {
{ Major: 9 } => CSharpLangVersion.v13_0,
{ Major: 8 } => CSharpLangVersion.v12_0,
{ Major: 7 } => CSharpLangVersion.v11_0,
{ Major: 6 } => CSharpLangVersion.v10_0,
Expand All @@ -73,6 +74,7 @@ public static CSharpLangVersion FromNetCoreSdkVersion (SemVersion sdkVersion)
CSharpLangVersion.v10_0 => "10.0",
CSharpLangVersion.v11_0 => "11.0",
CSharpLangVersion.v12_0 => "12.0",
CSharpLangVersion.v13_0 => "13.0",
CSharpLangVersion.Latest => "latest",
_ => throw new ArgumentException ($"Not a valid value: '{version}'", nameof (version))
};
Expand Down
5 changes: 1 addition & 4 deletions Mono.TextTemplating/Mono.TextTemplating.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,7 @@
<!-- limit to 6.0 so that the MSBuild task can load on .NET 6.0 -->
<PackageReference Include="System.CodeDom" Version="6.0.0" Condition="'$(TargetFramework)'!='net472'" />
<None Include="readme.md" Pack="true" PackagePath="\" />
<None Include="package\Mono.TextTemplating.targets" Pack="true" PackagePath="buildTransitive\net461\Mono.TextTemplating.targets" />
<None Include="package\_._" Pack="true" PackagePath="buildTransitive\net472\_._" />
<None Include="package\Mono.TextTemplating.targets" Pack="true" PackagePath="buildTransitive\netcoreapp2.0\Mono.TextTemplating.targets" />
<None Include="package\_._" Pack="true" PackagePath="buildTransitive\net6.0\_._" />
<None Include="package\Mono.TextTemplating.targets" Pack="true" PackagePath="buildTransitive\Mono.TextTemplating.targets" />
</ItemGroup>

<ItemGroup>
Expand Down
6 changes: 6 additions & 0 deletions Mono.TextTemplating/Mono.TextTemplating/TemplateSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,12 @@ public TemplateSettings ()
public string GetFullName () => string.IsNullOrEmpty (Namespace) ? Name : Namespace + "." + Name;

internal CodeGenerationOptions CodeGenerationOptions { get; } = new CodeGenerationOptions ();

/// <summary>
/// Base directory for calculation of relative line pragmas.
/// Internal until we clean up the settings API.
/// </summary>
internal string RelativeLinePragmasBaseDirectory { get; set; }
}

public class CustomDirective
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,16 @@ public static CodeCompileUnit GenerateCompileUnit (ITextTemplatingEngineHost hos

static void GenerateTransformMethod (CodeTypeDeclaration templateType, TemplateSettings settings, ParsedTemplate pt, string templateFile, bool isOverride)
{
string baseDirectory = Path.GetDirectoryName (templateFile);
string pragmasRelativeToDirectory = null;

if (settings.RelativeLinePragmas) {
if (!string.IsNullOrEmpty (settings.RelativeLinePragmasBaseDirectory)) {
pragmasRelativeToDirectory = Path.GetFullPath (settings.RelativeLinePragmasBaseDirectory);
}
if (pragmasRelativeToDirectory is null && templateFile is not null) {
pragmasRelativeToDirectory = Path.GetDirectoryName (Path.GetFullPath (templateFile));
}
}

var transformMeth = Declare.Method ("TransformText").Returns<string> ().AsVirtual ();

Expand All @@ -87,16 +96,16 @@ static void GenerateTransformMethod (CodeTypeDeclaration templateType, TemplateS
CodeStatement st = null;
CodeLinePragma location = null;
if (!settings.NoLinePragmas) {
var f = seg.StartLocation.FileName ?? templateFile;
if (!string.IsNullOrEmpty (f)) {
// FIXME: we need to know where the output file will be to make this work properly
if (settings.RelativeLinePragmas) {
f = FileUtil.AbsoluteToRelativePath (baseDirectory, f);
} else {
f = Path.GetFullPath (f);
var filename = seg.StartLocation.FileName ?? templateFile;
if (!string.IsNullOrEmpty (filename)) {
if (!settings.RelativeLinePragmas) {
filename = Path.GetFileName (filename);
} else if (pragmasRelativeToDirectory is not null) {
filename = Path.GetFullPath (filename);
filename = FileUtil.AbsoluteToRelativePath (pragmasRelativeToDirectory, filename);
}
}
location = new CodeLinePragma (f, seg.StartLocation.Line);
location = new CodeLinePragma (filename, seg.StartLocation.Line);
}
switch (seg.Type) {
case SegmentType.Block:
Expand Down
Loading

0 comments on commit 9b6fc72

Please sign in to comment.