| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| // Check if dependency resolution is happening at configuration time |
| def resolvingAllowed = false |
| int pcount = allprojects.size() |
| allprojects { p -> |
| p.afterEvaluate { |
| resolvingAllowed = --pcount == 0 |
| } |
| def checkResolution = { cnf -> |
| cnf.incoming.beforeResolve { |
| if (!resolvingAllowed) { |
| def e = new RuntimeException() |
| List<StackTraceElement> inGradleBuild = e.stackTrace.findAll { it.fileName?.endsWith('.gradle') && !it.fileName.endsWith('bad-practices.gradle') } |
| def stack = inGradleBuild.collect { |
| " at ${it.fileName}:${it.lineNumber}" |
| }.join("\n") |
| throw new IllegalStateException("Configuration $cnf in project $p is being resolved at configuration time.\nThis shouldn't be necessary and usually indicates an error in the build script.\nSee :\n${stack}") |
| } |
| } |
| } |
| p.configurations.all(checkResolution) |
| // This will make sure we also capture problems with detached configurations |
| // However it will only do so with build scripts that use dynamic Groovy |
| p.configurations.metaClass = new ContainerMetaclassClass(p.configurations.metaClass, checkResolution) |
| } |
| |
| @groovy.transform.CompileStatic |
| class ContainerMetaclassClass extends DelegatingMetaClass { |
| Closure configuration |
| |
| ContainerMetaclassClass(MetaClass metaClass, Closure configuration) { |
| super(metaClass) |
| this.configuration = configuration |
| } |
| |
| Object invokeMethod(Object object, String name, Object[] args) { |
| maybeConfigure(super.invokeMethod(object, name, args), name) |
| } |
| |
| Object invokeMethod(Object object, String name, Object arg) { |
| maybeConfigure(super.invokeMethod(object, name, arg), name) |
| } |
| |
| private Object maybeConfigure(Object object, String name) { |
| if ('detachedConfiguration' == name) { |
| configuration(object) |
| } |
| object |
| } |
| } |