Compare commits

11 Commits

Author SHA1 Message Date
c78907aeeb test commit 2025-05-21 16:22:20 +01:00
1d5b4a4ab7 add: README 2025-03-07 16:31:40 +00:00
1dc11c5f76 update: upgrade to godot 4.4.0 2025-03-04 12:26:15 +00:00
7e6b950fee add: Patchable items and frames 2025-03-04 11:58:14 +00:00
f32feecd4f add: Template Define 2025-02-22 03:56:27 +00:00
b03b10b4ed improve: clean up 2025-02-20 10:42:46 +00:00
607d5cb6a5 fix: passthrough should point to polonium registry 2025-02-20 09:31:11 +00:00
f70cab525b add: registry pass through 2025-02-19 17:09:07 +00:00
cadb3e02ac improve: better version control 2025-02-18 21:22:47 +00:00
3a08d8ae16 fix: missing type 2025-02-18 16:05:37 +00:00
b4fabd01bb Merge pull request 'draft_texture_button' (#1) from draft_texture_button into master
Reviewed-on: #1
2025-02-18 14:30:12 +00:00
10 changed files with 234 additions and 70 deletions

6
.gitignore vendored
View File

@@ -3,3 +3,9 @@ obj/
/packages/
riderModule.iml
/_ReSharper.Caches/
/summerizer.py
/NuGet.config
/Polonium.Tasks.sln.DotSettings.user
/VersionInfo.props
.idea/
/summerizer

View File

@@ -1,13 +0,0 @@
# Default ignored files
/shelf/
/workspace.xml
# Rider ignored files
/.idea.Polonium.Tasks.iml
/modules.xml
/projectSettingsUpdater.xml
/contentModel.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<TasksFolder>$(MSBuildThisFileDirectory)tasks/netstandard2.0/</TasksFolder>
<TasksAssembly>$(TasksFolder)$(MSBuildThisFileName).dll</TasksAssembly>
@@ -13,4 +12,8 @@
TaskName="GenerateTextureSetTask"
AssemblyFile="$(TasksAssembly)"
/>
<UsingTask
TaskName="GenerateRegistryPassThrough"
AssemblyFile="$(TasksAssembly)"
/>
</Project>

View File

@@ -1,5 +1,5 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="VersionInfo.props" Condition="Exists('VersionInfo.props')" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<IsPackable>true</IsPackable>
@@ -8,7 +8,7 @@
<RootNamespace>Polonium.Tasks</RootNamespace>
<AssemblyName>Polonium.Tasks</AssemblyName>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Version>0.1.1-x</Version>
<Version>$(PoloniumTasksVersion)</Version>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<GenerateDependencyFile>true</GenerateDependencyFile>
<TargetsForTfmSpecificBuildOutput>$(TargetsForTfmSpecificBuildOutput);CopyProjectReferencesToPackage</TargetsForTfmSpecificBuildOutput>
@@ -18,21 +18,9 @@
</PropertyGroup>
<ItemGroup>
<PackageReference
Include="Microsoft.Build"
Version="17.12.6"
PrivateAssets="all"
/>
<PackageReference
Include="Microsoft.Build.Tasks.Core"
Version="17.12.6"
PrivateAssets="all"
/>
<PackageReference
Include="Microsoft.CodeAnalysis"
Version="4.12.0"
PrivateAssets="all"
/>
<PackageReference Include="Microsoft.Build" Version="17.12.6" PrivateAssets="all" />
<PackageReference Include="Microsoft.Build.Tasks.Core" Version="17.12.6" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis" Version="4.12.0" PrivateAssets="all" />
<EmbeddedResource Update="Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
@@ -44,11 +32,8 @@
</Compile>
<AdditionalFiles Remove="AnalyzerReleases.Shipped.md" />
<AdditionalFiles Remove="AnalyzerReleases.Unshipped.md" />
<None
Include="Package/build/**/*"
Pack="true"
PackagePath="build"
/>
<None Include="Package/build/**/*" Pack="true" PackagePath="build" />
<None Include="VersionInfo.props" Condition="Exists('VersionInfo.props')" Pack="true" PackagePath="build" />
</ItemGroup>
<Target Name="CopyProjectReferencesToPackage" DependsOnTargets="ResolveReferences">
<ItemGroup>
@@ -65,9 +50,9 @@
>
<ItemGroup>
<BuiltProjectOutputGroupOutput
Include="$(ProjectDepsFilePath)"
TargetPath="$(ProjectDepsFileName)"
FinalOutputPath="$(ProjectDepsFilePath)"
Include="$(ProjectDepsFilePath)"
TargetPath="$(ProjectDepsFileName)"
FinalOutputPath="$(ProjectDepsFilePath)"
/>
</ItemGroup>
</Target>
@@ -79,8 +64,6 @@
</Target>
<Target Name="CopyPackageToLocalFeed" AfterTargets="Pack">
<Message Text="Executing Copy Pack Task" Importance="high" />
<Message Text="OutputPath: $(OutputPath)" Importance="high" />
<ItemGroup>
<NuGetPackages Include="$(OutputPath)../*.nupkg" />
</ItemGroup>

33
README.md Normal file
View File

@@ -0,0 +1,33 @@
# Polonium.Tasks
**Project Description**
Polonium.Tasks is a set of MSBuild tasks created to support Godot C# projects using the Polonium library. It streamlines building, cleaning, packaging, and code generation steps by automating operations around scripts, templates, and resources.
**Key Features**
- **GenerateProxyNodesTask**: Examines source directories and generates script proxies based on `[ProxyNode]` in Polonium, should not be used manually in custom project.
- **GenerateRegistryPassThrough**: Produces bridging files for `[RegistryPassThrough]` attributes in Polonium, should not be used manually in custom project
- **GenerateTextureSetTask**: Helps build and bundle multiple textures (e.g., button states) into a coherent set.
- **Custom Build Workflows**: Extends typical MSBuild processes to manage Godot-specific tasks.
**Installation**
1. Add the package to your project via `.csproj`:
```xml
<PackageReference Include="Polonium.Tasks" Version="x.x.x" />
```
2. Restore the packages and build your project.
**Usage Example**
```xml
<Target Name="Prepare" BeforeTargets="BeforeBuild">
<GenerateProxyNodesTask
SourceDirectory="$(ProjectDir)Package/embedded/GlobalClasses"
TemplateDirectory="$(ProjectDir)Package/embedded/polonium_templates"
AttributeName="ProxyNode"
/>
</Target>
```
When you run a build, these tasks will automatically generate or update relevant files, saving you manual overhead.
**License**
This project is licensed under the [MIT License](https://opensource.org/licenses/MIT).

12
publish Normal file → Executable file
View File

@@ -1,2 +1,12 @@
#!/bin/bash
dotnet nuget push "$(ls -t ./bin/Debug/Polonium.Tasks.*.nupkg | head -n 1)" --source hangman-lab
SCRIPT_DIR=$(dirname "$(realpath "${BASH_SOURCE[0]}")")/
LATEST_PACKAGE=$(ls -t "${SCRIPT_DIR}"bin/Debug/Polonium.Tasks.*.nupkg 2>/dev/null | head -n 1)
if [[ -z "$LATEST_PACKAGE" ]]; then
echo "❌ Error: No .nupkg file found in ${SCRIPT_DIR}/bin/Debug/"
exit 1
fi
echo "🚀 Pushing NuGet package: $LATEST_PACKAGE"
dotnet nuget push "$LATEST_PACKAGE" --source hangman-lab --skip-duplicate

82
src/PoloniumTask.cs Normal file
View File

@@ -0,0 +1,82 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.Build.Utilities;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
namespace Polonium.Tasks;
public abstract class PoloniumTask : Task
{
protected static bool HasGetterOnly(PropertyDeclarationSyntax property)
{
var registryAttribute = property.AttributeLists
.SelectMany(a => a.Attributes)
.FirstOrDefault(a => a.Name.ToString() == "RegistryPassThrough");
if (registryAttribute?.ArgumentList != null)
{
foreach (var argument in registryAttribute.ArgumentList.Arguments)
{
if (argument.Expression is LiteralExpressionSyntax literal)
{
if (literal.Kind() == SyntaxKind.TrueLiteralExpression)
return true;
if (literal.Kind() == SyntaxKind.FalseLiteralExpression)
return false;
}
}
}
return false;
}
protected static string GetDisplayName(ClassDeclarationSyntax cls)
{
string name = cls.Identifier.Text;
SyntaxNode node = cls.Parent;
while (node is not null)
{
if(node is NamespaceDeclarationSyntax ns)
name = ns.Name.ToString() + "." + name;
else if (node is FileScopedNamespaceDeclarationSyntax fs)
name = fs.Name.ToString() + "." + name;
node = node.Parent;
}
return name;
}
protected static string GetRelativePath(string basePath, string fullPath)
{
Uri baseUri = new Uri(basePath.EndsWith(Path.DirectorySeparatorChar.ToString()) ? basePath : basePath + Path.DirectorySeparatorChar);
Uri fullUri = new Uri(fullPath);
return Uri.UnescapeDataString(baseUri.MakeRelativeUri(fullUri).ToString().Replace('/', Path.DirectorySeparatorChar));
}
protected static string GetDisplayName(TypeSyntax type)
{
if (type is IdentifierNameSyntax identifierName)
return identifierName.Identifier.Text;
if (type is QualifiedNameSyntax qualifiedName)
return GetDisplayName(qualifiedName.Left) + "." + GetDisplayName(qualifiedName.Right);
if (type is GenericNameSyntax genericName)
{
string typeName = genericName.Identifier.Text;
string typeArguments = string.Join(", ", genericName.TypeArgumentList.Arguments.Select(GetDisplayName));
return $"{typeName}<{typeArguments}>";
}
if (type is AliasQualifiedNameSyntax aliasQualifiedName)
return $"{aliasQualifiedName.Alias.Identifier.Text}::{GetDisplayName(aliasQualifiedName.Name)}";
if (type is PredefinedTypeSyntax predefinedType)
return predefinedType.Keyword.Text;
return type.ToString();
}
protected static IEnumerable<string> GetUsings(string code)
{
SyntaxTree tree = CSharpSyntaxTree.ParseText(code);
CompilationUnitSyntax root = tree.GetCompilationUnitRoot();
return root.Usings
.Select(u => u.ToString());
}
}

View File

@@ -4,13 +4,13 @@ using System.IO;
using System.Linq;
using System.Text;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
namespace Polonium.Tasks;
using Polonium.Tasks;
public class GenerateProxyNodesTask : Task
// ReSharper disable once CheckNamespace
public class GenerateProxyNodesTask : PoloniumTask
{
[Required]
public string SourceDirectory { get; set; }
@@ -97,19 +97,6 @@ public class GenerateProxyNodesTask : Task
}
}
private string GetDisplayName(ClassDeclarationSyntax cls)
{
string name = cls.Identifier.Text;
SyntaxNode node = cls.Parent;
while (node is not null)
{
if(node is NamespaceDeclarationSyntax ns)
name = ns.Name.ToString() + "." + name;
else if (node is FileScopedNamespaceDeclarationSyntax fs)
name = fs.Name.ToString() + "." + name;
node = node.Parent;
}
return name;
}
}

