【问题标题】:nu.studer.credentials does not work from inside Spocknu.studer.credentials 在 Spock 内部不起作用
【发布时间】:2021-12-31 08:50:17
【问题描述】:

我正在构建一个 Gradle 插件,该插件需要用户名和密码才能访问外部资源;为了避免明文密码,我使用插件nu.studer.credentials。

为了测试我的插件,我使用 Spock;以下测试文件CredentialsFunctionTest.groovy 被剥离到仅相关部分,以显示问题:

package my.gradle.plugin

import org.gradle.testkit.runner.GradleRunner
import spock.lang.Specification
import spock.lang.TempDir

/**
 * A simple functional test for the credentials acquisition.
 */
class CredentialsFunctionalTest extends Specification {
    @TempDir
    private File projectDir

    private getBuildFile() {
        new File( projectDir, "build.gradle" )
    }

    private getSettingsFile() {
        new File( projectDir, "settings.gradle" )
    }

    def "can run task"() {
        given:
//---> Begin of settings file <------------------------------------------------
        settingsFile << """
plugins {
    id  'nu.studer.credentials' version '3.0'
}

"""
//---> End of settings file <--------------------------------------------------

//---> Begin of build file <---------------------------------------------------
        buildFile << """
plugins {
    id  'nu.studer.credentials'
}

String username = credentials.forKey( 'myUser' )
System.out.printf( 'Username: %s%n', username )
String password = credentials.forKey( 'myPassword' )
System.out.printf( 'Password: %s%n', password )

task doSomething {
} 
"""
//---> End of build file <-----------------------------------------------------

        when:
        def runner = GradleRunner.create()
        runner.forwardOutput()
        runner.withPluginClasspath()
        runner.withArguments("doSomething" )
        runner.withProjectDir( projectDir )
        def result = runner.build()

        then:
        result.output.contains( "Alive!" )
    }
}

“用户名”和“密码”的输出是 null——这样的测试预计会失败,因为在任何地方都没有字符串 "Alive!" 的输出。

当我将文件 settings.gradle 和 build.gradle(以下内容)放到一个空文件夹中,并使用 gradle doSomething 调用 gradle 时,我得到了预期的输出。

settings.gradle:

plugins {
    id  'nu.studer.credentials' version '3.0'
}

build.gradle:

plugins {
    id  'nu.studer.credentials'
}

String username = credentials.forKey( 'myUser' )
System.out.printf( 'Username: %s%n', username )
String password = credentials.forKey( 'myPassword' )
System.out.printf( 'Password: %s%n', password )

task doSomething {
} 

nu.studer.credentials 插件将值存储在$GRADLE_USER_HOME/gradle.encrypted.properties 中,因此一种假设是 Spock 使用的是不同的临时用户和/或主文件夹。

【问题讨论】:

  • Spock 在这方面没有做任何事情,我建议更仔细地查看GradleRunner。
  • @LeonardBrünings - 感谢您将我引向正确的方向。

标签: gradle groovy spock gradle-plugin


【解决方案1】:

根据Leonard Brünings 在他对我的问题的评论中给我的提示,我能够确定问题并制定解决方案。

正如 Leonard 所说,问题不在于 Spock 本身,而在于执行测试的 GradleRunner:这将使用与“常规”Gradle 执行不同的“Gradle 用户主目录”。

通过参数-g或者--gradle-user-home可以改变这个,但是不建议在测试Gradle插件的时候用这个指向默认位置(我们这里是用Gradle来测试Gradle的……)。

幸运的是,nu.studer.credentials 插件提供了一个配置参数,允许指定保存加密凭据的文件的位置:-PcredentialsLocation=&lt;path&gt;。

所以解决方案看起来像这样(我只从原始测试脚本中提取了when: 部分):

…
when:
def runner = GradleRunner.create()
runner.forwardOutput()
runner.withPluginClasspath()
runner.withArguments( "-PcredentialsLocation=%s/.gradle".formatted( System.getProperty( "user.home" ) ), "doSomething" )
runner.withProjectDir( projectDir )
def result = runner.build()
…

当然,测试仍然失败,但它现在显示 username 和 password 的正确值!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-11
    • 2020-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 1970-01-01
    相关资源
    最近更新 更多