Skip to content

Commit

Permalink
Merge pull request #4 from uzzu/testable-dotenv-properties
Browse files Browse the repository at this point in the history
Fix dotenv properties as testable
  • Loading branch information
uzzu authored Apr 17, 2020
2 parents d1f329c + fcac8c7 commit 39a356c
Show file tree
Hide file tree
Showing 11 changed files with 429 additions and 23 deletions.
1 change: 1 addition & 0 deletions .ruby-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
2.6
82 changes: 82 additions & 0 deletions Dangerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#
# GitHub Comment
#
github.dismiss_out_of_range_messages({
error: false,
warning: true,
message: true,
markdown: true
})

#
# File watching
#

[
".idea/codeStyleSettings.xml",
].each do |file|
warn("Are you sure want to modify #{file} ?") if git.modified_files.include?(file)
end

#
# Compiler warnings, errors
#

warning_pattern = /w: (?<path>(?:\/.+)+\.kt): \((?<line>\d+), (?<column>\d+)\): (?<description>.*)/
error_pattern = /e: (?<path>(?:\/.+)+\.kt): \((?<line>\d+), (?<column>\d+)\): (?<description>.*)/

target_files = (git.modified_files - git.deleted_files) + git.added_files
kotlin_compile_files = Dir.glob("**/build/kotlin/compile*Kotlin*.stdout")
unless kotlin_compile_files.empty?
compile_messages = File.read(kotlin_compile_files.first).strip
.split("\n")
.each { |s|
if match = s.match(warning_pattern)
file = Pathname(match[:path]).relative_path_from(Pathname(Dir.pwd)).to_s
if git.diff_for_file(file)
warn("#{match[:description]}", file: file, line: match[:line].to_i)
else
warn("#{file}: (#{match[:line]}, #{match[:column]}): #{match[:description]}")
end
end
if match = s.match(error_pattern)
file = Pathname(match[:path]).relative_path_from(Pathname(Dir.pwd)).to_s
if git.diff_for_file(file)
fail("#{match[:description]}", file: file, line: match[:line].to_i)
else
fail("#{file}: (#{match[:line]}, #{match[:column]}): #{match[:description]}")
end
end
}
end

#
# ktlint
#
checkstyle_format.base_path = Dir.pwd
Dir.glob('**/build/reports/ktlint/ktlint*Check.xml') do |file|
checkstyle_format.report file
end

#
# JUnit test results
#

tests = []
failures = []
errors = []
skipped = []

Dir.glob("**/build/test-results/**/TEST-*.xml") do |file|
junit.parse file
tests.concat(junit.tests)
failures.concat(junit.failures)
errors.concat(junit.errors)
skipped.concat(junit.skipped)
end
junit.tests = tests
junit.failures = failures
junit.errors = errors
junit.skipped = skipped

junit.report
8 changes: 8 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# frozen_string_literal: true

source "https://rubygems.org"
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }

gem 'danger'
gem 'danger-junit'
gem 'danger-checkstyle_format'
70 changes: 70 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
GEM
remote: https://rubygems.org/
specs:
addressable (2.7.0)
public_suffix (>= 2.0.2, < 5.0)
claide (1.0.3)
claide-plugins (0.9.2)
cork
nap
open4 (~> 1.3)
colored2 (3.1.2)
cork (0.3.0)
colored2 (~> 3.1)
danger (7.0.0)
claide (~> 1.0)
claide-plugins (>= 0.9.2)
colored2 (~> 3.1)
cork (~> 0.1)
faraday (>= 0.9.0, < 2.0)
faraday-http-cache (~> 2.0)
git (~> 1.6)
kramdown (~> 2.0)
kramdown-parser-gfm (~> 1.0)
no_proxy_fix
octokit (~> 4.7)
terminal-table (~> 1)
danger-checkstyle_format (0.1.1)
danger-plugin-api (~> 1.0)
ox (~> 2.0)
danger-junit (1.0.0)
danger (> 2.0)
ox (~> 2.0)
danger-plugin-api (1.0.0)
danger (> 2.0)
faraday (1.0.1)
multipart-post (>= 1.2, < 3)
faraday-http-cache (2.2.0)
faraday (>= 0.8)
git (1.6.0)
rchardet (~> 1.8)
kramdown (2.1.0)
kramdown-parser-gfm (1.1.0)
kramdown (~> 2.0)
multipart-post (2.1.1)
nap (1.1.0)
no_proxy_fix (0.1.2)
octokit (4.18.0)
faraday (>= 0.9)
sawyer (~> 0.8.0, >= 0.5.3)
open4 (1.3.4)
ox (2.13.2)
public_suffix (4.0.4)
rchardet (1.8.0)
sawyer (0.8.2)
addressable (>= 2.3.5)
faraday (> 0.8, < 2.0)
terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1)
unicode-display_width (1.7.0)

PLATFORMS
ruby

DEPENDENCIES
danger
danger-checkstyle_format
danger-junit

BUNDLED WITH
2.1.4
9 changes: 9 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,15 @@ allprojects {
}
}

ktlint {
verbose.set(true)
outputToConsole.set(true)
reporters {
reporter(org.jlleitschuh.gradle.ktlint.reporter.ReporterType.CHECKSTYLE)
}
ignoreFailures.set(true)
}

