Composables

Setup Popcorn Plugin

Organization

CodandoTV

Use when configuring a multi-module Kotlin Multiplatform or Android project to use the PopcornGpParentPlugin for architectural rule enforcement. Triggers on phrases like "setup popcorn", "configure popcorn plugin", "add popcorn to project", "architectural rules setup", "enforce module dependencies".

Overview

Repository
CodandoTV/popcorn-guineapig
Publisher
CodandoTV
Stars
25
Forks
3
Bundled files
0
License
MIT
Updated
Nov 15, 2026

Installation

tmp=$(mktemp -d)
git clone --depth 1 https://github.com/CodandoTV/popcorn-guineapig.git "$tmp"
mkdir -p ~/.claude/skills
cp -R "$tmp/popcornguineapigplugin/src/main/resources/skills/setup-popcorn-plugin" ~/.claude/skills/setup-popcorn-plugin
rm -rf "$tmp"

Instructions

Setup Popcorn Plugin

Guides the setup of PopcornGpParentPlugin in a multi-module Kotlin Multiplatform (KMP) or Android project to enforce architectural rules on module dependency graphs.

When to use

  • Initializing architectural rule enforcement in a new or existing multi-module project
  • Migrating from per-module rule definitions to centralized parent plugin configuration
  • Setting up CI/CD validation for module dependency boundaries
  • Onboarding a team to automated architecture checks

Prerequisites

Requirement Minimum version
Java 17
Gradle 8.11
Kotlin 2.2.0
Android Gradle Plugin 8.7.3 (Android projects only)

Detection: choose the right setup path

Before configuring, determine how the project manages build infrastructure by checking these in order:

Infrastructure detected Where to place plugin + rules
build-logic/ directory exists Convention plugin in build-logic/, applied in root
buildSrc/ directory exists Plugin class in buildSrc/, applied in root
Neither exists Apply plugin + DSL directly in root build.gradle.kts

Ask the user about their project structure if it is unclear.

Path 1: build-logic (convention plugins)

1.1 Add dependency

In build-logic/build.gradle.kts, add:

implementation("io.github.codandotv:popcornguineapig:<latest-version>")
1.2 Create the setup convention plugin

Create build-logic/src/main/kotlin/popcorngp-setup.gradle.kts:

plugins {
    id("io.github.codandotv.popcorngpparent")
}

popcornGuineapigParentConfig {
    type = ProjectType.KMP  // or ProjectType.ANDROID

    children = listOf(
        PopcornChildConfiguration(
            moduleNameRegex = ":util:[a-z]+",
            rules = listOf(
                NoDependencyRule(),
            ),
        ),
        PopcornChildConfiguration(
            moduleNameRegex = ":feature:[a-z]+",
            rules = listOf(
                DoNotWithRule(
                    notWith = listOf("data"),
                ),
            ),
        ),
        // Add more children matching your module structure
    )
}
1.3 Apply the convention plugin

In root build.gradle.kts:

plugins {
    id("popcorngp-setup")
}

Path 2: buildSrc

2.1 Add dependency

In buildSrc/build.gradle.kts, add:

implementation("io.github.codandotv:popcornguineapig:<latest-version>")
2.2 Create the plugin class

Create buildSrc/src/main/kotlin/PopcornSetupPlugin.kt:

import com.github.codandotv.popcorn.presentation.PopcornGpParentPlugin
import org.gradle.api.Plugin
import org.gradle.api.Project

class PopcornSetupPlugin : Plugin<Project> {
    override fun apply(target: Project) {
        target.plugins.apply(PopcornGpParentPlugin::class.java)

        target.extensions.configure("popcornGuineapigParentConfig") {
            // Use withGroovyBuilder or access via typed extension
        }
    }
}

Register it in buildSrc/build.gradle.kts:

gradlePlugin {
    plugins {
        create("popcornSetup") {
            id = "popcorn-setup"
            implementationClass = "PopcornSetupPlugin"
        }
    }
}
2.3 Apply in root

In root build.gradle.kts:

plugins {
    id("popcorn-setup")
}

Path 3: Direct root build.gradle.kts

3.1 Apply plugin and configure

In root build.gradle.kts:

plugins {
    id("io.github.codandotv.popcorngpparent") version "<latest-version>"
}

popcornGuineapigParentConfig {
    type = ProjectType.KMP  // or ProjectType.ANDROID

    children = listOf(
        PopcornChildConfiguration(
            moduleNameRegex = ":util:[a-z]+",
            rules = listOf(
                NoDependencyRule(),
            ),
        ),
        PopcornChildConfiguration(
            moduleNameRegex = ":feature:[a-z]+",
            rules = listOf(
                DoNotWithRule(
                    notWith = listOf("data"),
                ),
            ),
        ),
    )
}

