All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.dagere.peass.execution.gradle.GradleBuildfileVisitor Maven / Gradle / Ivy

The newest version!
package de.dagere.peass.execution.gradle;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.codehaus.groovy.ast.ASTNode;
import org.codehaus.groovy.ast.CodeVisitorSupport;
import org.codehaus.groovy.ast.builder.AstBuilder;
import org.codehaus.groovy.ast.expr.ArgumentListExpression;
import org.codehaus.groovy.ast.expr.ConstantExpression;
import org.codehaus.groovy.ast.expr.Expression;
import org.codehaus.groovy.ast.expr.MapEntryExpression;
import org.codehaus.groovy.ast.expr.MethodCallExpression;
import org.codehaus.groovy.ast.expr.NamedArgumentListExpression;
import org.codehaus.groovy.ast.expr.TupleExpression;

import de.dagere.peass.config.ExecutionConfig;

public class GradleBuildfileVisitor extends CodeVisitorSupport {

   private static final Logger LOG = LogManager.getLogger(GradleBuildfileVisitor.class);
   private static final String ADDEDBYPEASS = " // Added dynamically by Peass.";
   public static final String JUPITER_EXECUTION_CONFIG = "junit.jupiter.execution.parallel.enabled";
   public static final String JUPITER_EXECUTION_CONFIG_DEFAULT = "junit.jupiter.execution.parallel.mode.default";

   private int offset = 0;
   private int dependencyLine = -1;
   private int testLine = -1;
   private TestTaskParser testTaskProperties = null;
   private TestTaskParser integrationTestTaskProperties = null;
   private int integrationTestLine = -1;

   private int androidLine = -1;
   private int compileOptionsLine = -1;
   private int sourceCompatibilityLine = -1;
   private int targetCompatibilityLine = -1;
   private int testOptionsAndroid = -1;
   private int unitTestsAll = -1;
   private int buildTools = -1;
   private int buildToolsVersion = -1;
   private int compileSdkVersion = -1;
   private int defaultConfigLine = -1;
   private int minSdkVersion = -1;
   private int targetSdkVersion = -1;
   private int multiDexEnabled = -1;
   private int gradleVersionLine = -1;
   private int androidPackagingOptions = -1;
   private int allConfigurationsLine = -1;
   private MethodCallExpression configurations = null;

   private List excludeLines = new LinkedList<>();
   private boolean hasVersion = true;
   private boolean subprojectJava = false;
   private List gradleFileContents;

   private final ExecutionConfig config;

   public GradleBuildfileVisitor(final File buildfile, ExecutionConfig config) throws IOException {
      this.config = config;
      gradleFileContents = Files.readAllLines(Paths.get(buildfile.toURI()));

      try (Stream lines = Files.lines(buildfile.toPath())) {
         final AstBuilder builder = new AstBuilder();

         String content = lines.filter(line -> !line.trim().startsWith("import ") || (offset++) == -1)
               .collect(Collectors.joining("\n"));

         final List nodes = builder.buildFromString(content);

         for (final ASTNode node : nodes) {
            node.visit(this);
         }
      }
   }

   @Override
   public void visitMethodCallExpression(final MethodCallExpression call) {
      LOG.trace("Call: {}", call.getMethodAsString());
      if (call != null && call.getMethodAsString() != null) {
         // System.out.println(call.getMethodAsString());
         if (call.getMethodAsString().equals("dependencies")) {
            // System.out.println(call);
            dependencyLine = call.getLastLineNumber() + offset;
         } else if (call.getMethodAsString().equals("buildscript")) {
            // continue parsing
         } else if (call.getMethodAsString().equals("test")) {
            testLine = call.getLastLineNumber() + offset;
            if (call.getArguments() instanceof ArgumentListExpression) {
               ArgumentListExpression arguments = (ArgumentListExpression) call.getArguments();
               testTaskProperties = new TestTaskParser(arguments);
            }
         } else if (call.getMethodAsString().equals("integrationTest")) {
            integrationTestLine = call.getLastLineNumber() + offset;
            if (call.getArguments() instanceof ArgumentListExpression) {
               ArgumentListExpression arguments = (ArgumentListExpression) call.getArguments();
               parseTaskDefinition(arguments);
            }
         } else if (call.getMethodAsString().equals("android")) {
            androidLine = call.getLastLineNumber() + offset;
         } else if (call.getMethodAsString().equals("compileOptions")) {
            compileOptionsLine = call.getLastLineNumber() + offset;
         } else if (call.getMethodAsString().equals("sourceCompatibility")) {
            sourceCompatibilityLine = call.getLastLineNumber() + offset;
         } else if (call.getMethodAsString().equals("targetCompatibility")) {
            targetCompatibilityLine = call.getLastLineNumber() + offset;
         } else if (call.getMethodAsString().equals("testOptions")) {
            testOptionsAndroid = call.getLastLineNumber() + offset;
         } else if (call.getMethodAsString().equals("unitTests.all")) {
            unitTestsAll = call.getLastLineNumber() + offset;
         } else if (call.getMethodAsString().equals("classpath")) {
            if (isGradleVersionLine(call)) {
               gradleVersionLine = call.getLastLineNumber() + offset;
            }
         } else if (call.getMethodAsString().equals("buildToolsVersion")) {
            buildToolsVersion = call.getLastLineNumber() + offset;
         } else if (call.getMethodAsString().equals("compileSdkVersion")) {
            compileSdkVersion = call.getLastLineNumber() + offset;
         } else if (call.getMethodAsString().equals("defaultConfig")) {
            defaultConfigLine = call.getLastLineNumber() + offset;
         } else if (call.getMethodAsString().equals("minSdkVersion")) {
            minSdkVersion = call.getLastLineNumber() + offset;
         } else if (call.getMethodAsString().equals("targetSdkVersion")) {
            targetSdkVersion = call.getLastLineNumber() + offset;
         } else if (call.getMethodAsString().equals("multiDexEnabled")) {
            multiDexEnabled = call.getLastLineNumber() + offset;
         } else if (call.getMethodAsString().equals("android.packagingOptions")) {
            androidPackagingOptions = call.getLastLineNumber() + offset;
         } else if (call.getMethodAsString().equals("task")) {
            parseNewTask(call);
         } else if (call.getMethodAsString().equals("register")) {
            // System.out.println(call.getClass());
            parseNewTask(call);
         } else if (call.getMethodAsString().equals("exclude")) {
            parseExcludes(call);
         } else if (call.getMethodAsString().equals("configurations")) {
            configurations = call;
         } else if (call.getMethodAsString().equals("all")) {
            if (configurations != null) {
               if (call.getLineNumber() >= configurations.getLineNumber() && call.getLineNumber() <= configurations.getLastLineNumber()) {
                  allConfigurationsLine = call.getLineNumber();
               }
            }
         }
      }

      super.visitMethodCallExpression(call);
   }
   
