2016년 5월 24일 화요일

Dependency Management [Working with dependencies]



아래 예제에서 우리는 dependencies setup을 볼 수 있다.

configurations {
    sealife
    alllife
}

dependencies {
    sealife "sea.mammals:orca:1.0", "sea.fish:shark:1.0", "sea.fish:tuna:1.0"
    alllife configurations.sealife
    alllife "air.birds:albatross:1.0"
}

dependency들은 아래와 같이 transitive dependency를 가지고 있다.

shark-1.0 -> seal-2.0, tuna-1.0

orca-1.0 -> seal-1.0

tuna-1.0 -> herring-1.0

당신은 선언된 dependency 혹은 그것들의 subset에 접근하기 위해 아래와 같이 설정을 사용할 수 있다.

ex) Accessing declared dependencies

build.gradle

task dependencies << {
    configurations.alllife.dependencies.each { dep -> println dep.name }
    println()
    configurations.alllife.allDependencies.each { dep -> println dep.name }
    println()
    configurations.alllife.allDependencies.findAll { dep -> dep.name != 'orca' }
        .each { dep -> println dep.name }
}

gradle -q dependencies 의 실행 결과

> gradle -q dependencies
albatross

albatross
orca
shark
tuna

albatross
shark
tuna

dependencies task는 오직 configuration에 직접 명시된 dependency만을 return한다.
allDependencies task는 확장된 configuration으로부터 dependencies를 포함한다.

configuration dependencies의 library files를 얻기 위해 당신은 아래와 같이 할 수 있다.

ex) Configuration.files

build.gradle

task allFiles << {
    configurations.sealife.files.each { file ->
        println file.name
    }
}

gradle -q allFiles 의 실행 결과

> gradle -q allFiles
orca-1.0.jar
shark-1.0.jar
tuna-1.0.jar
herring-1.0.jar
seal-2.0.jar

가끔씩 당신은 configuration dependencies 의 subset의 library file들을 원할 수도 있다.

ex) Configuration.files with spec

build.gradle

task files << {
    configurations.sealife.files { dep -> dep.name == 'orca' }.each { file ->
        println file.name
    }
}

gradle -q files 의 실행 결과

> gradle -q files
orca-1.0.jar
seal-2.0.jar

Configuration.files method는 항상 전체 configuration의 모든 artifact를 검색한다.
그리고 명시된 dependencies에 의해 검색된 파일들을 필터링한다.
예에서 보았듯이, transitive dependencies는 포함된다.

당신은 또한 configuration을 복사할 수도 있다.
당신은 선택적으로 원본 configuration으로부터 복사되어야 할 dependencies의 subset을 명시할 수 있다.
복사할 수 있는 method는 두가지가 있다.
copy method는 configuration에 명시적으로 속해있는 dependencies 만 복사한다.
copyRecursive method는 확장된 configuration에 속해있는 모든 dependencies를 복사한다.

ex) Configuration.copy

build.gradle

task copy << {
    configurations.alllife.copyRecursive { dep -> dep.name != 'orca' }
        .allDependencies.each { dep -> println dep.name }
    println()
    configurations.alllife.copy().allDependencies
        .each { dep -> println dep.name }
}

gradle -q copy 의 실행 결과

> gradle -q copy
albatross
shark
tuna

albatross

명심해야 할 사항은 복사된 configuration의 return된 file들은 항상 original configuration의 dependency subset과 같지 않을 수 있다는 것이다.

ex) Configuration.copy vs. Configuration.files

build.gradle

task copyVsFiles << {
    configurations.sealife.copyRecursive { dep -> dep.name == 'orca' }
        .each { file -> println file.name }
    println()
    configurations.sealife.files { dep -> dep.name == 'orca' }
        .each { file -> println file.name }
}

gradle -q copyVsFiles 의 실행 결과

> gradle -q copyVsFiles
orca-1.0.jar
seal-1.0.jar

orca-1.0.jar
seal-2.0.jar

위의 예제에서, shark가 seal-2.0 의 dependency를 가지고 있는 것에 반하여 orca 는 seal-1.0 의 dependency를 가지고 있다.
original configuration은 어떤 것이 새로운 seal-2.0 version으로 풀어지는지 version 충돌을 가지고 있다.
file method는 orca의 transitive dependency로써 seal-2.0을 되돌려준다.
복사된 configuration은 오직 orca만 가지고 있고 거기엔 version 충돌이 없으며 seal-1.0이 리턴된다.

만약 configuration이 불변이라면, 이 것의 상태를 바꾸는 것 혹은 어떤 것의 상태를 바꾸는 것은 예외를 발생시킬 것이다.
당신은 항상 resolved configuration을 복사할 수 있다.
복사된 configuration은 unresolved 상태에 있고, 새롭게 resolve될 수 있다.

원본 출처 : https://docs.gradle.org/current/userguide/dependency_management.html

댓글 없음 :

댓글 쓰기