Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem with use cases of executing subproject's task with dotenv option by using CLI arguments #67

Open
uzzu opened this issue Nov 27, 2023 · 6 comments

Comments

@uzzu
Copy link
Owner

uzzu commented Nov 27, 2023

Forked from #39 (comment)

refs: #39 (comment)

I'm still working on how to make the use cases of executing subproject's task with dotenv option by using CLI arguments, but I think the following tests would be good to pass.

Now failing test case
    @Test
    fun changeFileWithIgnoringParentByUsingCliOptionWithCallSubProject() {
        RootProject(projectDir) {
            settingsGradle(
                """
                include("sub")
                """.trimIndent()
            )
            buildGradle(
                """
                plugins {
                    id("base")
                    id("co.uzzu.dotenv.gradle")
                }
                println("[root] FOO: ${'$'}{env.FOO.value}")
                """.trimIndent()
            )
            file(
                ".env.template",
                """
                FOO=
                """.trimIndent()
            )
            file(
                ".env",
                """
                FOO=100
                """.trimIndent()
            )
            directory("sub")
            file(
                "sub/build.gradle",
                """
                plugins {
                    id("base")
                }
                println("[sub] BAR: ${'$'}{env.BAR.value}")
                """.trimIndent()
            )
            file(
                "sub/.env.template",
                """
                BAR=
                """.trimIndent()
            )
            file(
                "sub/.env",
                """
                BAR=200
                """.trimIndent()
            )
            file(
                "sub/.env.local",
                """
                BAR=2000
                """.trimIndent()
            )
        }

        val result = GradleRunner.create()
            .withPluginClasspath()
            .withProjectDir(projectDir)
            .withArguments(":sub:clean", "-Pdotenv.filename=.env.local")
            .build()

        assertAll {
            assertThat(result.output).contains("[root] FOO: 100")
            assertThat(result.output).contains("[sub] BAR: 2000")
        }
    }

execution log

FAILURE: Build failed with an exception.

* Where:
Build file '/private/var/folders/xxx/build.gradle.kts' line: 1

* What went wrong:
An exception occurred applying plugin request [id: 'co.uzzu.dotenv.gradle']
> Failed to apply plugin 'co.uzzu.dotenv.gradle'.
   > Could not read the dotenv file specified in the gradle.properties. dotenv.filename: .env.local, path: /private/var/folders/xxx/.env.local

workaround: Use gradle.properties

@uzzu
Copy link
Owner Author

uzzu commented Dec 2, 2023

(memo) Perhaps the plugin can be resolved all command line arguments by using StartParameter

logs

println(target.gradle.startParameter.toString())

StartParameter{taskRequests=[DefaultTaskExecutionRequest{args=[:sub:clean],projectPath='null',rootDir='null'}], excludedTaskNames=[], currentDir=<<omitted>>, projectProperties={dotenv.filename=.env.local}, systemPropertiesArgs={}, gradleUserHomeDir=<<omitted>>/dotenv-gradle/plugin/build/tmp/test/work/.gradle-test-kit, gradleHome=<<omitted>>, logLevel=LIFECYCLE, showStacktrace=INTERNAL_EXCEPTIONS, buildFile=null, initScripts=[], dryRun=false, rerunTasks=false, offline=false, refreshDependencies=false, parallelProjectExecution=false, configureOnDemand=false, maxWorkerCount=8, buildCacheEnabled=false, writeDependencyLocks=false, verificationMode=STRICT, refreshKeys=false}

@uzzu
Copy link
Owner Author

uzzu commented Dec 9, 2023

I have created a prototype, but it has a lot of problem to resolve this plugins cofigurations.

When executing Gradle from the CLI, it's possible to specify tasks for multiple subprojects, but you can't specify -P options for each task individually. This means that you cannot specify different .env file names for each subproject you execute.

Determining the expected behavior when CLI arguments are provided is extremely challenging.
Seriously, in this plugin, deciding not to support CLI arguments (like -Pdotenv.xyz=aaa) is crucial for sustainable maintenance.

I could consider supporting local.properties, but there hasn't been a demand for that so far.

@uzzu
Copy link
Owner Author

uzzu commented Dec 9, 2023

I think the root cause is the use of Gradle Properties for configuration. However, it's currently unavoidable, as it provides an understandable and minimally necessary functionality for many users. The use of CLI options was unexpected.

Apart from this, until I decide to stop using Gradle Properties for configuring this plugin by facing other issues, CLI options will not be supported.

@uzzu uzzu closed this as completed Dec 9, 2023
@uzzu uzzu added the wontfix This will not be worked on label Dec 9, 2023
@slhck
Copy link
Contributor

slhck commented Feb 20, 2024

I have followed this issue and I am a bit unsure how to realize the following:

I want to develop a library that will be built in different variants. These variants all use different .env files (e.g., different server configurations or default API keys).

It used to be possible to simply set ENV_FILE=.env.variant1 ./gradlew …, with an older version of this plugin.

How else can one set a different env file to use? Editing gradle.properties is not a solution since that file is also committed to the repository; I cannot change it every time I want to build a different variant.

@slhck
Copy link
Contributor

slhck commented Feb 20, 2024

I have a workaround that is not very clean, but here it goes.

In my build.gradle for the library, I define some defaults:

def envLookup() {
    def defaults = [
        'API_ENDPOINT': 'http://10.0.2.2:3001/api/v1',
        'API_KEY'     : 'test',
        'VARIANT'     : 'default',
        'SERVICE'     : 'default'
    ]

    def envLookup = [:]
    defaults.each { key, value ->
        envLookup[key] = env.fetch(key, value)
    }

    return envLookup
}

I can use this, e.g., like:

buildConfigField "String", "API_ENDPOINT", "\"${envLookup()['API_ENDPOINT']}\""

For actually building the library, I have a Bash script:

#!/bin/bash

# trap exit by restoring the original gradle.properties from Git
function cleanup {
  echo "Restoring gradle.properties"
  git checkout gradle.properties
}

trap cleanup EXIT

# set the envfile to use for building
envFile=$1

gradleOpts="dotenv.filename=$envFile"

# temporarily write the filename setting into gradle.properties (see: https://github.com/uzzu/dotenv-gradle/issues/39)
echo >> gradle.properties
echo "$gradleOpts" >> gradle.properties

# build
./gradlew clean
./gradlew example:assembleRelease

# any other build steps as necessary

This will overwrite the gradle.properties on the fly and restore it to the default after completion.

@uzzu
Copy link
Owner Author

uzzu commented Apr 1, 2024

I'll reopen the issue aside from how to solve it.

@uzzu uzzu reopened this Apr 1, 2024
@uzzu uzzu removed the wontfix This will not be worked on label Apr 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants