2014-06-04 1 views
0

범위가 sbt에서 중요합니다. 그리고 나는 그것으로 완전히 괜찮습니다. 그러나 계층 적 구조 설정을 가능하게하는 위임 규칙도 있습니다. 좀 더 구체적인 규칙에 추가 설정을 적용하는 데 사용하고 싶습니다. 내가 test:targetExampleList(extended, base, testing)하지 List(extended, base) 될 것으로 예상테스트 범위 설정이 올바른 값을 보유하지 않는 이유는 무엇입니까?

> show compile:sourceExample 
[info] List(base) 
> show test:sourceExample 
[info] List(base, testing) 
> show compile:targetExample 
[info] List(extended, base) 
> show test:targetExample 
[info] List(extended, base) 

:

import sbt._ 
import Keys._ 

object TestBuild extends Build { 
    val sourceExample = settingKey[Seq[String]]("example source for setting dependency") 
    val targetExample = settingKey[Seq[String]]("example of a dependent setting") 

    override lazy val settings = super.settings ++ Seq (
    sourceExample := Seq("base"), 
    targetExample := "extended" +: sourceExample.value, 
    sourceExample in Test += "testing" 
) 
} 

예는 나에게 예기치 않은 출력을 제공합니다. 결과를 얻은 후에는 왜 정확히 표시된 것처럼 작동하는지 즉시 알 수 있습니다. test:targetExample*:targetExample에서 계산 된 값을 중첩 범위에서 계산하는 규칙이 아니라 위임합니다.

이 동작으로 인해 내 자신의 플러그인을 작성하는 데 두 가지 어려움이 있습니다. 플러그인 개발자로서 모든 범위에서 동일한 규칙을 정의하는 추가 작업이 있습니다. 그리고 내부 작업의 범위 정의를 암기해야 사용자로 올바르게 사용할 수 있습니다.

이 불편을 어떻게 극복 할 수 있습니까? 대신 대신 이름이이라는 의미로 설정을 소개하고 싶습니다. 어떤 트릭이 그 일을 할 수 있습니까?

P. libraryDependencies in Test% test을 사용하면 훨씬 간결 해 보입니다.


sbt가 설명서에서 설명한대로 값을 파생한다는 것을 완전히 이해한다는 것을 분명히해야합니다. 제작자가 의도 한대로 작동합니다.

하지만 규칙을 준수해야하는 이유는 무엇입니까? 나는 그들을 반 직관적이라고 완전히 본다. Sbt는 상속이 정의되는 방식과 달리 실제로 작동하는 상속 의미를 도입합니다. 당신이

trait A { lazy val x : Int = 5 } 
trait B extends A { lazy val y : Int = x * 2} 
trait C extends A { override lazy val x : Int = 3 } 

를 쓸 때 당신은 실제로 10 제대로 상속의이 종류를 사용할 수 있지만 상속을 구현하기위한보다 전통적인 방법을 찾을 수 욕망으로 잎 (new B with C).y이 될 것이라는 점을 알고 (6),하지 (10)가 될 것으로 예상된다. 사전 name->value을 기반으로 자신의 구현을 작성할 수도 있습니다. 그리고 프로그래밍의 10 번째 규칙에 따라 더 진행할 수 있습니다.

그래서 공통적 인 의미에 따라 상속 의미를 가져올 수있는 해킹을 찾고 있습니다. 시작 지점으로 나는 모든 설정을 검사하고 부모로부터 어린이에게 명시 적으로 푸시하도록 command을 작성할 것을 제안 할 수 있습니다. 그리고 sbt가 실행될 때마다 자동으로이 명령을 호출하십시오.

하지만 나에게 너무 더러운 것처럼 보입니다. 비슷한 의미를 달성하는 데 더 우아한 방법이 있다면 나는 골동품입니다.그것은 당신의 소원에 대해 명시 적으로 in Test를 사용 Test 범위 sourceExample 값을 사용해야

targetExample := "extended" +: sourceExample.value 

:

답변

0

"잘못된" 값에 대한 이유는 targetExample이 같이 Compile 범위에 sourceExample에 달려 있다는 것입니다

targetExample := "extended" +: (sourceExample in Test).value 

inspect을 사용하면 종속성을 알 수 있습니다. 체인.

나는이 간단한 빌드 정의에 대해 build.sbt 파일을 사용하는 것이 좋습니다.

0

Plugins Best Practices - Playing nice with configurations에 설명 된대로 다른 설정으로 기본 설정을 다시 사용할 수 있습니다. 나는 이것이 당신에게 당신이 찾고있는 것과 비슷한 의미를 부여해야한다고 믿습니다.

기본 설정을 정의하고 다른 구성으로 재사용 할 수 있습니다.

import sbt._ 
import Keys._ 

object TestBuild extends Build { 

    val sourceExample = settingKey[Seq[String]]("example source for setting dependency") 
    val targetExample = settingKey[Seq[String]]("example of a dependent setting") 

    override lazy val settings = super.settings ++ 
    inConfig(Compile)(basePluginSettings) ++ 
    inConfig(Test)(basePluginSettings ++ Seq(
     sourceExample += "testing" // we are already "in Test" here 
    )) 

    lazy val basePluginSettings: Seq[Setting[_]] = Seq (
    sourceExample := Seq("base"), 
    targetExample := "extended" +: sourceExample.value 
) 

} 

ps. 플러그인을 작성하는 것에 대해 이야기하고 있으므로, 이전 메커니즘이 이제 deprecated이므로, AutoPlugin 인 sbt 플러그인을 작성하는 새로운 방법을 살펴볼 수도 있습니다.

+0

더 많은 설정이 있다면 어떻게해야합니까? 'libraryDependencies'를 예제로 사용할 수 있습니다. 태스크가 너무 복잡하고 사용자 정의 유추 메카니즘을 실현할 수있는 이유로 태스크마다 정의되지 않습니다. '% test'는 의존성 정의의 일부입니다. – ayvango

+0

@ayvango 올바르게 가져올 지 확신이 없지만 다른 '지연 값'처럼 범위를 지정하지 않은 설정을 추가하고'inConfig' 메소드를 통해 범위를 지정하지 않고'settings'에 추가 할 수 있습니다. 그러나 당신이'basePluginSettings'에서 정의한다면, 나는 또한 그것이 작동해야한다고 생각합니다, 당신은 단지 설정에서 그것을 오버라이드하지 않습니다. – lpiepiora

관련 문제