Skip to content

Commit

Permalink
Feature/maven dependency versioning requirement specification (#20)
Browse files Browse the repository at this point in the history
* Removed IDE Specific files

* Maven versioning requirement specification

* removed logging and downloadFile now throws IOException

* Exception handling in JSONHelper & Version bump

* Bug fixes in Maven dependency resolver

* commons-compress version change
  • Loading branch information
prathamgahlout authored Mar 1, 2024
1 parent 843701b commit bee0be5
Show file tree
Hide file tree
Showing 10 changed files with 376 additions and 70 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.phsyberdome</groupId>
<artifactId>phsyberdome-sca-cli</artifactId>
<version>1.0.2-beta</version>
<version>1.0.3-beta</version>
<packaging>jar</packaging>
<build>
<plugins>
Expand Down
115 changes: 107 additions & 8 deletions src/main/java/com/phsyberdome/drona/Plugins/JavaMavenPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,17 @@
import com.phsyberdome.drona.Models.Pair;
import com.phsyberdome.drona.Utils.FileUtil;
import com.phsyberdome.drona.Utils.MavenRepoHelper;
import com.phsyberdome.drona.Utils.MavenVersionHelper;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.io.FileUtils;
Expand All @@ -41,9 +45,13 @@ public class JavaMavenPlugin implements PluginInterface

private ArrayList<Module> modules;
private final LicenseDetector licenseDetector;

private Set<Module> scannedDependencies;


public JavaMavenPlugin(LicenseDetector licenseDetector) {
this.licenseDetector = licenseDetector;
this.scannedDependencies = new HashSet<>();
}


Expand Down Expand Up @@ -77,7 +85,6 @@ public void readModules() {
String rootGroupId = MavenRepoHelper.extractAttributeFromNode(doc.getDocumentElement(), "groupId");
String rootVersion = MavenRepoHelper.extractAttributeFromNode(doc.getDocumentElement(), "version");
Module root = new Module(rootArtifactId,rootVersion);

NodeList list = doc.getElementsByTagName("dependency");

for(int i=0;i<list.getLength();i++){
Expand All @@ -88,29 +95,53 @@ public void readModules() {
}
Element element = (Element) node;


var isSoftRequirement = false;
String artifactId = MavenRepoHelper.extractAttributeFromNode(element, "artifactId");
String groupId = MavenRepoHelper.extractAttributeFromNode(element, "groupId");
String version = MavenRepoHelper.extractAttributeFromNode(element, "version");
String scope = MavenRepoHelper.extractAttributeFromNode(element, "scope");
String optional = MavenRepoHelper.extractAttributeFromNode(element, "optional");
if(scope!=null && (scope.equals("test") || scope.equals("import"))){
continue;
}
if(optional!=null && (optional.equals("true"))){
continue;
}

// if we have a property as version.
if(version!=null)
version = MavenRepoHelper.resolvePropertyValue(version, doc);
// If we dont even have version mentioned.
else
version = MavenRepoHelper.getVersionFromParent(artifactId,MavenRepoHelper.getParentPOM(doc));
if(version!=null){
var resolvedVersion = MavenVersionHelper.resolveVersion(groupId, artifactId, version);
if(resolvedVersion.equals(version)) {
// Was it a soft requirement?
isSoftRequirement = true;
}
version = resolvedVersion;
}

Module m = new Module(artifactId,version);
m.setSupplier(groupId);
if(alreadyScanned(m)){
CLIHelper.updateCurrentLine("Dependency "+artifactId+" already scanned",Ansi.Color.GREEN);
root.addToDependencies(getScannedModule(m));
continue;
}else if(isSoftRequirement && isAlreadyScannedArtifact(m.getName())){
CLIHelper.updateCurrentLine("Dependency "+artifactId+" already scanned",Ansi.Color.GREEN);
root.addToDependencies(getScannedModule(artifactId));
continue;
}

if(version!=null){
getLicenseAndTransitiveDependenciesForModule(m);
}else{
}else {
CLIHelper.updateCurrentLine("Cannot proceed! REASON: Couldnt get version for "+m.getName(),Ansi.Color.CYAN);
}
root.addToDependencies(m);
scannedDependencies.add(m);
}
}
modules.add(root);
Expand All @@ -123,7 +154,7 @@ public void readModules() {


private void getLicenseAndTransitiveDependenciesForModule(Module root) {
CLIHelper.updateCurrentLine("Building dep tree for "+root.getName(),Ansi.Color.CYAN);
CLIHelper.updateCurrentLine("Building dep tree for "+root.getName()+"@"+root.getVersion(),Ansi.Color.CYAN);
String repoUrlString = buildRepositoryUrl(root);
String loc = Configuration.getConfiguration().getCloneLocation().toString();
Path path = FileUtil.getFilePathFromURL(repoUrlString,loc);
Expand Down Expand Up @@ -153,10 +184,10 @@ private void buildDependencyTree(Module root, Path pathToModule) {
try {
FileUtils.copyURLToFile(new URL(urlToPomString), file);
} catch (MalformedURLException ex) {
Logger.getLogger(MavenRepoHelper.class.getName()).log(Level.SEVERE, null, ex);
// Logger.getLogger(MavenRepoHelper.class.getName()).log(Level.SEVERE, null, ex);
return;
} catch (IOException ex) {
Logger.getLogger(MavenRepoHelper.class.getName()).log(Level.SEVERE, null, ex);
// Logger.getLogger(MavenRepoHelper.class.getName()).log(Level.SEVERE, null, ex);
return;
}
CLIHelper.updateCurrentLine("Downloaded pom from "+urlToPomString,Ansi.Color.GREEN);
Expand All @@ -171,36 +202,61 @@ private void buildDependencyTree(Module root, Path pathToModule) {
return;
}
NodeList list = doc.getElementsByTagName("dependency");

for(int i=0;i<list.getLength();i++){
Node node = list.item(i);
if(node.getNodeType() == Node.ELEMENT_NODE) {
if(!node.getParentNode().getNodeName().equals("dependencies")){
continue;
}
var isSoftRequirement = false;
Element element = (Element) node;
String artifactId = MavenRepoHelper.extractAttributeFromNode(element, "artifactId");
String groupId = MavenRepoHelper.extractAttributeFromNode(element, "groupId");
String version = MavenRepoHelper.extractAttributeFromNode(element, "version");
String scope = MavenRepoHelper.extractAttributeFromNode(element, "scope");
String optional = MavenRepoHelper.extractAttributeFromNode(element, "optional");

if(scope!=null && (scope.equals("test") || scope.equals("import"))){
continue;
}
if(optional!=null && (optional.equals("true"))){
continue;
}
// if we have a property as version.
if(version!=null)
version = MavenRepoHelper.resolvePropertyValue(version, doc);
// If we dont even have version mentioned.
else
version = MavenRepoHelper.getVersionFromParent(artifactId,MavenRepoHelper.getParentPOM(doc));

if(version!=null){
var resolvedVersion = MavenVersionHelper.resolveVersion(groupId, artifactId, version);
if(resolvedVersion.equals(version)) {
// Was it a soft requirement?
isSoftRequirement = true;
}
version = resolvedVersion;
}

Module m = new Module(artifactId,version);
m.setSupplier(groupId);
if(alreadyScanned(m)){
CLIHelper.updateCurrentLine("Dependency "+artifactId+" already scanned",Ansi.Color.GREEN);
root.addToDependencies(getScannedModule(m));
continue;
}else if(isSoftRequirement && isAlreadyScannedArtifact(m.getName())){
CLIHelper.updateCurrentLine("Dependency "+artifactId+" already scanned",Ansi.Color.GREEN);
root.addToDependencies(getScannedModule(artifactId));
continue;
}

if(version!=null){
getLicenseAndTransitiveDependenciesForModule(m);
}else{
CLIHelper.updateCurrentLine("Cannot proceed! REASON: Couldnt get version for "+m.getName(),Ansi.Color.RED);
}
root.addToDependencies(m);
scannedDependencies.add(m);
}
}

Expand Down Expand Up @@ -228,5 +284,48 @@ private static String buildRepositoryUrl(Module root) {
public ArrayList<Module> getModules() {
return modules;
}

private boolean alreadyScanned(Module m){
Iterator it = scannedDependencies.iterator();
while(it.hasNext()){
Module a = (Module) it.next();
if(a.getName()==m.getName() && a.getVersion() == m.getVersion()){
return true;
}
}
return false;
}

private Module getScannedModule(Module m){
Iterator it = scannedDependencies.iterator();
while(it.hasNext()){
Module a = (Module) it.next();
if(a.getName().strip().equalsIgnoreCase(m.getName().strip()) && a.getVersion().strip().equalsIgnoreCase(m.getVersion().strip())){
return a;
}
}
return m;
}
private Module getScannedModule(String artifactId){
Iterator it = scannedDependencies.iterator();
while(it.hasNext()){
Module a = (Module) it.next();
if(a.getName().strip().equalsIgnoreCase(artifactId.strip())){
return a;
}
}
return new Module(artifactId,"");
}

private boolean isAlreadyScannedArtifact(String artifiactId) {
Iterator it = scannedDependencies.iterator();
while(it.hasNext()){
Module a = (Module) it.next();
if(a.getName().equalsIgnoreCase(artifiactId)){
return true;
}
}
return false;
}

}
13 changes: 5 additions & 8 deletions src/main/java/com/phsyberdome/drona/Utils/FileUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -156,19 +156,16 @@ public static Path getFilePathFromURL(String path, String cloneLocation){
return null;
}

public static File downloadFile(String path, String url){
public static File downloadFile(String path, String url)throws IOException{
File file = FileSystems.getDefault().getPath(path).toFile();
if(file.exists()) {
FileUtil.deleteDirectory(file);
}
try {
FileUtils.copyURLToFile(new URL(url), file);
} catch (MalformedURLException ex) {
Logger.getLogger(MavenRepoHelper.class.getName()).log(Level.SEVERE, null, ex);
// Logger.getLogger(MavenRepoHelper.class.getName()).log(Level.SEVERE, null, ex);
return null;
} catch (IOException ex) {
Logger.getLogger(MavenRepoHelper.class.getName()).log(Level.SEVERE, null, ex);
return null;
}
return file;
}
Expand Down Expand Up @@ -218,10 +215,10 @@ public static String readFile(Path filePath) {
text = content.collect(Collectors.joining("\n"));
}
return text;
} catch (IOException ex) {
} catch (Exception ex) {
CLIHelper.updateCurrentLine(ex.getLocalizedMessage(), Ansi.Color.RED);
return null;
}
return "";
}

public static void extractZipFolder(String zipFile,String extractFolder)
Expand Down Expand Up @@ -334,7 +331,7 @@ public static void extractTarball(String tarfile,String toPath) throws FileNotFo
tarEntry = tarIn.getNextTarEntry();
}
tarIn.close();
}catch(IOException e){
}catch(Exception e){
CLIHelper.updateCurrentLine("Failed to untar file " + tarfile,Ansi.Color.RED);
}

Expand Down
17 changes: 8 additions & 9 deletions src/main/java/com/phsyberdome/drona/Utils/JSONHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.phsyberdome.drona.CLIHelper;
import com.phsyberdome.drona.Models.Pair;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.fusesource.jansi.Ansi;

/**
*
Expand All @@ -27,7 +26,7 @@ public static String convertToJson(Object object) {
try {
json = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(object);
}catch(JsonProcessingException e) {
Logger.getLogger(JSONHelper.class.getCanonicalName()).log(Level.WARNING, e.getLocalizedMessage());
CLIHelper.updateCurrentLine("Failed to convert to json!", Ansi.Color.RED);
return null;
}
return json;
Expand All @@ -38,7 +37,7 @@ public static <T> T convertToObj(Class<T> c,String json) {
ObjectMapper objectMapper = new ObjectMapper();
return (T) objectMapper.readValue(json, c);
}catch(Exception e) {
Logger.getLogger(JSONHelper.class.getCanonicalName()).log(Level.WARNING, e.getLocalizedMessage());
CLIHelper.updateCurrentLine("Failed to parse json!", Ansi.Color.RED);
}
return null;
}
Expand All @@ -49,8 +48,8 @@ public static String getValue(String keyPath,String json){
try {
root = objectMapper.readTree(json);
return root.at(keyPath).asText();
} catch (JsonProcessingException ex) {
Logger.getLogger(JSONHelper.class.getName()).log(Level.SEVERE, null, ex);
} catch (Exception e){
CLIHelper.updateCurrentLine("Failed to parse json!", Ansi.Color.RED);
}
return null;
}
Expand All @@ -68,8 +67,8 @@ public static List<String> getValues(String keyPath,String json){
res.add(field.getKey());
}
return res;
} catch (JsonProcessingException ex) {
Logger.getLogger(JSONHelper.class.getName()).log(Level.SEVERE, null, ex);
} catch (Exception ex) {
CLIHelper.updateCurrentLine("Failed to parse json!", Ansi.Color.RED);
}
return null;
}
Expand Down
21 changes: 17 additions & 4 deletions src/main/java/com/phsyberdome/drona/Utils/MavenRepoHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import com.phsyberdome.drona.CLIHelper;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
Expand Down Expand Up @@ -61,11 +62,19 @@ public static Document readXMLDocument(Path path) {



public static Document getMavenMetadataDocument(String groupId, String artifactId) {
public static Document getMavenMetadataDocument(String groupId, String artifactId){
String repoUrl = buildRootRepoUrl(groupId, artifactId);
String mvnMetadataFileUrl = repoUrl + "maven-metadata.xml";

File metadataFile = FileUtil.downloadFile("/.drona/temp/data/metadata.xml", mvnMetadataFileUrl);
File metadataFile;
try {
metadataFile = FileUtil.downloadFile("/.drona/temp/data/metadata.xml", mvnMetadataFileUrl);
} catch (IOException ex) {
return null;
}
if(metadataFile==null) {
return null;
}
Document doc = readXMLDocument(metadataFile.toPath());
if(metadataFile.exists()){
FileUtil.deleteDirectory(metadataFile);
Expand Down Expand Up @@ -135,7 +144,6 @@ public static String getVersionFromParent(String artifactId,Document doc){
public static Document getParentPOM(Document pom) {
NodeList parents = pom.getElementsByTagName("parent");
if(parents.getLength() <= 0){
System.out.println("This is the root pom!");
return null;
}
Element parent = (Element) parents.item(0);
Expand All @@ -144,7 +152,12 @@ public static Document getParentPOM(Document pom) {
String version = parent.getElementsByTagName("version").item(0).getTextContent();
//version = resolvePropertyValue(version, pom);
String urlToParentPom = buildUrlForPomFile(groupId, artifactId, version);
File file = FileUtil.downloadFile("/.drona/temp/poms/pom.xml", urlToParentPom);
File file;
try {
file = FileUtil.downloadFile("/.drona/temp/poms/"+artifactId+"_parent_pom.xml", urlToParentPom);
} catch (IOException ex) {
return null;
}
Document doc = readXMLDocument(file.toPath());
if(file.exists()){
FileUtil.deleteDirectory(file);
Expand Down
Loading

0 comments on commit bee0be5

Please sign in to comment.