/** * Copyright 2015-2016 Red Hat, Inc, and individual contributors. * <p> * Licensed 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 * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * 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. */ package org.wildfly.swarm.arquillian.adapter.gradle; import java.io.ByteArrayOutputStream; import java.nio.file.Path; import java.util.Scanner; import java.util.Stack; import org.gradle.tooling.GradleConnector; import org.gradle.tooling.ProjectConnection; import org.gradle.tooling.model.GradleProject; import org.wildfly.swarm.tools.ArtifactSpec; import org.wildfly.swarm.tools.DeclaredDependencies; /** * A very naive way to get access the gradle dependency information. * * @author Heiko Braun * @since 19/10/16 */ public class GradleDependencyAdapter { private static final String PREFIX1 = "+---"; private static final String PREFIX2 = "\\---"; private static final String PROJECT = "project"; private static final String COLON = ":"; /** * A gradle build configuration reference */ public enum Configuration { ARCHIVE("archives"), DEFAULT("default"), COMPILE("compile"), RUNTIME("runtime"), TEST_COMPILE("testCompile"), TEST_RUNTIME("testRuntime"); private String literal; Configuration(String literal) { this.literal = literal; } } public GradleDependencyAdapter(Path projectDir) { this.rootPath = projectDir; } public DeclaredDependencies parseDependencies(Configuration configuration) { System.out.println(rootPath); GradleConnector connector = GradleConnector.newConnector() .forProjectDirectory(rootPath.toFile()); ProjectConnection connection = connector.connect(); GradleProject project = connection.getModel(GradleProject.class); ByteArrayOutputStream bout = new ByteArrayOutputStream(); connection.newBuild() .withArguments("dependencies", "--configuration", configuration.literal) .setStandardOutput(bout) .run(); connection.close(); // parse DeclaredDependencies declaredDependencies = new DeclaredDependencies(); String deps = new String(bout.toByteArray()); Scanner scanner = new Scanner(deps); while (scanner.hasNextLine()) { String line = scanner.nextLine(); // top level deps if (line.startsWith(PREFIX1) || line.startsWith(PREFIX2)) { if (stack.size() > 0) { stack.pop(); } // parse line = parseLine(line); String coord = parseCoordinate(line); ArtifactSpec parent = DeclaredDependencies.createSpec(coord); declaredDependencies.add(parent); stack.push(parent); } else if (line.contains(PREFIX)) { // transient line = parseLine(line); if (line.startsWith(PROJECT)) { // Always skip 'project' dependencies. continue; } String coord = parseCoordinate(line); declaredDependencies.add(stack.peek(), DeclaredDependencies.createSpec(coord)); } } scanner.close(); return declaredDependencies; } private String parseCoordinate(String line) { String[] coords = line.split(COLON); if (3 == coords.length) { String version = coords[2]; if (version.contains(VERSION_UP)) { String s = coords[0] + ":" + coords[1] + ":" + version.substring(version.indexOf(VERSION_UP) + VERSION_UP.length(), version.length()); return s; } else { return line; } } else { throw new IllegalArgumentException("Unexpected input format"); } } private String parseLine(String line) { line = line.substring(line.indexOf(PREFIX) + PREFIX.length(), line.length()); if (line.endsWith(SUFFIX)) { line = line.substring(0, line.indexOf(SUFFIX)); } return line; } private static final String PREFIX = "--- "; private static final String SUFFIX = " (*)"; private static final String VERSION_UP = "-> "; private Stack<ArtifactSpec> stack = new Stack<>(); private Path rootPath; }