Skip to content

Commit

Permalink
feat(execution): add on-demand value injection
Browse files Browse the repository at this point in the history
  • Loading branch information
matkoch committed Jan 17, 2024
1 parent eee9dc0 commit 2bdabd2
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Nuke.Common.Execution;
using Nuke.Common.Utilities;

namespace Nuke.Common.ValueInjection;

Expand All @@ -15,6 +17,23 @@ public void OnBuildInitialized(
IReadOnlyCollection<ExecutableTarget> executableTargets,
IReadOnlyCollection<ExecutableTarget> executionPlan)
{
ValueInjectionUtility.InjectValues(Build, x => x.GetType() != typeof(ParameterAttribute));
ValueInjectionUtility.InjectValues(Build, (member, attribute) =>
{
if (attribute.GetType() == typeof(ParameterAttribute))
return false;

if (!Build.GetType().HasCustomAttribute<OnDemandValueInjectionAttribute>() &&
!member.HasCustomAttribute<OnDemandAttribute>())
return true;

if (member.HasCustomAttribute<RequiredAttribute>())
return false;

var requiredMembers = executionPlan.SelectMany(x => x.DelegateRequirements)
.Where(x => x is not Expression<Func<bool>>)
.Select(x => x.GetMemberInfo()).ToList();

return requiredMembers.Contains(member);
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ internal class InjectParameterValuesAttribute : BuildExtensionAttributeBase, IOn
{
public void OnBuildCreated(IReadOnlyCollection<ExecutableTarget> executableTargets)
{
ValueInjectionUtility.InjectValues(Build, x => x.GetType() == typeof(ParameterAttribute));
ValueInjectionUtility.InjectValues(Build, (_, attribute) => attribute.GetType() == typeof(ParameterAttribute));
}
}
6 changes: 3 additions & 3 deletions source/Nuke.Build/Execution/ValueInjectionUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ object GetValue()
return (T) (s_valueCache[parameter] = s_valueCache.GetValueOrDefault(parameter) ?? GetValue());
}

public static void InjectValues<T>(T instance = default, Func<ValueInjectionAttributeBase, bool> filter = null)
public static void InjectValues<T>(T instance = default, Func<MemberInfo, Attribute, bool> filter = null)
{
filter ??= _ => true;
InjectValuesInternal(instance, GetInjectionMembers(instance?.GetType() ?? typeof(T)).Where(x => filter(x.Attribute)));
filter ??= (_, _) => true;
InjectValuesInternal(instance, GetInjectionMembers(instance?.GetType() ?? typeof(T)).Where(x => filter(x.Member, x.Attribute)));
}

private static void InjectValuesInternal<T>(
Expand Down
30 changes: 21 additions & 9 deletions source/Nuke.Build/ParameterAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,20 +67,32 @@ public override object GetValue(MemberInfo member, object instance)
}
}

/// <summary>
/// Marks a member as being required for the whole build.
/// </summary>
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public class RequiredAttribute : Attribute
{
}
public class RequiredAttribute : Attribute;

/// <summary>
/// Suppresses warning logging if value injection throws an exception.
/// </summary>
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public class OptionalAttribute : Attribute
{
}
public class OptionalAttribute : Attribute;

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter)]
public class SecretAttribute : Attribute
{
}
public class SecretAttribute : Attribute;

/// <summary>
/// Enables on-demand value injection, where non-parameter members are only injected if required by a target.
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public class OnDemandValueInjectionAttribute : Attribute;

/// <summary>
/// Marks a member to be injected only if required by a target.
/// </summary>
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
public class OnDemandAttribute : Attribute;

[AttributeUsage(AttributeTargets.Interface, AllowMultiple = false, Inherited = false)]
public class ParameterPrefixAttribute : Attribute
Expand Down

0 comments on commit 2bdabd2

Please sign in to comment.