Skip to content

Add enum-typed flags to Gradle DSL (#162)#185

Merged
kirich1409 merged 2 commits into
mainfrom
feat/gradle-dsl-enum-flags
May 17, 2026
Merged

Add enum-typed flags to Gradle DSL (#162)#185
kirich1409 merged 2 commits into
mainfrom
feat/gradle-dsl-enum-flags

Conversation

@kirich1409
Copy link
Copy Markdown
Contributor

Add `enum(key, typeFqn, default)` declarator to `FlagContainer` with full round-trip support through the generation pipeline.

New public DSL surface

```kotlin
featured {
localFlags {
enum(
key = "checkout_variant",
typeFqn = "com.example.CheckoutVariant",
default = "LEGACY",
) {
description = "Checkout flow variant"
category = "Checkout"
}
}
}
```

Generator behaviour

  • ConfigParamGenerator — emits `ConfigParam<com.example.CheckoutVariant>(key = "checkout_variant", defaultValue = com.example.CheckoutVariant.LEGACY)`
  • ExtensionFunctionGenerator — emits `fun ConfigValues.getCheckoutVariant(): com.example.CheckoutVariant` (same `get…` pattern as non-Boolean primitives)
  • ProguardRulesGenerator — enum flags are intentionally excluded from `-assumevalues` rules; their values are resolved at runtime from providers and cannot be assumed at build time (per issue body)
  • IosConstValGenerator — enum flags are skipped; `const val` only supports primitives and `String`

iOS generator

Enum flags are silently skipped by `IosConstValGenerator` in both `generate` (iosMain actual) and `generateExpect` (commonMain expect). The class KDoc documents this constraint. No structural decision is deferred — the behaviour is fully defined and tested.

Test coverage

New/extended tests:

  • `FlagContainerTest` — `enum` declarator stores FQN type and constant default; configure block works; descriptor round-trip preserves all fields
  • `ConfigParamGeneratorTest` — FQN type argument, `FQN.CONSTANT` default syntax, inclusion in local object
  • `ExtensionFunctionGeneratorTest` — `get…` extension generated for enum; `is…Enabled` is not used
  • `ProguardRulesGeneratorTest` — enum flags excluded from rules; blank output when only enum flags present
  • `IosConstValGeneratorTest` — enum flags skipped in both `generate` and `generateExpect`; blank when all-enum list
  • `FeaturedPluginIntegrationTest` — fixture now declares an enum flag; `assertContainsAssumevaluesBlock` asserts `checkoutVariant` is absent from ProGuard output

Fixture source: `CheckoutVariant.kt` added to the Android test fixture so `assembleRelease` can compile the generated `ConfigParam`.

Closes #162

Adds `FlagContainer.enum(key, typeFqn, default)` declarator. Enum flags
round-trip through FlagSpec/ResolveFlagsTask as the fully-qualified class
name stored in the `type` field. LocalFlagEntry.isEnum detects enum types
via presence of '.' in the type string.

Generator behaviour:
- ConfigParamGenerator: emits ConfigParam<com.example.Foo> with default
  expressed as FQN.CONSTANT_NAME.
- ExtensionFunctionGenerator: emits get…() extension returning the raw
  enum type (same as non-Boolean primitives).
- ProguardRulesGenerator: skips enum flags — values are resolved at runtime
  and cannot be assumed at build time.
- IosConstValGenerator: skips enum flags — const val only supports
  primitives and String.

Integration test fixture: adds CheckoutVariant enum source so assembleRelease
compiles generated ConfigParam<CheckoutVariant>. assertContainsAssumevaluesBlock
now also asserts enum flags are absent from ProGuard output.
@kirich1409 kirich1409 marked this pull request as ready for review May 17, 2026 10:24
Copilot AI review requested due to automatic review settings May 17, 2026 10:24
@qodo-code-review
Copy link
Copy Markdown

Review Summary by Qodo

Add enum-typed flags to Gradle DSL with full generation pipeline support

✨ Enhancement

Grey Divider

Walkthroughs

Description
• Add enum(key, typeFqn, default) DSL declarator to FlagContainer
• Enum flags round-trip through generation pipeline with FQN type support
• Generators handle enums: ConfigParam uses FQN syntax, extension functions use get…() pattern
• ProGuard and iOS generators intentionally skip enums (runtime values, const val limitations)
• Comprehensive test coverage including integration test with fixture enum
Diagram
flowchart LR
  DSL["FlagContainer.enum<br/>DSL declarator"]
  FlagSpec["FlagSpec stores<br/>FQN type + default"]
  ConfigParam["ConfigParamGenerator<br/>emits FQN.CONSTANT syntax"]
  Extension["ExtensionFunctionGenerator<br/>emits get…() pattern"]
  ProGuard["ProguardRulesGenerator<br/>skips enums"]
  iOS["IosConstValGenerator<br/>skips enums"]
  DSL --> FlagSpec
  FlagSpec --> ConfigParam
  FlagSpec --> Extension
  FlagSpec --> ProGuard
  FlagSpec --> iOS
Loading

Grey Divider

File Changes

1. featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/FlagContainer.kt ✨ Enhancement +21/-0

Add enum() declarator with full DSL support

featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/FlagContainer.kt


2. featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/FlagSpec.kt 📝 Documentation +2/-1

Update type documentation to include enum FQNs

featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/FlagSpec.kt


3. featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/LocalFlagEntry.kt ✨ Enhancement +13/-1

Add isEnum property detecting FQN types via dot

featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/LocalFlagEntry.kt


View more (12)
4. featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/FlagEntryUtils.kt 📝 Documentation +1/-1

Update extension function naming documentation for enums

featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/FlagEntryUtils.kt


5. featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/ConfigParamGenerator.kt ✨ Enhancement +5/-4

Emit FQN.CONSTANT syntax for enum default values

featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/ConfigParamGenerator.kt


6. featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/ProguardRulesGenerator.kt 📝 Documentation +4/-0

Document intentional exclusion of enum flags

featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/ProguardRulesGenerator.kt


7. featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/IosConstValGenerator.kt ✨ Enhancement +17/-6

Filter out enum flags from iOS const val generation

featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/IosConstValGenerator.kt


8. featured-gradle-plugin/src/test/kotlin/dev/androidbroadcast/featured/gradle/FlagContainerTest.kt 🧪 Tests +38/-0

Add enum flag storage and configuration tests

featured-gradle-plugin/src/test/kotlin/dev/androidbroadcast/featured/gradle/FlagContainerTest.kt


9. featured-gradle-plugin/src/test/kotlin/dev/androidbroadcast/featured/gradle/ConfigParamGeneratorTest.kt 🧪 Tests +23/-0

Add tests for enum ConfigParam generation

featured-gradle-plugin/src/test/kotlin/dev/androidbroadcast/featured/gradle/ConfigParamGeneratorTest.kt


10. featured-gradle-plugin/src/test/kotlin/dev/androidbroadcast/featured/gradle/ExtensionFunctionGeneratorTest.kt 🧪 Tests +17/-0

Add tests for enum extension function generation

featured-gradle-plugin/src/test/kotlin/dev/androidbroadcast/featured/gradle/ExtensionFunctionGeneratorTest.kt


11. featured-gradle-plugin/src/test/kotlin/dev/androidbroadcast/featured/gradle/ProguardRulesGeneratorTest.kt 🧪 Tests +21/-0

Add tests for enum exclusion from ProGuard rules

featured-gradle-plugin/src/test/kotlin/dev/androidbroadcast/featured/gradle/ProguardRulesGeneratorTest.kt


12. featured-gradle-plugin/src/test/kotlin/dev/androidbroadcast/featured/gradle/IosConstValGeneratorTest.kt 🧪 Tests +67/-0

Add tests for enum filtering in iOS generation

featured-gradle-plugin/src/test/kotlin/dev/androidbroadcast/featured/gradle/IosConstValGeneratorTest.kt


13. featured-gradle-plugin/src/test/kotlin/dev/androidbroadcast/featured/gradle/FeaturedPluginIntegrationTest.kt 🧪 Tests +9/-1

Assert enum flags absent from ProGuard output

featured-gradle-plugin/src/test/kotlin/dev/androidbroadcast/featured/gradle/FeaturedPluginIntegrationTest.kt


14. featured-gradle-plugin/src/test/fixtures/android-project/build.gradle.kts ⚙️ Configuration changes +1/-0

Add enum flag to test fixture DSL

featured-gradle-plugin/src/test/fixtures/android-project/build.gradle.kts


15. featured-gradle-plugin/src/test/fixtures/android-project/src/main/kotlin/dev/androidbroadcast/featured/testapp/CheckoutVariant.kt 🧪 Tests +6/-0

Add CheckoutVariant enum for fixture compilation

featured-gradle-plugin/src/test/fixtures/android-project/src/main/kotlin/dev/androidbroadcast/featured/testapp/CheckoutVariant.kt


Grey Divider

Qodo Logo

@qodo-code-review
Copy link
Copy Markdown

qodo-code-review Bot commented May 17, 2026

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider


Action required

1. iOS includes remote flags 🐞 Bug ≡ Correctness
Description
IosConstValGenerator filters out enum-typed entries but still generates expect/actual declarations
for remote flags, freezing remote defaults into compile-time constants. Because the iOS generation
task reads ResolveFlagsTask output containing both local and remote flags, this can incorrectly
eliminate runtime-configurable behavior on iOS.
Code

featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/IosConstValGenerator.kt[R33-34]

+        val eligible = entries.filterNot { it.isEnum }
+        if (eligible.isEmpty()) return ""
Evidence
The plugin wires ResolveFlagsTask output (containing both local and remote descriptors) into the iOS
const-val task; parsing preserves flagType, but IosConstValGenerator only filters by enum-ness and
never checks isLocal, so remote entries are emitted.

featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/FeaturedPlugin.kt[45-56]
featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/FeaturedPlugin.kt[117-132]
featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/ResolveFlagsTask.kt[53-60]
featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/ResolveFlagsTask.kt[64-69]
featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/ScanResultParser.kt[60-71]
featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/LocalFlagEntry.kt[28-29]
featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/IosConstValGenerator.kt[32-36]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`GenerateIosConstValTask` reads the unified flags file produced by `ResolveFlagsTask` (which includes both local and remote flags). `IosConstValGenerator` currently only filters out enums, so remote flags still end up as `expect val` / `actual const val`, incorrectly turning runtime-resolved remote values into compile-time constants.

### Issue Context
Other generators explicitly treat local and remote differently (e.g., ProGuard rules are local-only). iOS const-val generation should similarly operate on local flags only.

### Fix Focus Areas
- featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/FeaturedPlugin.kt[45-56]
- featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/FeaturedPlugin.kt[117-132]
- featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/ResolveFlagsTask.kt[53-60]
- featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/ResolveFlagsTask.kt[64-69]
- featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/ScanResultParser.kt[60-71]
- featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/IosConstValGenerator.kt[32-64]

### Suggested change
- In both `generate` and `generateExpect`, change eligibility to:
 - `val eligible = entries.filter { it.isLocal && !it.isEnum }`
- Add/update tests to include a remote flag and assert it is absent from iOS output.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Enum inputs unvalidated ✓ Resolved 🐞 Bug ☼ Reliability
Description
FlagContainer.enum accepts arbitrary typeFqn/default strings without enforcing a fully-qualified
enum type and a valid constant identifier, so malformed inputs can generate invalid Kotlin (e.g.,
non-FQN types won’t be treated as enum, and defaults containing '.' will be re-qualified). This
fails later in codegen rather than at DSL evaluation time, making builds break with opaque compiler
errors.
Code

featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/FlagContainer.kt[R95-102]

+    public fun enum(
+        key: String,
+        typeFqn: String,
+        default: String,
+        configure: FlagSpec.() -> Unit = {},
+    ) {
+        _flags += FlagSpec(key = key, defaultValue = default, type = typeFqn).apply(configure)
+    }
Evidence
The enum DSL stores raw strings, while downstream behavior depends on a heuristic (isEnum =
contains '.') and then concatenates type and default into a Kotlin expression; without validation,
invalid user input can easily bypass enum detection or generate an invalid reference.

featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/FlagContainer.kt[95-102]
featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/LocalFlagEntry.kt[28-40]
featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/ConfigParamGenerator.kt[65-72]
featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/IosConstValGenerator.kt[32-36]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`FlagContainer.enum(...)` persists `typeFqn` and `default` verbatim. Downstream generators infer enum-ness via `LocalFlagEntry.isEnum` and emit `"$type.$defaultValue"` for defaults; malformed inputs (e.g. `typeFqn = "CheckoutVariant"` or `default = "CheckoutVariant.LEGACY"`) will produce uncompilable generated Kotlin.

### Issue Context
This is a new public DSL entrypoint, so failing fast with a clear Gradle error message is preferable to later compilation failures in generated sources.

### Fix Focus Areas
- featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/FlagContainer.kt[95-102]
- featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/LocalFlagEntry.kt[30-40]
- featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/ConfigParamGenerator.kt[65-72]

### Suggested change
- Add `require('.' in typeFqn)` (or stronger validation) in `FlagContainer.enum`.
- Add `require(default.isNotBlank())` and reject `default` containing `.` (or require it matches a Kotlin identifier / backticked identifier pattern).
- Add/adjust unit tests to assert invalid inputs fail with a clear message.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds first-class support for enum-typed local flags in the Gradle DSL and threads the new type through code generation, while explicitly excluding enums from generators that can’t safely/meaningfully support them (ProGuard assumevalues, iOS const vals).

Changes:

  • Added enum(key, typeFqn, default) to FlagContainer and persisted enum type FQN + default constant through descriptors.
  • Updated generators to handle enum defaults (TypeFqn.CONSTANT) and to exclude enums from ProGuard rules and iOS const val output.
  • Extended unit/integration tests and the Android fixture to cover enum end-to-end behavior.

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/FlagContainer.kt Adds the public enum(...) DSL declarator for enum-typed flags.
featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/LocalFlagEntry.kt Introduces isEnum helper used by downstream generators.
featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/ConfigParamGenerator.kt Emits enum default values as TypeFqn.CONSTANT.
featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/IosConstValGenerator.kt Skips enum-typed entries when generating iOS expect/actual const val output.
featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/ProguardRulesGenerator.kt Documents intentional exclusion of enums from -assumevalues.
featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/FlagEntryUtils.kt Clarifies that enum flags use get… extension naming.
featured-gradle-plugin/src/test/kotlin/dev/androidbroadcast/featured/gradle/FlagContainerTest.kt Tests enum storage, configure block behavior, and descriptor round-trip contents.
featured-gradle-plugin/src/test/kotlin/dev/androidbroadcast/featured/gradle/ConfigParamGeneratorTest.kt Tests enum generic type emission and TypeFqn.CONSTANT default syntax.
featured-gradle-plugin/src/test/kotlin/dev/androidbroadcast/featured/gradle/ExtensionFunctionGeneratorTest.kt Tests get… extension generation for enum flags.
featured-gradle-plugin/src/test/kotlin/dev/androidbroadcast/featured/gradle/ProguardRulesGeneratorTest.kt Tests that enum flags are excluded from ProGuard rules.
featured-gradle-plugin/src/test/kotlin/dev/androidbroadcast/featured/gradle/IosConstValGeneratorTest.kt Tests that enum flags are skipped in iOS const-val generation.
featured-gradle-plugin/src/test/kotlin/dev/androidbroadcast/featured/gradle/FeaturedPluginIntegrationTest.kt Ensures fixture enum flag does not appear in ProGuard output.
featured-gradle-plugin/src/test/fixtures/android-project/build.gradle.kts Declares an enum flag in the fixture DSL.
featured-gradle-plugin/src/test/fixtures/android-project/src/main/kotlin/dev/androidbroadcast/featured/testapp/CheckoutVariant.kt Adds fixture enum type used by the new DSL flag.

Comment on lines +100 to +103
) {
_flags += FlagSpec(key = key, defaultValue = default, type = typeFqn).apply(configure)
}

Comment on lines 32 to 40
public fun generate(entries: List<LocalFlagEntry>): String {
if (entries.isEmpty()) return ""
val eligible = entries.filterNot { it.isEnum }
if (eligible.isEmpty()) return ""
return buildString {
appendLine(HEADER)
appendLine("package $GENERATED_PACKAGE")
appendLine()
entries.forEach { entry ->
eligible.forEach { entry ->
appendLine(actualDeclaration(entry))
Comment on lines +33 to +34
val eligible = entries.filterNot { it.isEnum }
if (eligible.isEmpty()) return ""
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. Ios includes remote flags 🐞 Bug ≡ Correctness

IosConstValGenerator filters out enum-typed entries but still generates expect/actual declarations
for remote flags, freezing remote defaults into compile-time constants. Because the iOS generation
task reads ResolveFlagsTask output containing both local and remote flags, this can incorrectly
eliminate runtime-configurable behavior on iOS.
Agent Prompt
### Issue description
`GenerateIosConstValTask` reads the unified flags file produced by `ResolveFlagsTask` (which includes both local and remote flags). `IosConstValGenerator` currently only filters out enums, so remote flags still end up as `expect val` / `actual const val`, incorrectly turning runtime-resolved remote values into compile-time constants.

### Issue Context
Other generators explicitly treat local and remote differently (e.g., ProGuard rules are local-only). iOS const-val generation should similarly operate on local flags only.

### Fix Focus Areas
- featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/FeaturedPlugin.kt[45-56]
- featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/FeaturedPlugin.kt[117-132]
- featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/ResolveFlagsTask.kt[53-60]
- featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/ResolveFlagsTask.kt[64-69]
- featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/ScanResultParser.kt[60-71]
- featured-gradle-plugin/src/main/kotlin/dev/androidbroadcast/featured/gradle/IosConstValGenerator.kt[32-64]

### Suggested change
- In both `generate` and `generateExpect`, change eligibility to:
  - `val eligible = entries.filter { it.isLocal && !it.isEnum }`
- Add/update tests to include a remote flag and assert it is absent from iOS output.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@kirich1409
Copy link
Copy Markdown
Contributor Author

Code review

Found 2 issues:

  1. LocalFlagEntry.isEnum ('.' in type) is an under-constrained heuristic with no validation guard in the FlagContainer.enum() DSL — both false-positive (e.g., legacy descriptor with java.lang.StringformatDefault() emits java.lang.String.someValue, broken Kotlin) and false-negative (unqualified typeFqn = "MyEnum" → falls to else branch, emits bare "LEGACY" instead of MyEnum.LEGACY). Both paths fail silently as a generated-code compile error rather than a clear DSL-time error. A require('.' in typeFqn) { "typeFqn must be a fully-qualified class name" } in FlagContainer.enum() would fail fast.

* - The generated `ConfigParam` default expression uses `TypeFqn.CONSTANT_NAME` syntax.
*/
public val isEnum: Boolean get() = '.' in type
/**

  1. featured-gradle-plugin/CLAUDE.md DSL example documents boolean/int/string declarators but not the new enum(...) declarator added in this PR. Project CLAUDE.md says: «When code is modified, update directly related docs — KDoc, inline comments, .md files.»

featured {
localFlags {
boolean("dark_mode", default = false) { category = "UI" }
int("max_retries", default = 3)
}
remoteFlags {
boolean("promo_banner", default = false) { description = "Show promo banner" }
}
}

🤖 Generated with Claude Code

- If this code review was useful, please react with 👍. Otherwise, react with 👎.

- Require '.' in typeFqn so unqualified names fail at configuration time
  rather than as a generated-code compile error.
- Add enum example to featured-gradle-plugin/CLAUDE.md DSL section.
@kirich1409 kirich1409 merged commit 8a8dbc6 into main May 17, 2026
9 of 10 checks passed
@kirich1409 kirich1409 mentioned this pull request May 17, 2026
20 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(gradle-plugin): support enum types in Gradle DSL

2 participants