문제

에서 언급한 바와 같이 문서, Gradle은 방향성 비순환 그래프(DAG)를 사용하여 종속성 그래프를 작성합니다.제가 이해한 바로는 평가와 실행을 위한 별도의 주기를 갖는 것이 빌드 도구의 주요 기능입니다.예를 들어그만큼 Gradle 문서 이는 다른 방법으로는 불가능했던 일부 기능을 가능하게 한다고 말합니다.

저는 이 기능의 강력한 기능을 보여주는 실제 사례에 관심이 있습니다.종속성 그래프가 중요한 사용 사례에는 어떤 것이 있나요?저는 특히 Gradle이나 이와 유사한 도구를 사용하는 현장의 개인적인 이야기에 관심이 있습니다.

'정확한' 답변을 평가하기 어려울 것이기 때문에 처음부터 이 '커뮤니티 위키'를 만들고 있습니다.

도움이 되었습니까?

해결책

이 도발적인 질문은 마침내 Gradle을 살펴보게 된 동기를 제공했습니다.아직 사용해보지 않았기 때문에 개인적인 이야기가 아닌 문서를 탐색하면서 언급된 분석만 제공할 수 있습니다.

내 첫 번째 질문은 왜 Gradle 작업 종속성 그래프가 비순환이 보장되는지였습니다.이에 대한 답은 찾지 못했으나 반대의 경우는 쉽게 구성되기 때문에 순환 감지는 그래프가 빌드될 때 실행되는 검증이고, 다음과 같은 경우 첫 번째 작업을 실행하기 전에 빌드가 실패한다고 가정하겠습니다. 불법적인 순환 종속성이 있습니다.먼저 그래프를 작성하지 않으면 빌드가 거의 완료될 때까지 이 실패 조건이 발견되지 않을 수 있습니다.또한 감지 루틴은 모든 작업이 실행된 후에 실행되어야 하므로 매우 비효율적입니다(그래프가 점진적으로 구축되고 전역적으로 사용 가능한 한 깊이 우선 검색은 시작점을 찾는 데만 필요하며 이후에는 주기 평가에는 최소한의 작업이 필요하지만 전체 작업은 처음에 전체 관계 세트에 대해 단일 축소를 수행하는 것보다 여전히 더 큽니다.저는 조기 발견을 주요 이점으로 꼽고 싶습니다.

작업 종속성은 지연될 수 있습니다(참조:4.3 작업 종속성 및 13.14의 관련 예).전체 그래프가 작성될 때까지 지연 작업 종속성을 올바르게 평가할 수 없습니다.무수한 문제를 일으킬 수 있고 추가 종속성이 검색 및 해결됨에 따라 반복적인 재컴파일이 필요한 전이적(비작업) 종속성 해결의 경우에도 마찬가지입니다(저장소에 대한 반복적인 요청도 필요함).작업 규칙 기능(13.8)도 불가능합니다.이러한 문제와 다른 많은 문제는 Gradle이 동적 언어를 사용하고 작업을 동적으로 추가 및 수정할 수 있다는 점을 고려하여 일반화할 수 있습니다. 따라서 1차 평가 전에는 실행 경로가 구축되고 생성되므로 결과가 비결정적일 수 있습니다. 런타임 중에 수정되므로 아직 생성되지 않았기 때문에 나중에 알 수 없는 종속성이나 동작 지시문이 있는 경우 서로 다른 평가 순서가 임의로 다른 결과를 생성할 수 있습니다.(이것은 몇 가지 구체적인 예를 통해 조사해 볼 가치가 있을 수 있습니다.이것이 사실이라면 두 번의 패스만으로는 항상 충분하지 않습니다.A -> B, B -> C(여기서 C는 A의 동작을 변경하여 더 이상 B에 의존하지 않게 됨)에 문제가 있는 것입니다.임의의 작업에서 메타프로그래밍을 허용하지 않도록 비로컬 범위로 메타프로그래밍을 제한하는 모범 사례가 있기를 바랍니다.재미있는 예는 손자가 할아버지를 죽이거나 할머니와 결혼하는 시간 여행 역설의 시뮬레이션이 될 것이며, 몇 가지 실용적인 윤리 원칙을 생생하게 보여줍니다!)

현재 실행 중인 빌드에 대한 더 나은 상태 및 진행률 보고가 가능합니다.TaskExecutionListener는 각 작업 처리에 대한 전후 후크를 제공하지만 남은 작업 수를 알지 못하면 "6개 작업이 완료되었습니다." 외에는 상태에 대해 말할 수 있는 것이 많지 않습니다.foo 작업을 실행하려고 합니다." 대신 gradle.taskGraph.whenReady의 작업 수로 TaskExecutionListener를 초기화한 다음 이를 TaskExecutionGraph에 연결할 수 있습니다.이제 "72개 작업 중 6개 작업이 완료되었습니다."와 같은 보고서 세부 정보를 활성화하는 정보를 제공할 수 있습니다.이제 foo 작업을 실행합니다.남은 예상 시간:2시간 38분." 이는 지속적인 통합 서버용 콘솔에 표시하는 데 유용하거나 Gradle을 사용하여 대규모 다중 프로젝트 빌드를 조정하고 시간 예측이 중요한 경우에 유용합니다.

Jerry Bullard가 지적한 것처럼 수명 주기의 평가 부분은 환경에 대한 정보를 제공하는 실행 계획을 결정하는 데 매우 중요합니다. 환경은 실행 컨텍스트에 의해 부분적으로 결정되기 때문입니다(DAG로 구성 섹션의 예 4.15).또한 이것이 실행 최적화에 유용하다는 것을 알 수 있었습니다.독립적인 하위 경로는 다른 스레드로 안전하게 전달될 수 있습니다.실행을 위한 걷기 알고리즘은 순진하지 않은 경우 메모리 집약도가 낮을 ​​수 있습니다(내 직관에 따르면 항상 하위 경로가 가장 많은 경로를 걷는 것이 항상 하위 경로가 가장 적은 경로를 선호하는 것보다 더 큰 스택으로 이어질 것이라고 생각합니다).

이 기능의 흥미로운 용도는 데모 및 점진적 개발을 지원하기 위해 시스템의 많은 구성 요소가 처음에 스텁아웃되는 상황일 수 있습니다.그런 다음 개발 중에 각 구성 요소가 구현될 때 빌드 구성을 업데이트하는 대신 빌드 자체에서 하위 프로젝트를 포함할 준비가 되었는지 확인할 수 있습니다(아마도 코드를 가져와 컴파일하고 미리 결정된 테스트 모음을 실행하려고 시도할 수 있음). .그렇다면 평가 단계에서 이를 공개하고 적절한 작업이 포함되며, 그렇지 않으면 스텁에 대한 작업을 선택합니다.아마도 아직 사용할 수 없는 Oracle 데이터베이스에 대한 종속성이 있을 수 있으며 그 동안에는 내장된 데이터베이스를 사용하고 있을 것입니다.빌드에서 가용성을 확인하고, 가능할 때 투명하게 전환하고, 사용자가 알려주는 대신 데이터베이스를 전환했음을 알려줄 수 있습니다.이러한 측면에서 창의적인 용도가 많이 있을 수 있습니다.

Gradle은 정말 멋져 보입니다.연구를 촉발해 주셔서 감사합니다!

다른 팁

an 동일한 문서의 예 이 접근법의 힘을 보여줍니다.

나중에 자세히 설명 하듯이 (30 장, 빌드 라이프 사이클 참조) Gradle에는 구성 단계와 실행 단계가 있습니다. 구성 단계 Gradle 후에는 실행 해야하는 모든 작업을 알고 있습니다. Gradle 은이 정보를 사용할 수있는 갈고리를 제공합니다. 이를위한 유스 케이스는 릴리스 작업이 실행될 작업의 일부인지 확인하는 것입니다. 이에 따라 일부 변수에 다른 값을 할당 할 수 있습니다.

다시 말해, 빌드 프로세스에 일찍 연결할 수 있으므로 필요에 따라 코스를 변경할 수 있습니다. 실제 빌드 작업이 이미 수행 된 경우 변경하기에는 너무 늦을 수 있습니다.

나는 지금 다른 빌드 시스템을 평가하고 있으며 Gradle을 사용하면 'Jar'유형의 모든 작업을 열거하고 변경하여 변경하여 모든 JAR Manifest가 'Build-Number'속성 (나중에 최종 결승에 사용하는 데 사용됩니다. 파일 이름) :

gradle.taskGraph.whenReady {
    taskGraph ->
    taskGraph.getAllTasks().findAll {
        it instanceof org.gradle.api.tasks.bundling.Jar
    }.each {
        it.getManifest().getAttributes().put('Build-Number', project.buildVersion.buildNumber)
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top