Skip to content

Latest commit

 

History

History
263 lines (224 loc) · 12.4 KB

REPOLAYOUT.md

File metadata and controls

263 lines (224 loc) · 12.4 KB

Repository Layout

This repository is meant to be built as a Gradle multi-project build with approximately the following structure. For simplicity, not every subproject will be detailed in this document.

aws-toolkit-jetbrains
├── buildSrc                                :buildSrc
│   ├── ⋮
│   └── build.gradle.kts 
│
├── detekt-rules                            :detekt-rules
│   ├── ⋮
│   └── build.gradle.kts 
│
├── ui-tests                                :ui-tests
│   ├── ⋮
│   └── build.gradle.kts 
│
├── common                                  :common
│   ├── ⋮
│   └── build.gradle.kts 
│
├── plugins
│   ├── core                                :plugin-core
│   │   ├── sdk-codegen                     :plugin-core:sdk-codegen
│   │   │   ├── ⋮
│   │   │   └── build.gradle.kts 
│   │   ├── community                       :plugin-core:community
│   │   │   ├── ⋮
│   │   │   └── build.gradle.kts
│   │   ├── ultimate                        :plugin-core:ultimate
│   │   │   ├── ⋮
│   │   │   └── build.gradle.kts
│   │   ├── rider                           :plugin-core:rider
│   │   │   ├── ⋮
│   │   │   └── build.gradle.kts
│   │   └── build.gradle.kts
│   │
│   ├── toolkit                             :plugin-toolkit
│   │   ├── community                       :plugin-toolkit:community
│   │   │   ├── ⋮
│   │   │   └── build.gradle.kts
│   │   ├── ultimate                        :plugin-toolkit:ultimate
│   │   │   ├── ⋮
│   │   │   └── build.gradle.kts
│   │   ├── rider                           :plugin-toolkit:rider
│   │   │   ├── ⋮
│   │   │   └── build.gradle.kts
│   │   ├── gateway                         :plugin-toolkit:gateway
│   │   │   ├── ⋮
│   │   │   └── build.gradle.kts
│   │   └── build.gradle.kts
│   │
│   ├── amazonq                              :plugin-amazonq
│   │   ├── codewhisperer                   :plugin-amazonq:codewhisperer
│   │   │   ├── community                   :plugin-amazonq:codewhisperer:community
│   │   │   │   ├── ⋮
│   │   │   │   └── build.gradle.kts
│   │   │   ├── ultimate                    :plugin-amazonq:codewhisperer:ultimate
│   │   │   │   ├── ⋮
│   │   │   │   └── build.gradle.kts
│   │   │   └── build.gradle.kts
│   │   ├── codemodernizer                  :plugin-amazonq:codemodernizer
│   │   │   ├── community                   :plugin-amazonq:codemodernizer:community
│   │   │   │   ├── ⋮
│   │   │   │   └── build.gradle.kts
│   │   │   └── build.gradle.kts
│   │   ├── ⋮
│   │   ├── mynah-ui                        :plugin-amazonq:mynah-ui  
│   │   │   ├── ⋮
│   │   │   └── build.gradle.kts
│   │   └── build.gradle.kts 
│   │
│   └── toolbox                             :plugin-toolbox
│       ├── ⋮
│       └── build.gradle.kts 
│
│
├── build.gradle.kts  
└── settings.gradle.kts  

The intent of the above directory structure is to support emitting multiple discrete release artifacts from a single monorepo. Where practical, CODEOWNERS should be accurately defined to facilitate proper assignment of pull requests. This layout also conveniently allows us to define GitHub rulesets for specific reposistory subprojects.

Subprojects

Sub-projects should naturally fall along natural, logical boundaries. For example:

  • :buildSrc: The standard Gradle convention for encapsulated build logic
  • :detekt-rules: detekt custom rules and configuration for the entire repository
  • :common: Common utilities shared across all release artifacts
  • :ui-tests: UI tests for all release artifacts

However, sub-projects in plugins/ are primary defined along feature and code ownership boundaries. Instead of the standard :plugins:<artifact>:<sub-sub-project> structure, we reduce nesting by defining these projects as :plugin-<artifact>:<sub-sub-project>.

Sourcesets defined in each sub-project are utilized in the conventional manner for a Kotlin/JVM project. Use of Java is discouraged in this project; all new code should be written in Kotlin with the standard coding conventions.

Since we have very little Java remaining and new code is exclusively Kotlin, we do not follow the standard Gradle directory configuration. Instead, we allow Kotlin and Java code to be rooted directly against the subproject root:

subproject
├── src
│   ├── file1.kt
│   ├── file2.kt
│   ├── ⋮
│   └── file.java
├── tst
│   ├── file3.kt
│   └── ⋮
├── resources
│   ├── META-INF
│   └── ⋮
├── ⋮
└── build.gradle.kts

Sourcesets referencing code in the IntelliJ Platform have additional layout conventions, partially due to restrictions on how JetBrains' Gradle plugin configures a given sub-project, and partially to improve the developer experience by shifting runtime errors to compilation errors.

A (sub-)sub-project is further declared to segment code according to platform-level dependencies. For example, code residing in community/ only references dependencies in the "community" IDEs (IntelliJ IDEA Community, PyCharm Community, etc)., which code residing in ultimate/ only references dependencies in the "ultimate" (paid) IDEs. The "ultimate" platform itself is a superset of "community", and so the "ultimate" sub-project takes a direct dependency on the "community" sub-project to support code-reuse.

