# Source sets

> How Elide finds a project's sources and resources: the conventional src layout, declaring source sets in elide.pkl, precedence and per-set classpaths.

A source set is a named group of sources and resources. Elide derives compile, test and packaging tasks from each.

## Conventional layout

`main` is in `src/main`, `test` in `src/test`, any other set in `src/<name>`:

| Path | Meaning |
| --- | --- |
| `src/<set>/java`, `/kotlin`, `/js`, `/ts`, `/python` | Sources, one directory per language |
| `src/<set>/resources` | Resources |

- Every language directory that exists is compiled. With none, `src/<set>` itself is the source root.
- `src` is used as `src/main`; `test` or `tests` as `src/test`.
- `main` and `test` exist when their directories do. Other sets must be declared.

This layout needs no `sources` block:

```text
src/main/kotlin/sample/Main.kt
src/main/resources/app.properties
src/test/kotlin/sample/MainTest.kt
```

`elide project info` prints the resolved sets; `(by convention)` marks paths from the layout.

## Declare source sets

```pkl
sources {
  // A glob moves only the sources.
  ["main"] = "lib/**/*.kt"

  // A block sets more properties.
  ["integrationTest"] {
    type = "test"
    paths { "it/**/*.kt" }
  }
}
```

`new Sources.SourceSetSpec { … }` (with `import "elide:Sources.pkl" as Sources`) is the long form of the entry.
Paths are project-relative globs or directories; a directory is walked recursively.

## Precedence

Each declared property replaces the convention for that property only.

| Property | Left out | Declared |
| --- | --- | --- |
| `type` | Inferred from the name | Always used |
| `paths` | The conventional layout for the name | Used verbatim |
| `resources` | `src/<name>/resources`, when present | Used verbatim |
| `dependsOn` | Test and example sets see `main` | Used verbatim; empty means nothing |

| `type` | Inferred from | Behavior |
| --- | --- | --- |
| `test` | `test`, `tests` | Run by `elide test`; resolves `testPackages`. |
| `example` | `example`, `examples` | Production set. |
| `source` | any other name | Production set. |
| `other` | — | Production set. |

Artifacts that name no sources package every production set. A declared set whose paths cover `src/main` or
`src/test` replaces that conventional set, so no file compiles twice.

## Dependencies and classpaths

Production sets resolve `packages`, `modules`, `compileOnly`, `runtimeOnly` and `processors`. Test sets add
`testPackages` and the sets they depend on. A test set with `dependsOn {}` compiles and runs without `main`'s classes
and resources, but still resolves `packages`. See [Dependencies](https://elide.help/docs/toolchain/dependencies#maven-buckets).

```bash
elide classpath                 # main:compile
elide classpath runtime         # main:runtime
elide classpath test:runtime    # [<source-set>:]<usage>
```

`elide classpath` resolves the classpath and prints it on one line, entries separated by `:`. Usages: `compile`,
`runtime`, `processor`, `modules`, `toolchain`, `provided`; anything else exits `2`. Install also writes
`.dev/dependencies/m2/{compile,runtime,test,processors}.classpath`.

## Resources

On the JVM, resources are on the classpath for runs and tests and are copied into JARs.

```pkl
sources {
  ["main"] {
    resources {
      "assets/banner.txt"
      new {
        from = "config/services"
        into = "META-INF"
      }
    }
  }
}
```

A plain path is copied to the output root. `from` (a directory or file) is copied under `into`:
`config/services/app.Service` becomes `META-INF/services/app.Service`. `into` defaults to the root.

## Artifacts

```pkl
artifacts {
  ["app"] = new Jvm.Jar {}                 // every non-test source set
  ["lib"] = new Jvm.Jar { sources { "api" } }
}
```

Source and Javadoc JARs follow the same rule. A JAR's `resources` add to its sets'. See
[JAR Assembly](https://elide.help/docs/toolchain/jvm/jar).

## Languages

The file extension determines the language: `.java`, `.kt`, `.js`/`.mjs`/`.cjs`/`.jsx`,
`.ts`/`.mts`/`.cts`/`.tsx`, `.py`. A set with Java and Kotlin runs both compilers; a set with neither runs no JVM
compilation. Compiler settings for one set go in the language's block, keyed by the set's name: `jvm.java.sourceSets`
(see [Java Compiler](https://elide.help/docs/toolchain/jvm/javac#build-projects)).
Kotlin scripts (`.kts`) in a set are counted as Kotlin sources but produce no classes and are not type-checked.