View File

@@ -0,0 +1,78 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Microsoft.Build.Framework;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Polonium.Tasks;
// ReSharper disable once CheckNamespace
public class GenerateRegistryPassThrough : PoloniumTask
{
[Required] public string ProjectDir { get; set; }
public override bool Execute()
{
try
{
StringBuilder sb = new();
string csFile = Directory
.GetFiles($"{ProjectDir}src", "PoloniumRegistry.cs", SearchOption.TopDirectoryOnly)
.FirstOrDefault();
string code = File.ReadAllText(csFile!);
sb.AppendLine("#pragma warning disable IDE0130");
foreach (string use in GetUsings(code))
sb.AppendLine(use);
sb
.AppendLine("using System.Collections.Generic;")
.AppendLine("// ReSharper disable once CheckNamespace")
.AppendLine("public static partial class GlobalRegistry")
.AppendLine("{");
SyntaxTree tree = CSharpSyntaxTree.ParseText(code);
CompilationUnitSyntax root = tree.GetCompilationUnitRoot();
ClassDeclarationSyntax clas = root
.DescendantNodes()
.OfType<ClassDeclarationSyntax>()
.FirstOrDefault(cls => cls.Identifier.Text == "PoloniumRegistry");
IEnumerable<PropertyDeclarationSyntax> properties = clas?.Members
.OfType<PropertyDeclarationSyntax>()
.Where(m => m.AttributeLists
.SelectMany(a => a.Attributes)
.Any(a => a.Name.ToString() == "RegistryPassThrough"));
if (properties is null)
return false;
foreach (PropertyDeclarationSyntax property in properties)
{
if (HasGetterOnly(property))
sb.AppendLine($" public static {GetDisplayName(property.Type)} {property.Identifier.ToString()} => PoloniumRegistry.{property.Identifier.ValueText};");
else
{
sb
.AppendLine($" public static {GetDisplayName(property.Type)} {property.Identifier.ToString()}")
.AppendLine(" {")
.AppendLine($" get => PoloniumRegistry.{property.Identifier.ValueText};")
.AppendLine($" set => PoloniumRegistry.{property.Identifier.ValueText} = value;")
.AppendLine(" }");
}
}
sb
.AppendLine("}")
.AppendLine("#pragma warning restore IDE0130");
File.WriteAllText($"{ProjectDir}Package/embedded/Patches/RegistryPassThrough.p.cs", sb.ToString());
return true;
}
catch (Exception e)
{
Log.LogErrorFromException(e);
return false;
}
}
}

View File

@@ -2,11 +2,11 @@ using System;
using System.IO;
using System.Text;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using Polonium.Tasks;
namespace Polonium.Tasks;
public class GenerateTextureSetTask : Task
// ReSharper disable once CheckNamespace
public class GenerateTextureSetTask : PoloniumTask
{
[Required]
public string RootPath { get; set; }
@@ -103,11 +103,6 @@ public class GenerateTextureSetTask : Task
}
}
private string GetRelativePath(string basePath, string fullPath)
{
Uri baseUri = new Uri(basePath.EndsWith(Path.DirectorySeparatorChar.ToString()) ? basePath : basePath + Path.DirectorySeparatorChar);
Uri fullUri = new Uri(fullPath);
return Uri.UnescapeDataString(baseUri.MakeRelativeUri(fullUri).ToString().Replace('/', Path.DirectorySeparatorChar));
}
}