import * as path from "path" ; import * as vscode from "vscode" ; import { Dependency } from "../explorer/model/Dependency" ; import { MavenProject } from "../explorer/model/MavenProject" ; import { IOmittedStatus } from "../explorer/model/OmittedStatus" ; import { getDependencyTree } from "../handlers/showDependenciesHandler" ; const DUPLICATE_INDICATOR = "omitted for duplicate" ; const CONFLICT_INDICATOR = "omitted for conflict" ; export async function parseRawDependencyDataHandler ( project ) { const dependencyTree = await getDependencyTree ( project . pomPath ) ; if ( dependencyTree === undefined ) { throw new Error ( "Failed to generate dependency tree." ) ; } let treeContent = dependencyTree . slice ( 0 , - 1 ) ; treeContent = treeContent . replace ( /\|/g , " " ) ; treeContent = treeContent . replace ( /\\/g , "+" ) ; treeContent = treeContent . replace ( /\n/g , "\r\n" ) ; const re = /([\w.]+:[\w.-]+:)([\w.-]+)(:[\w/.(\s]+):\s([\w.-]+)\)/gm ; treeContent = treeContent . replace ( re , "$1$4$3 with $2)" ) ; project . fullText = treeContent ; const indent = "   " ; const eol = "\r\n" ; const prefix = "+- " ; const [ treeNodes , conflictNodes ] = await parseTreeNodes ( treeContent , eol , indent , prefix , project . pomPath ) ; project . conflictNodes = conflictNodes ; project . dependencyNodes = treeNodes ; return treeNodes ; } async function parseTreeNodes ( treecontent , eol , indent , prefix , projectPomPath ) { const treeNodes = [ ] ; const conflictNodes = [ ] ; if ( treecontent ) { let curNode ; let preNode ; let parentNode ; let rootNode ; let curIndentCnt ; let preIndentCnt ; const lines = treecontent . split ( eol ) . splice ( 1 ) ; const toDependency = ( line ) : Dependency => { let name = line . slice ( curIndentCnt + prefix . length ) ; const indexCut = name . indexOf ( "(" ) ; let supplement = "" ; if ( indexCut !== - 1 ) { supplement = name . substr ( indexCut ) ; name = name . substr ( 0 , indexCut - 1 ) ; } const [ gid , aid , version , scope ] = name . split ( ":" ) ; let effectiveVersion ; let omittedStatus ; if ( supplement . indexOf ( CONFLICT_INDICATOR ) !== - 1 ) { const re = /\(omitted for conflict with ([\w.-]+)\)/gm ; effectiveVersion = supplement . replace ( re , "$1" ) ; omittedStatus = { status : "conflict" , effectiveVersion , description : supplement } ; } else if ( supplement . indexOf ( DUPLICATE_INDICATOR ) !== - 1 ) { omittedStatus = { status : "duplicate" , effectiveVersion : version , description : supplement } ; } return new Dependency ( gid , aid , version , scope , projectPomPath , omittedStatus ) ; } ; lines . forEach ( line => { curIndentCnt = line . indexOf ( prefix ) ; curNode = toDependency ( line ) ; let uri ; let curFilePath ; if ( curIndentCnt === 0 ) { curNode . root = curNode ; rootNode = curNode ; parentNode = curNode ; curFilePath = path . join ( curNode . groupId , curNode . artifactId ) ; } else { curNode . root = rootNode ; if ( curIndentCnt === preIndentCnt ) { parentNode . addChild ( curNode ) ; } else if ( curIndentCnt > preIndentCnt ) { parentNode = preNode ; parentNode . addChild ( curNode ) ; } else { const level = ( preIndentCnt - curIndentCnt ) / indent . length ; for ( let i = level ; i > 0 ; i -= 1 ) { parentNode = parentNode . parent ; } parentNode . addChild ( curNode ) ; } const parentFilePath = parentNode . uri . path ; curFilePath = path . join ( parentFilePath , path . join ( curNode . groupId , curNode . artifactId ) ) ; } uri = vscode . Uri . file ( curFilePath ) ; uri = uri . with ( { authority : projectPomPath } ) ; if ( curNode . omittedStatus === undefined ) { curNode . uri = uri ; } else if ( curNode . omittedStatus . status === "conflict" ) { curNode . uri = uri . with ( { query : "hasConflict" } ) ; let tmpNode = curNode ; while ( tmpNode . parent !== undefined ) { const parent = tmpNode . parent ; if ( parent . uri . query !== "hasConflict" ) { parent . uri = uri . with ( { query : "hasConflict" } ) ; tmpNode = parent ; } else { break ; } } conflictNodes . push ( curNode ) ; } else if ( curNode . omittedStatus . status === "duplicate" ) { curNode . uri = uri . with ( { query : "isDuplicate" } ) ; } if ( curIndentCnt === 0 ) { treeNodes . push ( rootNode ) ; } preIndentCnt = curIndentCnt ; preNode = curNode ; } ) ; } return [ treeNodes , conflictNodes ] ; }