Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 26 additions & 69 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,86 +1,43 @@
# Dotenv Gradle
# Dotenv Gradle with Resources

![main](https://github.com/uzzu/dotenv-gradle/workflows/main/badge.svg) [![ktlint](https://img.shields.io/badge/code%20style-%E2%9D%A4-FF4081.svg)](https://ktlint.github.io/)
[![Gradle Plugin Portal](https://img.shields.io/maven-metadata/v/https/plugins.gradle.org/m2/co/uzzu/dotenv/gradle/co.uzzu.dotenv.gradle.gradle.plugin/maven-metadata.xml.svg?colorB=007ec6&label=gradlePluginPortal)](https://plugins.gradle.org/plugin/co.uzzu.dotenv.gradle)
### Forked from [uzzu/dotenv-gradle](https://github.com/uzzu/dotenv-gradle)

**Provides dotenv (`.env`) and dotenv templates (`.env.template`) as variables in a Project extension.**
A Gradle plugin fork that extends the original Dotenv Gradle plugin by adding support for processing resource files during the `processResources` phase.

## How to use

### Setup
## Example Usage

Apply this plugin to the root project. [Read the Gradle Plugin Portal to setup the plugin.](https://plugins.gradle.org/plugin/co.uzzu.dotenv.gradle).
### 1. Example `.env` file

Note that this plugin is not registered to Maven Central.

You do not need to apply this plugin to subprojects; the values are applied automatically.

### Create `.env` in the root directory of your gradle project

For example:

```dosini
FOO=foo
BAR="bar"
BAZ='baz'

# You can comment out lines with a #
; You can comment out lines with a ;
```dotenv
FOO=hello
BAR=world
BAZ=123
```

Then, you will be able to use the environment variables in your gradle scripts:
### 2. Resource file **before** processing (`src/main/resources/config.yml`)

```Kotlin
println(env.FOO.isPresent) // => true
println(env.FOO.value) // => foo
println(env.BAR.orNull()) // => bar
println(env.BAZ.orElse("default baz")) // => baz
```yaml
message: "${FOO}, ${BAR}! Your code is ${BAZ}"
```

**Don't commit the `.env` file.** Ideally, add it to your `.gitignore` file.

### API

- `(Boolean) env.isPresent(name: String)`: Indicates that an environment variable with specified name is present.

- `(String) env.fetch(name: String)`: Returns the environment variable of the given name.

- `(String) env.fetch(name: String, defaultValue: String)`: Returns an environment variable, or specified default value if environment variable was not set.

- `(String?) env.fetchOrNull(name: String)`: Returns an environment variable, or `null` if the environment variable was not set.

- `(Map<String, String) env.allVariables()`: Returns all environment variables.

- `(Map<String, String?) env.allVariablesOrNull()`: Returns all environment variables, and includes `null` values for unset variables.
### 3. Resource file **after** processing (`build/resources/main/config.yml`)

### Templates

If a `.env.template` file exists, this plugin populates environment variables names from the template, too. This means you can use the template to define the environment variables that are required for your project, and override them in the `.env` file. Values within the `.env.template` file are *not* populated when read, all values will be `null`.

[See the `change_template_file` example](/examples/change_template_file) for more details.

### Changing the name of the `.env` file

You can also use a different name for the `.env` file. [See this example](/examples/change_file) on how to do this.

### Hierarchical dotenv definitions

This project supports subproject-only variables and extensions.

[See this example](/examples/hierarchical_definitions) for more details.

### Other Features/Functions

Note that all APIs of this `env` extension consider the `.env` file.

If the same variable name value is defined in both the `.env` file and system environment variables, the system environment variable takes precedence.
```yaml
message: "hello, world! Your code is 123"
```
---
## Config

[See more examples](/examples).
You can adjust path to your env file and which files are processed by setting a pattern in your `gradle.properties`:

## Restrictions
```properties
dotenv.filename=.env
dotenv.resources.pattern=**/*
```

This plugin does not support specifying properties with the `-P` option of CLI arguments, and there are no plans to support it in the future. See [#67](https://github.com/uzzu/dotenv-gradle/issues/67)

## License
---

[Apache License 2.0](/LICENSE.txt)
For more information, configuration options, and advanced usage, please refer to the original project:
[uzzu/dotenv-gradle](https://github.com/uzzu/dotenv-gradle)
15 changes: 7 additions & 8 deletions plugin/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ tasks {
// region publishing

object Artifact {
const val GroupId = "co.uzzu.dotenv"
const val GroupId = "io.github.s41u.dotenv"
const val ArtifactId = "gradle"
const val Version = "4.0.0"
const val Version = "4.0.0-with-resources"
}

group = Artifact.GroupId
Expand All @@ -62,17 +62,16 @@ publishing {
}
}

@Suppress("UnstableApiUsage")
gradlePlugin {
website = "https://github.com/uzzu/dotenv-gradle"
vcsUrl = "https://github.com/uzzu/dotenv-gradle.git"
website = "https://github.com/s41u/dotenv-gradle"
vcsUrl = "https://github.com/s41u/dotenv-gradle.git"

plugins {
create("dotenv") {
id = "co.uzzu.dotenv.gradle"
id = "${Artifact.GroupId}.${Artifact.ArtifactId}"
implementationClass = "co.uzzu.dotenv.gradle.DotEnvPlugin"
displayName = "Gradle dotenv plugin"
description = "A converting plugin from dotenv(.env.template, .env) files to Gradle project extension"
displayName = "Dotenv Gradle Plugin with Resources"
description = "Forked version with resources processing feature"
tags = listOf("dotenv")
}
}
Expand Down
26 changes: 26 additions & 0 deletions plugin/src/main/kotlin/co/uzzu/dotenv/gradle/Configuration.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,39 +7,47 @@ import java.util.Properties
internal interface Configuration {
val filename: String
val templateFilename: String
val resourcesPattern: String
}

internal interface RootConfiguration : Configuration {
val ignoreParentFilename: Boolean
val ignoreParentTemplateFilename: Boolean
val ignoreParentResourcesPattern: Boolean
}

@Suppress("ConstPropertyName")
object ConfigurationKey {
const val Filename: String = RootConfigurationKey.Filename
const val TemplateFilename: String = RootConfigurationKey.TemplateFilename
const val ResourcesPattern: String = RootConfigurationKey.ResourcesPattern
}

@Suppress("ConstPropertyName")
object RootConfigurationKey {
const val IgnoreParentFilename: String = "dotenv.filename.ignore.parent"
const val IgnoreParentTemplateFilename: String = "dotenv.template.filename.ignore.parent"
const val IgnoreParentResourcesPattern: String = "dotenv.resources.pattern.ignore.parent"

const val Filename: String = "dotenv.filename"
const val TemplateFilename: String = "dotenv.template.filename"
const val ResourcesPattern: String = "dotenv.resources.pattern"
}

internal object DefaultConfiguration : Configuration {
override val filename: String = DefaultRootConfiguration.filename
override val templateFilename: String = DefaultRootConfiguration.templateFilename
override val resourcesPattern: String = DefaultRootConfiguration.resourcesPattern
}

internal object DefaultRootConfiguration : RootConfiguration {
override val ignoreParentFilename: Boolean = true
override val ignoreParentTemplateFilename: Boolean = true
override val ignoreParentResourcesPattern: Boolean = true

override val filename: String = ".env"
override val templateFilename: String = ".env.template"
override val resourcesPattern: String = "**/*"
}

internal class ConfigurationResolver(
Expand Down Expand Up @@ -69,6 +77,13 @@ internal class ConfigurationResolver(
DefaultRootConfiguration.templateFilename,
rootConfiguration.ignoreParentTemplateFilename,
),
resourcesPattern = resolveStringFor(
project,
gradlePropertiesFromFile,
ConfigurationKey.ResourcesPattern,
DefaultRootConfiguration.resourcesPattern,
rootConfiguration.ignoreParentResourcesPattern,
),
)
}
}
Expand Down Expand Up @@ -96,6 +111,10 @@ internal class ConfigurationResolver(
RootConfigurationKey.IgnoreParentTemplateFilename,
DefaultRootConfiguration.ignoreParentTemplateFilename,
),
ignoreParentResourcesPattern = it.boolProperty(
RootConfigurationKey.IgnoreParentResourcesPattern,
DefaultRootConfiguration.ignoreParentResourcesPattern,
),
filename = it.stringProperty(
RootConfigurationKey.Filename,
DefaultRootConfiguration.filename,
Expand All @@ -104,6 +123,10 @@ internal class ConfigurationResolver(
RootConfigurationKey.TemplateFilename,
DefaultRootConfiguration.templateFilename,
),
resourcesPattern = it.stringProperty(
RootConfigurationKey.ResourcesPattern,
DefaultRootConfiguration.resourcesPattern,
),
)
}

Expand Down Expand Up @@ -155,11 +178,14 @@ internal class ConfigurationResolver(
private data class ConfigurationImpl(
override val filename: String,
override val templateFilename: String,
override val resourcesPattern: String,
) : Configuration

private data class RootConfigurationImpl(
override val ignoreParentFilename: Boolean,
override val ignoreParentTemplateFilename: Boolean,
override val ignoreParentResourcesPattern: Boolean,
override val filename: String,
override val templateFilename: String,
override val resourcesPattern: String,
) : RootConfiguration
17 changes: 17 additions & 0 deletions plugin/src/main/kotlin/co/uzzu/dotenv/gradle/DotEnvPlugin.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import co.uzzu.dotenv.EnvProvider
import co.uzzu.dotenv.SystemEnvProvider
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.file.DuplicatesStrategy
import org.gradle.api.plugins.ExtensionAware
import org.gradle.api.plugins.JavaPlugin
import org.gradle.language.jvm.tasks.ProcessResources

@Suppress("unused")
class DotEnvPlugin : Plugin<Project> {
Expand All @@ -29,5 +32,19 @@ class DotEnvPlugin : Plugin<Project> {
dotenvProperties.forEach { (name, value) ->
env.extensions.create(name, DotEnvProperty::class.java, envProvider, name, value)
}

applyEnvToResources(dotenvProperties)
}

private fun Project.applyEnvToResources(dotenvProperties: Map<String, String?>) {
plugins.withType(JavaPlugin::class.java) {
val pr = project.tasks.findByName("processResources")
if (pr is ProcessResources) {
pr.duplicatesStrategy = DuplicatesStrategy.INCLUDE
val configuration = ConfigurationResolver(this).resolve()
pr.inputs.properties(dotenvProperties)
pr.filesMatching(configuration.resourcesPattern) { details -> details.expand(dotenvProperties) }
}
}
}
}
Loading