Mapping module structure to rules

Apply clean architecture principles when writing regex patterns and rules:

Architectural layer Typical module pattern Common rules
Utility / Common :util:*, :core:*, :common:* NoDependencyRule() — no internal dependencies
Domain :*:domain NoDependencyRule() or DoNotWithRule(notWith = listOf("data", "presentation"))
Data :*:data JustWithRule(justWith = listOf("domain")) — only depends on domain
Feature / UI :feature:* DoNotWithRule(notWith = listOf("data")) — depends on domain, not data directly
Guidelines
  • Each PopcornChildConfiguration should represent a coherent set of modules with the same constraints
  • Start minimal — add rules incrementally as the architecture stabilizes
  • Prefer DoNotWithRule over JustWithRule when the allowed dependency list is unbounded
  • Test regex patterns manually before committing: ":feature:home".matches(Regex(":feature:[a-z]+"))
  • All rule entries in notWith and justWith are treated as regular expressions

Rule reference

Rule Constructor Behavior
NoDependencyRule NoDependencyRule() Matched modules must have zero internal dependencies
JustWithRule JustWithRule(justWith = listOf("pattern")) Matched modules may only depend on modules matching at least one justWith pattern
DoNotWithRule DoNotWithRule(notWith = listOf("pattern")) Matched modules must NOT depend on modules matching any notWith pattern

Custom rules can be created by implementing the PopcornGuineaPigRule interface.

Project type selection

// For Kotlin Multiplatform projects
type = ProjectType.KMP
// Resolves dependencies from: commonMainImplementation, androidMainImplementation, iosMainImplementation

// For Android or plain JVM projects
type = ProjectType.ANDROID  // or ProjectType.JAVA
// Resolves dependencies from: implementation

Verification

After setup, validate:

# Run the architecture check
./gradlew popcornParent

# Generate error report
./gradlew popcornParent -PerrorReportEnabled

# Evaluate only selected modules (useful in CI)
./gradlew popcornParent --modules=":app,:core:network"

# Generate module metrics
./gradlew popcornModuleMetrics

# If cached configuration phase is enabled
./gradlew popcornParent --no-configuration-cache

Error reports are placed at <module>/build/reports/popcornguineapig/errorReport.md.

--modules (available from 3.3.0) accepts comma-separated Gradle project paths. Unknown paths fail the build; selected modules without a matching PopcornChildConfiguration are skipped with a warning.

Red flags

  • Configuring JustWithRule without clear module boundaries — the rule is strict and may break as modules grow
  • Overly broad regex patterns (e.g. :*) that match unintended modules
  • Forgetting to differentiate between KMP and Android ProjectType — wrong type means wrong dependency configurations are analyzed
  • Not committing the convention plugin file — other developers won't get the same checks

Clean code principles

  • Match regex patterns to real architectural layers in the project, not arbitrary groupings
  • Each module group should have a clear, single responsibility for its rules
  • Keep the configuration file well-structured and commented with the intent behind each rule
  • Review rules during PRs alongside code changes — architectural boundaries evolve with the project

FAQ

What does Setup Popcorn Plugin do?

Use when configuring a multi-module Kotlin Multiplatform or Android project to use the PopcornGpParentPlugin for architectural rule enforcement. Triggers on phrases like "setup popcorn", "configure popcorn plugin", "add popcorn to project", "architectural rules setup", "enforce module dependencies".

Who made Setup Popcorn Plugin?

CodandoTV (an organization) publishes it in the CodandoTV/popcorn-guineapig repository on GitHub.

Is Setup Popcorn Plugin free?

Yes. Setup Popcorn Plugin is open source, published by CodandoTV under the MIT license.

What comes with Setup Popcorn Plugin?

Just its instructions. Everything the agent needs is in one SKILL.md file.

Which agents can use Setup Popcorn Plugin?

Any coding agent that reads SKILL.md files, including Claude Code, Codex, Cursor, GitHub Copilot and Gemini CLI. The agent loads the skill when a task matches its description.

What are agent skills?

An agent skill is a folder with a SKILL.md file: instructions that teach a coding agent how to do one kind of task, and optionally files it can read while it works. The agent keeps only the skill's name and description in mind and reads the rest when a task calls for it.

How are agent skills different from MCP servers?

An MCP server gives an agent new tools to call, code that runs somewhere and returns results. A skill gives it knowledge: how to approach a task with the tools it already has. Many agents use both.

How can my agent test my Android app?

Robomori lets coding agents create, start and control Android emulators and devices from one command, so they can install your app, take screenshots and check dark mode, font sizes and languages.

You're subscribed

The next lesson lands in on Wednesday.