subprojects {
apply(plugin = "org.jlleitschuh.gradle.ktlint")
ktlint {
Expand Down
24 changes: 24 additions & 0 deletions plugin/src/main/kotlin/co/uzzu/dotenv/EnvProviders.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package co.uzzu.dotenv

/**
* Provides environment variable
*/
interface EnvProvider {
/**
* @return A environment variable for name.
*/
fun getenv(name: String): String?

/**
* @return All environment variables.
*/
fun getenv(): Map<String, String>
}

/**
* EnvProvider implementation using System#getenv
*/
class SystemEnvProvider : EnvProvider {
override fun getenv(name: String): String? = System.getenv(name)
override fun getenv(): Map<String, String> = System.getenv()
}
29 changes: 16 additions & 13 deletions plugin/src/main/kotlin/co/uzzu/dotenv/gradle/DotEnvPlugin.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package co.uzzu.dotenv.gradle

import co.uzzu.dotenv.DotEnvParser
import co.uzzu.dotenv.EnvProvider
import co.uzzu.dotenv.SystemEnvProvider
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.plugins.ExtensionAware
Expand All @@ -9,29 +11,30 @@ import java.nio.charset.Charset
@Suppress("unused")
class DotEnvPlugin : Plugin<Project> {
override fun apply(target: Project) {
val envTemplate = target.rootProject.envTemplate()
val envSource = target.rootProject.envSource()
val envMerged = envTemplate.keys
.union(envSource.keys)
.map { it to envSource[it] }
val envProvider = SystemEnvProvider()
val dotenvTemplate = target.rootProject.dotenvTemplate()
val dotenvSource = target.rootProject.dotenvSource()
val dotenvMerged = dotenvTemplate.keys
.union(dotenvSource.keys)
.map { it to dotenvSource[it] }
.toMap()

target.applyEnv(envMerged)
target.subprojects { it.applyEnv(envMerged) }
target.applyEnv(envProvider, dotenvMerged)
target.subprojects { it.applyEnv(envProvider, dotenvMerged) }
}

private fun Project.applyEnv(envProperties: Map<String, String?>) {
private fun Project.applyEnv(envProvider: EnvProvider, dotenvProperties: Map<String, String?>) {
val env =
extensions.create("env", DotEnvRoot::class.java, envProperties) as ExtensionAware
envProperties.forEach { (name, value) ->
env.extensions.create(name, DotEnvProperty::class.java, name, value)
extensions.create("env", DotEnvRoot::class.java, envProvider, dotenvProperties) as ExtensionAware
dotenvProperties.forEach { (name, value) ->
env.extensions.create(name, DotEnvProperty::class.java, envProvider, name, value)
}
}

private fun Project.envTemplate(filename: String = ".env.template") =
private fun Project.dotenvTemplate(filename: String = ".env.template"): Map<String, String> =
readText(filename).let(DotEnvParser::parse)

private fun Project.envSource(filename: String = ".env") =
private fun Project.dotenvSource(filename: String = ".env"): Map<String, String> =
readText(filename).let(DotEnvParser::parse)

private fun Project.readText(filename: String): String {
Expand Down
29 changes: 19 additions & 10 deletions plugin/src/main/kotlin/co/uzzu/dotenv/gradle/DotEnvProperties.kt
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
package co.uzzu.dotenv.gradle

open class DotEnvRoot(private val map: Map<String, String>) {
import co.uzzu.dotenv.EnvProvider

open class DotEnvRoot(
private val envProvider: EnvProvider,
private val map: Map<String, String>
) {
/**
* @return Indicates an environment variable with specified name is present
*/
fun isPresent(name: String): Boolean =
System.getenv()[name]?.let { true }
envProvider.getenv()[name]?.let { true }
?: map[name]?.let { true }
?: false

Expand All @@ -14,7 +19,7 @@ open class DotEnvRoot(private val map: Map<String, String>) {
* @throws IllegalStateException if it was not set
*/
fun fetch(name: String) =
System.getenv()[name]
envProvider.getenv()[name]
?: map[name]
?: throw IllegalStateException("""Environment variable $name was not set.""")

Expand All @@ -23,25 +28,29 @@ open class DotEnvRoot(private val map: Map<String, String>) {
* @throws IllegalStateException if it was not set
*/
fun fetch(name: String, defaultValue: String) =
System.getenv()[name]
envProvider.getenv()[name]
?: map[name]
?: defaultValue

/**
* @return An environment variable. If it was not set, returns specified default value
*/
fun fetchOrNull(name: String): String? =
System.getenv()[name]
envProvider.getenv()[name]
?: map[name]
}

open class DotEnvProperty(private val name: String, private val dotenvValue: String?) {
open class DotEnvProperty(
private val envProvider: EnvProvider,
private val name: String,
private val dotenvValue: String?
) {

/**
* @return Indicates an environment variable is present
*/
val isPresent: Boolean
get() = System.getenv()[name]?.let { true }
get() = envProvider.getenv()[name]?.let { true }
?: dotenvValue?.let { true }
?: false

Expand All @@ -51,22 +60,22 @@ open class DotEnvProperty(private val name: String, private val dotenvValue: Str
*/
val value: String
get() =
System.getenv()[name]
envProvider.getenv()[name]
?: dotenvValue
?: throw IllegalStateException("""Environment variable $name was not set.""")

/**
* @return An environment variable. If it was not set, returns specified default value
*/
fun orElse(defaultValue: String): String =
System.getenv()[name]
envProvider.getenv()[name]
?: dotenvValue
?: defaultValue

/**
* @return An environment variable. If it was not set, returns null.
*/
fun orNull(): String? =
System.getenv()[name]
envProvider.getenv()[name]
?: dotenvValue
}
8 changes: 8 additions & 0 deletions plugin/src/test/kotlin/co/uzzu/dotenv/InMemoryEnvProvider.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package co.uzzu.dotenv

class InMemoryEnvProvider(
private val map: Map<String, String>
) : EnvProvider {
override fun getenv(name: String): String? = map[name]
override fun getenv(): Map<String, String> = map
}
Loading

0 comments on commit 39a356c

Please sign in to comment.