   private boolean isGradleVersionLine(MethodCallExpression call) {
      Expression expression = call.getArguments();

      if (expression instanceof ArgumentListExpression) {
         ArgumentListExpression argumentList = (ArgumentListExpression) expression;

         boolean isGradleVersionNode = false;

         for (Expression e : argumentList.getExpressions()) {
            isGradleVersionNode |= e.getText().startsWith("com.android.tools.build:gradle");
         }

         return isGradleVersionNode;
      }

      return false;
   }

   private void parseExcludes(final MethodCallExpression call) {
      TupleExpression tuple = (TupleExpression) call.getArguments();
      Expression expression = tuple.getExpression(0);
      if (expression instanceof NamedArgumentListExpression) {
         NamedArgumentListExpression argumentListExpression = (NamedArgumentListExpression) expression;

         Map map = new HashMap<>();
         for (MapEntryExpression innerMapEntryExpression : argumentListExpression.getMapEntryExpressions()) {
            String key = innerMapEntryExpression.getKeyExpression().getText();
            String value = innerMapEntryExpression.getValueExpression().getText();

            map.put(key, value);
         }
         if ("junit".equals(map.get("group")) && "junit".equals(map.get("module"))) {
            excludeLines.add(call.getLineNumber() + offset);
         }
         if ("org.junit.vintage".equals(map.get("group")) && "junit-vintage-engine".equals(map.get("module"))) {
            excludeLines.add(call.getLineNumber() + offset);
         }
      }
   }

   private void parseNewTask(final MethodCallExpression call) {
      if (call.getArguments() instanceof ArgumentListExpression) {
         ArgumentListExpression arguments = (ArgumentListExpression) call.getArguments();
         Expression first = arguments.getExpression(0);
         if (first instanceof ConstantExpression) {
            ConstantExpression expression = (ConstantExpression) first;
            if (expression.getValue().equals("integrationTest")) {
               integrationTestLine = call.getLastLineNumber() + offset;
               parseTaskDefinition(arguments);
            }
         }
         if (first instanceof MethodCallExpression) {
            MethodCallExpression methodCallExpression = (MethodCallExpression) first;
            Expression method = methodCallExpression.getMethod();
            if (method instanceof ConstantExpression) {
               ConstantExpression expression = (ConstantExpression) method;
               if (expression.getValue().equals("integrationTest")) {
                  integrationTestLine = call.getLastLineNumber() + offset;
                  
                  parseTaskDefinition(arguments);
               }
            }
         }
      }
   }

   private void parseTaskDefinition(ArgumentListExpression arguments) {
      TestTaskParser parser = new TestTaskParser(arguments);
      integrationTestTaskProperties = parser;
   }

   @Override
   public void visitMapEntryExpression(final MapEntryExpression expression) {
      final String name = expression.getKeyExpression().getText();
      if (name.equals("buildTools")) {
         buildTools = expression.getLineNumber();
      }
      super.visitMapEntryExpression(expression);
   }

   public int getDependencyLine() {
      return dependencyLine;
   }

   public int getTestLine() {
      return testLine;
   }

   public TestTaskParser getTestTaskProperties() {
      return testTaskProperties;
   }

   public int getAndroidLine() {
      return androidLine;
   }

   public int getCompileOptionsLine() {
      return compileOptionsLine;
   }