An additional concern is supporting functionality across multiple IDE major versions where a dependent platform API changes signatures across major versions. We support this by conditionally including additional source files depending on the ideProfileName Gradle property (overridden in gradle.properties or at build time).

subproject
├── src             // always included
│   └── ⋮
├── src-231-232     // only included for 2023.1 to 2023.2 inclusive
│   └── ⋮
├── tst-231         // only included for the '2023.1' IDE major version
│   └── ⋮
├── resources-231+  // included for all builds >= 2023.1
│   └── ⋮
└── ⋮

Full documentation on the supported folder patterns can be found on the findFolders utility in :buildSrc.

For artifacts where major functional logic is developed by multiple independent teams, we optionally support another layer of subprojects to increase code locality during development

Below is a sample of the layout and sourceset interactions for the given artifacts:

  • plugin-core.zip
  • plugin-toolkit.zip
  • plugin-amazonq.zip
flowchart LR
    common

    common <-. depends/input for .-> plugin-core
    common <-. depends/input for .-> plugin-toolkit
    common <-. depends/input for .-> plugin-amazonq

    subgraph plugin-core
        resources-core[resources]
        sdk-codegen[sdk-codegen]
        community-core --depends--> resources-core
        community-core --depends--> sdk-codegen

        subgraph intellij platform sourcesets
            community-core[community]
            ultimate-core[ultimate]
            rider-core[rider]

            ultimate-core --depends--> community-core
            rider-core --depends--> ultimate-core
            rider-core --depends--> community-core

            community-core -. input for .-> instrument-core
            rider-core -. input for .-> instrument-core
            ultimate-core -. input for .-> instrument-core
            instrument-core[[InstrumentJarTask]]
        end

        resources-core -. input for .-> build-core
        sdk-codegen -. input for .-> build-core
        instrument-core -. input for .-> build-core
        build-core[[PrepareSandbox + BuildPlugin]]
        
        build-core -- emits --> plugincorezip
        plugincorezip[plugin-core.zip\n* instrumented-community.jar\n* instrumented-ultimate.jar\n* instrumented-rider.jar\n* resources.jar\n* sdk-codegen.jar\n* common.jar]
        style plugincorezip text-align:left
    end

    subgraph plugin-toolkit
        resources-toolkit[resources]

        community-toolkit --depends--> resources-toolkit
        subgraph plugintoolkitintellij[intellij platform sourcesets]
            community-toolkit[community]
            ultimate-toolkit[ultimate]
            rider-toolkit[rider]

            ultimate-toolkit --depends--> community-toolkit
            rider-toolkit --depends--> ultimate-toolkit
            rider-toolkit --depends--> community-toolkit

            community-toolkit -. input for .-> instrument-toolkit
            rider-toolkit -. input for .-> instrument-toolkit
            ultimate-toolkit -. input for .-> instrument-toolkit
            instrument-toolkit[[InstrumentJarTask]]
        end

        resources-toolkit -. input for .-> build-toolkit
        instrument-toolkit -. input for .-> build-toolkit
        build-toolkit[[PrepareSandbox + BuildPlugin]]

        build-toolkit -- emits --> plugintoolkitzip
        plugintoolkitzip[plugin-toolkit.zip\n* instrumented-community.jar\n* instrumented-ultimate.jar\n* instrumented-rider.jar\n* resources.jar\n* common.jar]
        style plugintoolkitzip text-align:left
    end


    subgraph plugin-amazonq
        direction LR
        mynah-ui

        subgraph codewhisperer[codewhisperer: intellij platform sourcesets]
            community-codewhisperer[community]
            ultimate-codewhisperer[ultimate]

            ultimate-codewhisperer --depends--> community-codewhisperer

            community-codewhisperer -. input for .-> instrument-codewhisperer
            ultimate-codewhisperer -. input for .-> instrument-codewhisperer
            instrument-codewhisperer[[InstrumentJarTask]]
        end

        subgraph amazonq[amazonq shared: intellij platform sourcesets]
            community-amazonq[community]
            ultimate-amazonq[ultimate]
            
            ultimate-amazonq --depends--> community-amazonq

            community-amazonq -. input for .-> instrument-amazonq
            ultimate-amazonq -. input for .-> instrument-amazonq
            instrument-amazonq[[InstrumentJarTask]]
        end

        subgraph codemodernizer[codemodernizer: intellij platform sourcesets]
            community-codemodernizer[community]

            community-codemodernizer -. input for .-> instrument-codemodernizer
            instrument-codemodernizer[[InstrumentJarTask]]
        end

        codewhisperer --depends---> amazonq
        codemodernizer --depends---> amazonq

        mynah-ui -. input for .-> build-amazonq
        instrument-amazonq -. input for .-> build-amazonq
        instrument-codewhisperer -. input for .-> build-amazonq
        instrument-codemodernizer -. input for .-> build-amazonq
        build-amazonq[[PrepareSandbox + BuildPlugin]]
        
        build-amazonq -- emits --> pluginamazonqzip
        pluginamazonqzip[plugin-amazonq.zip\n* mynah-ui.jar\n* instrumented-amazonqshared-community.jar\n* instrumented-amazonqshared-ultimate.jar\n* instrumented-codewhisperer-community.jar\n* instrumented-codewhisperer-ultimate.jar\n* instrumented-chat-community.jar\n* instrumented-codemodernizer-community.jar\n* common.jar]
        style pluginamazonqzip text-align:left
    end

    plugin-toolkit -. runtime dependency on API .-> plugincorezip
    plugin-amazonq -. runtime dependency on API .-> plugincorezip
Loading