How to pass multiple flags as a Cake argument?

258 Views Asked by At

We have a number of build flags we'd like to be able to pass to our Cake script as a single argument. Based on this answer and the TypeConverter documentation, I would expect the following simplified code to compile and run.

public class BuildFlagsConverter : TypeConverter
{
  public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
  {
    return true;
  }

  public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
  {
    return BuildFlags.None;
  }
}

[Flags]
[TypeConverter(typeof(BuildFlagsConverter))]
enum BuildFlags
{
  None = 0,
  FeatureOne = 1,
  FeatureTwo = 2,
  All = FeatureOne | FeatureTwo,
}

var buildFlags = Argument<BuildFlags>("buildFlags", BuildFlags.All);

I would then expect to be able to call cake --buildFlags="FeatureOne|FeatureTwo" to build. Instead, Cake is throwing the following error:

Error: One or more errors occurred. (FeatureOne|FeatureTwo is not a valid value for BuildFlags.)

I thought this might be related to using an enum instead of a class, so I tried converting BuildFlags to a static class with static getters for each of the above values. However, in this case I was still getting an error:

Error: One or more errors occurred. (TypeConverter cannot convert from System.String.)

Am I missing something? Is there a better way to do this? Ideally, we would still get the enum syntax within the script itself, but I suppose I'm open to alternatives.

1

There are 1 best solutions below

7
On

Update

After troubleshooting, it seems that using custom type converters works well on .NET, .NET Core, and .NET Framework, but does not work well on Mono.

Reported as a bug - https://github.com/cake-build/cake/issues/3333


Is it possible that you're using an old version of Cake that doesn't support custom type converters?

I tested your code on the latest version of Cake as of this writing (1.1.0) and it worked as expected.

Cake Type Converter example run

Cake Type Converter example run on MacOS


using System.ComponentModel;
using System.Globalization;

public class BuildFlagsConverter : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        return true;
    }

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        return BuildFlags.None;
    }
}

[Flags]
[TypeConverter(typeof(BuildFlagsConverter))]
enum BuildFlags
{
    None = 0,
    FeatureOne = 1,
    FeatureTwo = 2,
    All = FeatureOne | FeatureTwo,
}

var buildFlags = Argument<BuildFlags>("buildFlags", BuildFlags.All);
Information("buildFlags converted to: {0}", buildFlags);