Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Maven support for curation audit cmd #1118

Merged
merged 10 commits into from
Feb 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions tests/testdata/maven-example-with-many-types/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>org.jfrog</groupId>
<artifactId>cli-test</artifactId>
<version>1.0</version>
<packaging>jar</packaging>

<name>cli-test</name>
<url>http://maven.apache.org</url>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</build>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>lodash</artifactId>
<version>4.17.21</version>
<type>pom</type>
</dependency>
</dependencies>
</project>
47 changes: 20 additions & 27 deletions utils/java/deptreemanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"os"
"strings"

"github.com/jfrog/gofrog/datastructures"
"github.com/jfrog/jfrog-cli-core/v2/utils/config"
"github.com/jfrog/jfrog-cli-core/v2/utils/coreutils"
"github.com/jfrog/jfrog-cli-core/v2/utils/xray"
Expand All @@ -17,22 +16,20 @@ const (
GavPackageTypeIdentifier = "gav://"
)

func BuildDependencyTree(serverDetails *config.ServerDetails, depsRepo string, useWrapper, isMavenDepTreeInstalled bool, tech coreutils.Technology) ([]*xrayUtils.GraphNode, []string, error) {
depTreeParams := &DepTreeParams{
UseWrapper: useWrapper,
Server: serverDetails,
DepsRepo: depsRepo,
}
func BuildDependencyTree(depTreeParams DepTreeParams, tech coreutils.Technology) ([]*xrayUtils.GraphNode, map[string][]string, error) {
if tech == coreutils.Maven {
return buildMavenDependencyTree(depTreeParams, isMavenDepTreeInstalled)
return buildMavenDependencyTree(&depTreeParams)
}
return buildGradleDependencyTree(depTreeParams)
return buildGradleDependencyTree(&depTreeParams)
}

type DepTreeParams struct {
UseWrapper bool
Server *config.ServerDetails
DepsRepo string
UseWrapper bool
Server *config.ServerDetails
DepsRepo string
IsMavenDepTreeInstalled bool
IsCurationCmd bool
CurationCacheFolder string
}

type DepTreeManager struct {
Expand All @@ -47,36 +44,31 @@ func NewDepTreeManager(params *DepTreeParams) DepTreeManager {

// The structure of a dependency tree of a module in a Gradle/Maven project, as created by the gradle-dep-tree and maven-dep-tree plugins.
type moduleDepTree struct {
Root string `json:"root"`
Nodes map[string]depTreeNode `json:"nodes"`
}

type depTreeNode struct {
Children []string `json:"children"`
Root string `json:"root"`
Nodes map[string]xray.DepTreeNode `json:"nodes"`
}

// Reads the output files of the gradle-dep-tree and maven-dep-tree plugins and returns them as a slice of GraphNodes.
// It takes the output of the plugin's run (which is a byte representation of a list of paths of the output files, separated by newlines) as input.
func getGraphFromDepTree(outputFilePaths string) (depsGraph []*xrayUtils.GraphNode, uniqueDeps []string, err error) {
func getGraphFromDepTree(outputFilePaths string) (depsGraph []*xrayUtils.GraphNode, uniqueDepsMap map[string][]string, err error) {
modules, err := parseDepTreeFiles(outputFilePaths)
if err != nil {
return
}
allModulesUniqueDeps := datastructures.MakeSet[string]()
uniqueDepsMap = map[string][]string{}
for _, module := range modules {
moduleTree, moduleUniqueDeps := GetModuleTreeAndDependencies(module)
depsGraph = append(depsGraph, moduleTree)
for _, depToAdd := range moduleUniqueDeps {
allModulesUniqueDeps.Add(depToAdd)
for depToAdd, depTypes := range moduleUniqueDeps {
uniqueDepsMap[depToAdd] = depTypes
}
}
uniqueDeps = allModulesUniqueDeps.ToSlice()
return
}

// Returns a dependency tree and a flat list of the module's dependencies for the given module
func GetModuleTreeAndDependencies(module *moduleDepTree) (*xrayUtils.GraphNode, []string) {
moduleTreeMap := make(map[string][]string)
func GetModuleTreeAndDependencies(module *moduleDepTree) (*xrayUtils.GraphNode, map[string][]string) {
moduleTreeMap := make(map[string]xray.DepTreeNode)
moduleDeps := module.Nodes
for depName, dependency := range moduleDeps {
dependencyId := GavPackageTypeIdentifier + depName
Expand All @@ -85,8 +77,9 @@ func GetModuleTreeAndDependencies(module *moduleDepTree) (*xrayUtils.GraphNode,
childId := GavPackageTypeIdentifier + childName
childrenList = append(childrenList, childId)
}
if len(childrenList) > 0 {
moduleTreeMap[dependencyId] = childrenList
moduleTreeMap[dependencyId] = xray.DepTreeNode{
Types: dependency.Types,
Children: childrenList,
}
}
return xray.BuildXrayDependencyTree(moduleTreeMap, GavPackageTypeIdentifier+module.Root)
Expand Down
2 changes: 1 addition & 1 deletion utils/java/gradle.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ type gradleDepTreeManager struct {
DepTreeManager
}

func buildGradleDependencyTree(params *DepTreeParams) (dependencyTree []*xrayUtils.GraphNode, uniqueDeps []string, err error) {
func buildGradleDependencyTree(params *DepTreeParams) (dependencyTree []*xrayUtils.GraphNode, uniqueDeps map[string][]string, err error) {
manager := &gradleDepTreeManager{DepTreeManager: NewDepTreeManager(params)}
outputFileContent, err := manager.runGradleDepTree()
if err != nil {
Expand Down
42 changes: 27 additions & 15 deletions utils/java/mvn.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"net/url"
"os"
"os/exec"
"path"
"path/filepath"
"strings"

Expand All @@ -21,7 +22,7 @@ const (
mavenDepTreeJarFile = "maven-dep-tree.jar"
mavenDepTreeOutputFile = "mavendeptree.out"
// Changing this version also requires a change in MAVEN_DEP_TREE_VERSION within buildscripts/download_jars.sh
mavenDepTreeVersion = "1.0.2"
mavenDepTreeVersion = "1.1.0"
settingsXmlFile = "settings.xml"
)

Expand All @@ -42,37 +43,41 @@ var mavenDepTreeJar []byte

type MavenDepTreeManager struct {
DepTreeManager
isInstalled bool
cmdName MavenDepTreeCmd
settingsXmlPath string
isInstalled bool
// this flag its curation command, it will set dedicated cache and download url.
isCurationCmd bool
// path to the curation dedicated cache
curationCacheFolder string
cmdName MavenDepTreeCmd
settingsXmlPath string
}

func NewMavenDepTreeManager(params *DepTreeParams, cmdName MavenDepTreeCmd, isDepTreeInstalled bool) *MavenDepTreeManager {
func NewMavenDepTreeManager(params *DepTreeParams, cmdName MavenDepTreeCmd) *MavenDepTreeManager {
depTreeManager := NewDepTreeManager(&DepTreeParams{
Server: params.Server,
DepsRepo: params.DepsRepo,
})
return &MavenDepTreeManager{
DepTreeManager: depTreeManager,
isInstalled: isDepTreeInstalled,
cmdName: cmdName,
DepTreeManager: depTreeManager,
isInstalled: params.IsMavenDepTreeInstalled,
cmdName: cmdName,
isCurationCmd: params.IsCurationCmd,
curationCacheFolder: params.CurationCacheFolder,
}
}

func buildMavenDependencyTree(params *DepTreeParams, isDepTreeInstalled bool) (dependencyTree []*xrayUtils.GraphNode, uniqueDeps []string, err error) {
manager := NewMavenDepTreeManager(params, Tree, isDepTreeInstalled)
func buildMavenDependencyTree(params *DepTreeParams) (dependencyTree []*xrayUtils.GraphNode, uniqueDeps map[string][]string, err error) {
manager := NewMavenDepTreeManager(params, Tree)
outputFilePaths, clearMavenDepTreeRun, err := manager.RunMavenDepTree()
if err != nil {
if clearMavenDepTreeRun != nil {
err = errors.Join(err, clearMavenDepTreeRun())
}
return
}

defer func() {
err = errors.Join(err, clearMavenDepTreeRun())
}()

dependencyTree, uniqueDeps, err = getGraphFromDepTree(outputFilePaths)
return
}
Expand Down Expand Up @@ -123,6 +128,9 @@ func (mdt *MavenDepTreeManager) execMavenDepTree(depTreeExecDir string) (string,
func (mdt *MavenDepTreeManager) runTreeCmd(depTreeExecDir string) (string, error) {
mavenDepTreePath := filepath.Join(depTreeExecDir, mavenDepTreeOutputFile)
goals := []string{"com.jfrog:maven-dep-tree:" + mavenDepTreeVersion + ":" + string(Tree), "-DdepsTreeOutputFile=" + mavenDepTreePath, "-B"}
if mdt.isCurationCmd {
goals = append(goals, "-Dmaven.repo.local="+mdt.curationCacheFolder)
asafambar marked this conversation as resolved.
Show resolved Hide resolved
}
if _, err := mdt.RunMvnCmd(goals); err != nil {
return "", err
}
Expand Down Expand Up @@ -199,16 +207,20 @@ func removeMavenConfig() (func() error, error) {

// Creates a new settings.xml file configured with the provided server and repository from the current MavenDepTreeManager instance.
// The settings.xml will be written to the given path.
func (mdt *MavenDepTreeManager) createSettingsXmlWithConfiguredArtifactory(path string) error {
func (mdt *MavenDepTreeManager) createSettingsXmlWithConfiguredArtifactory(settingsXmlPath string) error {
username, password, err := getArtifactoryAuthFromServer(mdt.server)
if err != nil {
return err
}
remoteRepositoryFullPath, err := url.JoinPath(mdt.server.ArtifactoryUrl, mdt.depsRepo)
endPoint := mdt.depsRepo
if mdt.isCurationCmd {
endPoint = path.Join("api/curation/audit", endPoint)
}
remoteRepositoryFullPath, err := url.JoinPath(mdt.server.ArtifactoryUrl, endPoint)
if err != nil {
return err
}
mdt.settingsXmlPath = filepath.Join(path, settingsXmlFile)
mdt.settingsXmlPath = filepath.Join(settingsXmlPath, settingsXmlFile)
settingsXmlContent := fmt.Sprintf(settingsXmlTemplate, username, password, remoteRepositoryFullPath)

return errorutils.CheckError(os.WriteFile(mdt.settingsXmlPath, []byte(settingsXmlContent), 0600))
Expand Down
Loading
Loading