   public void setCompileOptionsLine(int compileOptionsLine) {
      this.compileOptionsLine = compileOptionsLine;
   }

   public int getSourceCompatibilityLine() {
      return sourceCompatibilityLine;
   }

   public int getTargetCompatibilityLine() {
      return targetCompatibilityLine;
   }

   public int getTestOptionsAndroid() {
      return testOptionsAndroid;
   }

   public int getUnitTestsAll() {
      return unitTestsAll;
   }

   public int getIntegrationTestLine() {
      return integrationTestLine;
   }
   
   public TestTaskParser getIntegrationTestTaskProperties() {
      return integrationTestTaskProperties;
   }

   public boolean isHasVersion() {
      return hasVersion;
   }

   public boolean isAndroid() {
      return getBuildTools() != -1 || androidLine != -1 || getBuildToolsVersion() != -1;
   }

   public void setHasVersion(final boolean hasVersion) {
      this.hasVersion = hasVersion;
   }

   public boolean hasVersion() {
      return hasVersion;
   }

   public int getBuildTools() {
      return buildTools;
   }

   public int getBuildToolsVersion() {
      return buildToolsVersion;
   }

   public int getCompileSdkVersion() {
      return compileSdkVersion;
   }

   public int getDefaultConfigLine() {
      return defaultConfigLine;
   }

   public void setDefaultConfigLine(int defaultConfigEnd) {
      defaultConfigLine = defaultConfigEnd;
   }
   
   public int getMinSdkVersion() {
      return minSdkVersion;
   }
   
   public int getTargetSdkVersion() {
      return targetSdkVersion;
   }

   public int getMultiDexEnabled() {
      return multiDexEnabled;
   }

   public int getGradleVersionLine() {
       return gradleVersionLine;
   }
   
   public int getAndroidPackagingOptions() {
      return androidPackagingOptions;
   }

   public void setAndroidPackagingOptions(int androidPackagingOptionsEnd) {
      androidPackagingOptions = androidPackagingOptionsEnd;
   }

   public boolean isSubprojectJava() {
      return subprojectJava;
   }

   public List getLines() {
      return gradleFileContents;
   }

   public List getExcludeLines() {
      return excludeLines;
   }

   public int getAllConfigurationsLine() {
      return allConfigurationsLine;
   }

   public void addLine(final int lineIndex, final String textForAdding) {
      gradleFileContents.add(lineIndex, textForAdding + ADDEDBYPEASS);
      if (lineIndex < dependencyLine && dependencyLine != -1) {
         dependencyLine++;
      }
      
      if (lineIndex < testLine && testLine != -1) {
         testLine++;
      }
      if (testTaskProperties != null) {
         testTaskProperties.increaseLines(lineIndex);
      }

      if (lineIndex < integrationTestLine && integrationTestLine != -1) {
         integrationTestLine++;
      }
      if (integrationTestTaskProperties != null) {
         integrationTestTaskProperties.increaseLines(lineIndex);
      }

      if (lineIndex < androidLine && androidLine != -1) {
         androidLine++;
      }
      if (lineIndex < compileOptionsLine && compileOptionsLine != -1) {
         compileOptionsLine++;
      }
      if (lineIndex < sourceCompatibilityLine && sourceCompatibilityLine != -1) {
         sourceCompatibilityLine++;
      }
      if (lineIndex < targetCompatibilityLine && targetCompatibilityLine != -1) {
         targetCompatibilityLine++;
      }
      if (lineIndex < testOptionsAndroid && testOptionsAndroid != -1) {
         testOptionsAndroid++;
      }
      if (lineIndex < unitTestsAll && unitTestsAll != -1) {
         unitTestsAll++;
      }
      if (lineIndex < buildTools && buildTools != -1) {
         buildTools++;
      }
      if (lineIndex < buildToolsVersion && buildToolsVersion != -1) {
         buildToolsVersion++;
      }
      if (lineIndex < compileSdkVersion && compileSdkVersion != -1) {
         compileSdkVersion++;
      }
      if (lineIndex < defaultConfigLine && defaultConfigLine != -1) {
         defaultConfigLine++;
      }
      if (lineIndex < minSdkVersion && minSdkVersion != -1) {
         minSdkVersion++;
      }
      if (lineIndex < targetSdkVersion && targetSdkVersion != -1) {
         targetSdkVersion++;
      }
      if (lineIndex < multiDexEnabled && multiDexEnabled != -1) {
         multiDexEnabled++;
      }
      if (lineIndex < androidPackagingOptions && androidPackagingOptions != -1) {
         androidPackagingOptions++;
      }
      if (lineIndex < allConfigurationsLine && allConfigurationsLine != -1) {
         allConfigurationsLine++;
      }
      List newExcludeLines = new LinkedList<>();
      for (Integer excludeLine : excludeLines) {
         if (lineIndex < excludeLine) {
            newExcludeLines.add(excludeLine + 1);
         }
      }
      excludeLines = newExcludeLines;
   }

   public void clearLine(final Integer lineNumber) {
      gradleFileContents.set(lineNumber - 1, "");
   }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy