Skip to content

Commit

Permalink
simplify loader and make all configuration optional
Browse files Browse the repository at this point in the history
  • Loading branch information
Carmine DiMascio committed Dec 3, 2017
1 parent 236ceb8 commit 878e02e
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 45 deletions.
16 changes: 12 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ Dotenv is a zero-dependency module that loads environment variables from a `.env
<dependency>
<groupId>io.github.cdimascio</groupId>
<artifactId>java-dotenv</artifactId>
<version>1.0.3</version>
<version>1.1.0</version>
</dependency>
```

### Gradle

```
compile 'io.github.cdimascio:java-dotenv:1.0.3'
compile 'io.github.cdimascio:java-dotenv:1.1.0'
```


Expand All @@ -39,10 +39,18 @@ MY_EVV_VAR2=My second env var
#### Configure java-dotenv
Configure `java-dotenv` once in your application.

Simple

```kotlin
val dotenv = Dotenv.configure().build()
```

Advanced

```kotlin
val dotenv = Dotenv
.configure()
.directory("./") // set to the current directory
.directory("./some/path") // set to the current directory - defaults to current dir
.ignoreIfMalformed() // do not throw an error if .env is malformed
.ignoreIfMissing() // do not throw an error if .env is missing
.build()
Expand Down Expand Up @@ -77,7 +85,7 @@ dotenv.get("MY_ENV_VAR1");

## Configuration options

### *required* `directory(path: String)`
### *optional* `directory(path: String)`
`path` specifies the directory containing `.env`. Dotenv first searches for `.env` using the given path on the filesystem. If not found it searches the given path on the classpath.

### *optional* `ignoreIfMalformed()`
Expand Down
4 changes: 2 additions & 2 deletions java-dotenv-1.0.3.pom → java-dotenv-1.1.0.pom
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

<groupId>io.github.cdimascio</groupId>
<artifactId>java-dotenv</artifactId>
<version>1.0.3</version>
<version>1.1.0</version>


<licenses>
Expand Down Expand Up @@ -52,7 +52,7 @@


<properties>
<kotlin.version>1.1.61</kotlin.version>
<kotlin.version>1.2.0</kotlin.version>
<main.class>io.cdimascio.DotenvKt</main.class>
<junit.version>4.12</junit.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
Expand Down
10 changes: 5 additions & 5 deletions java-dotenv.iml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
<configuration version="3" platform="JVM 1.6" useProjectSettings="false">
<compilerSettings />
<compilerArguments>
<option name="languageVersion" value="1.1" />
<option name="apiVersion" value="1.1" />
<option name="languageVersion" value="1.2" />
<option name="apiVersion" value="1.2" />
<option name="pluginOptions">
<array />
</option>
Expand All @@ -30,11 +30,11 @@
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="KotlinJavaRuntime" level="project" />
<orderEntry type="library" name="Maven: org.jetbrains.kotlin:kotlin-stdlib:1.1.61" level="project" />
<orderEntry type="library" name="Maven: org.jetbrains.kotlin:kotlin-stdlib:1.2.0" level="project" />
<orderEntry type="library" name="Maven: org.jetbrains:annotations:13.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.jetbrains.kotlin:kotlin-test-junit:1.1.61" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.jetbrains.kotlin:kotlin-test:1.1.61" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.jetbrains.kotlin:kotlin-test-junit:1.2.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.jetbrains.kotlin:kotlin-test:1.2.0" level="project" />
</component>
</module>
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

<groupId>io.github.cdimascio</groupId>
<artifactId>java-dotenv</artifactId>
<version>1.0.3</version>
<version>1.1.0</version>


<licenses>
Expand Down Expand Up @@ -52,7 +52,7 @@


<properties>
<kotlin.version>1.1.61</kotlin.version>
<kotlin.version>1.2.0</kotlin.version>
<main.class>io.cdimascio.DotenvKt</main.class>
<junit.version>4.12</junit.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
Expand Down
75 changes: 43 additions & 32 deletions src/main/kotlin/io/github/cdimascio/Dotenv.kt
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package io.github.cdimascio

import java.io.File
import java.io.IOException
import java.io.InputStream
import java.net.URI
import java.nio.file.Files
import java.nio.file.LinkOption
import java.nio.file.Path
import java.nio.file.Paths
import java.util.*
import java.util.stream.Collectors
import java.util.stream.Stream


interface Dotenv {
Expand All @@ -24,7 +25,7 @@ class DotEnvException : Exception {

class DotenvBuilder internal constructor() {
private var filename = ".env"
private var directoryPath = System.getProperty("user.home")
private var directoryPath = "" //System.getProperty("user.home")
private var throwIfMissing = true
private var throwIfMalformed = true

Expand Down Expand Up @@ -69,18 +70,12 @@ private class DotEnvReader(
fun read() = parse()

private fun parse(): List<Pair<String, String>> {
val path = try {
PathResolver.resolve(directory, filename)
val lines = try {
DotenvParser.parse(directory, filename)
} catch (e: DotEnvException) {
if (throwIfMissing) throw e
else return listOf()
}

val lines =
try { Files.lines(path) }
catch (e: Exception) {
throw DotEnvException(e)
}.collect(Collectors.toList())
}.collect(Collectors.toList())

return lines
.map { it.trim() }
Expand All @@ -99,25 +94,41 @@ private class DotEnvReader(
}
}

private object PathResolver {
fun resolve(directory: String, filename: String): Path {
val isFullPath = directory.endsWith(filename)
val useFileScheme = directory.toLowerCase().startsWith("file:")
val fullPath = if (isFullPath) directory else "$directory${File.separator}$filename"
var path = if (useFileScheme) Paths.get(URI.create(fullPath)) else Paths.get(fullPath)
path = path.normalize()

if (!Files.exists(path, *arrayOfNulls<LinkOption>(0))) {
val normalizedPath = path.toFile().path
path = javaClass.classLoader.getResource(normalizedPath)?.let {
Paths.get(it.toURI())
} ?: ClassLoader.getSystemResource(normalizedPath)?.let {
Paths.get(it.toURI())
}
private object DotenvParser {
fun parse(directory: String, filename: String): Stream<String> {
var dir = directory.replace("""\\""".toRegex(), "/")
dir = if (dir.endsWith("/")) dir.substring(0, dir.length - 1) else dir
dir = if (dir.endsWith(".env")) dir.substring(0, dir.length - 4) else dir
val location = "$dir/$filename"
val path = if (location.toLowerCase().startsWith("file:")) {
Paths.get(URI.create(location))
} else {
Paths.get(location)
}
if (path === null) {
throw DotEnvException("$fullPath not found")
}
return path
return if (Files.exists(path)) Files.lines(path)
else ClasspathHelper.loadFileFromClasspath(location)
}
}

private object ClasspathHelper {
fun loadFileFromClasspath(location: String): Stream<String> {
val loader = ClasspathHelper::class.java
val inputStream: InputStream? =
loader.getResourceAsStream(location)
?: loader.getResourceAsStream(location)
?: ClassLoader.getSystemResourceAsStream(location)
if (inputStream != null) {
try {
val scanner = Scanner(inputStream, "utf-8")
val lines = mutableListOf<String>()
while (scanner.hasNext()) {
lines.add(scanner.nextLine())
}
return lines.stream()
} catch (e: IOException) {
throw DotEnvException("Could not read $location from the classpath")
}
}
throw DotEnvException("Could not find $location on the classpath")
}
}
11 changes: 11 additions & 0 deletions src/test/kotlin/tests.kt
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,17 @@ class DotEnvTest() {
assertEquals(expectedHome, actualHome)
}

@test fun resourceCurrent() {
val dotenv = Dotenv.configure()
.ignoreIfMalformed()
.build()
assertEquals("my test ev 1", dotenv["MY_TEST_EV1"])

val expectedHome = System.getProperty("user.home")
val actualHome = dotenv.get("HOME")
assertEquals(expectedHome, actualHome)
}

@test(expected = DotEnvException::class) fun dotenvMissing() {
Dotenv.configure()
.directory("/missing/.env")
Expand Down

0 comments on commit 878e02e

Please sign in to comment.