diff --git a/index.js b/index.js index 3347052..39be290 100644 --- a/index.js +++ b/index.js @@ -1,20 +1,24 @@ import { extname } from 'path'; import { retrieveSimilarSbomPackages } from './sbom.js'; -import { getXMLFromFile, retrieveSimilarPomPackages, retrieveSimilarPomProperties } from './pom.js'; +import { getPomSpringBootVersion, getXMLFromFile, retrieveSimilarPomPackages, retrieveSimilarPomProperties } from './pom.js'; export const checkDependencies = async () => { const start = Date.now(); const filename = process.argv[2]; const fileExtension = extname(filename); - console.log('filename', filename, 'fileExtension', fileExtension); + // console.log('filename', filename, 'fileExtension', fileExtension); if (fileExtension === '.json') { console.log('Processing json file'); await retrieveSimilarSbomPackages(filename); } else if (fileExtension === '.xml') { console.log('Processing xml file'); const parsedPom = await getXMLFromFile(process.argv[2]); - await retrieveSimilarPomPackages(parsedPom); - await retrieveSimilarPomProperties(parsedPom); + const springBootVersion = await getPomSpringBootVersion(parsedPom); + if (springBootVersion) { + console.log('Detected Spring Boot Version -', springBootVersion); + await retrieveSimilarPomPackages(parsedPom, springBootVersion); + await retrieveSimilarPomProperties(parsedPom, springBootVersion); + } } else { console.log('Unknown extension, unable to process file.'); } diff --git a/pom.js b/pom.js index d18cf34..27fe5c2 100644 --- a/pom.js +++ b/pom.js @@ -14,8 +14,11 @@ export const getXMLFromFile = async (filename) => { }; const getPomProperties = async (parsedPom) => { - const properties = parsedPom.project.properties; - return Object.keys(properties); + const properties = parsedPom.project?.properties; + if (properties) { + return Object.keys(properties); + } + return []; }; const getSpringBootProperties = async (filename) => { @@ -24,22 +27,24 @@ const getSpringBootProperties = async (filename) => { }; const getPomDependenciesWithVersions = async (parsedPom) => { - return parsedPom.project.dependencies.dependency.filter(dep => dep.version); + // if it's not an array, a single dependency has been declared and it doesn't apply + if (Array.isArray(parsedPom?.project?.dependencies?.dependency)) { + return parsedPom.project.dependencies.dependency.filter(dep => dep.version); + } + return []; }; -const getPomSpringBootVersion = async (parsedPom) => { - if (parsedPom.project.parent.groupId === 'org.springframework.boot' && parsedPom.project.parent.artifactId === 'spring-boot-starter-parent') { +export const getPomSpringBootVersion = async (parsedPom) => { + if (parsedPom.project?.parent?.groupId === 'org.springframework.boot' && parsedPom.project?.parent?.artifactId === 'spring-boot-starter-parent') { return parsedPom.project.parent.version; } console.log('No Spring Boot version found.'); return ''; }; -export const retrieveSimilarPomPackages = async (parsedPom) => { +export const retrieveSimilarPomPackages = async (parsedPom, springBootVersion) => { const pomDependenciesWithVersions = await getPomDependenciesWithVersions(parsedPom); - const springBootVersion = await getPomSpringBootVersion(parsedPom); if (springBootVersion) { - console.log('Detected Spring Boot Version', springBootVersion); const defaultVersions = await getDefaultSpringBootVersions(springBootVersion); if (defaultVersions.length) { @@ -54,18 +59,18 @@ export const retrieveSimilarPomPackages = async (parsedPom) => { })); console.log('Mismatched Pom Package Count -', mismatchedPackages.length); - console.log('Mismatched Packages', mismatchedPackages); + if (mismatchedPackages.length) { + console.log('Mismatched Pom Packages -', mismatchedPackages); + } } else { console.log('Spring Boot default versions URL no longer exists.'); } } }; -export const retrieveSimilarPomProperties = async (parsedPom) => { +export const retrieveSimilarPomProperties = async (parsedPom, springBootVersion) => { const pomProperties = await getPomProperties(parsedPom); - const springBootVersion = await getPomSpringBootVersion(parsedPom); if (springBootVersion) { - console.log('Detected Spring Boot Version', springBootVersion); const defaultProperties = await getSpringBootProperties(springBootVersion); if (defaultProperties.length) { @@ -76,8 +81,10 @@ export const retrieveSimilarPomProperties = async (parsedPom) => { } })); - console.log('Declared Properties Count -', declaredProperties.length); - console.log('Declared Properties', declaredProperties); + console.log('Declared Pom Properties Count -', declaredProperties.length); + if (declaredProperties.length) { + console.log('Declared Pom Properties -', declaredProperties); + } } else { console.log('Spring Boot default versions URL no longer exists.'); } @@ -89,8 +96,8 @@ const getSpringDefaultProperties = async (sbVersion) => { await ensureDirExists(); if (!existsSync(`${cachePath}/properties_${sbVersion}.json`)) { await downloadSpringVersionProperties(sbVersion); - } else { - console.log('Spring Boot default properties file already exists in cache.'); + // } else { + // console.log('Spring Boot default properties file already exists in cache.'); } } catch (err) { console.error('Error retrieving spring default properties', err); @@ -107,10 +114,13 @@ const downloadSpringVersionProperties = async (sbVersion) => { const parsedTemplate = parse(template); const tableBody = parsedTemplate.getElementsByTagName('tbody')[1]; - tableBody.childNodes.forEach(child => // there's a header row we should skip - child.childNodes.length === 0 ? '' : versions.push({ - property: child.childNodes[3].rawText, - })); + // older versions of Spring Boot do not have property versions listed + if (tableBody) { + tableBody.childNodes.forEach(child => // there's a header row we should skip + child.childNodes.length === 0 ? '' : versions.push({ + property: child.childNodes[3].rawText, + })); + } await writeFileSync(`${cachePath}/properties_${sbVersion}.json`, JSON.stringify(versions, null, 2)); break; } diff --git a/sbom.js b/sbom.js index 2dcf750..f1533ab 100644 --- a/sbom.js +++ b/sbom.js @@ -21,14 +21,14 @@ export const retrieveSimilarSbomPackages = async (bomFile) => { const components = await getComponents(bomFile); const springBootVersion = await getSpringBootVersion(components); if (springBootVersion) { - console.log('Detected Spring Boot Version', springBootVersion); + console.log('Detected Spring Boot Version -', springBootVersion); const defaultVersions = await getDefaultSpringBootVersions(springBootVersion); if (defaultVersions.length) { const mismatchedPackages = []; components.forEach(bomPackage => defaultVersions.forEach(bootPackage => { if (bomPackage.group === bootPackage.group && bomPackage.name === bootPackage.name && bomPackage.version !== undefined && bomPackage.version !== bootPackage.version) { - const existingMatches = mismatchedPackages.find(mismatchedPackage => mismatchedPackage.group === bomPackage.group && mismatchedPackage.name === bomPackage.name && mismatchedPackage.sbomVersion === bomPackage.version && mismatchedPackage.bootVersion === bootPackage.version); + const existingMatches = mismatchedPackages.find(mismatchedPackage => mismatchedPackage.group === bomPackage.group && mismatchedPackage.name === bomPackage.name && mismatchedPackage.inputFileVersion === bomPackage.version && mismatchedPackage.bootVersion === bootPackage.version); if (!existingMatches) { mismatchedPackages.push(new Package(bomPackage.group, bomPackage.name, bomPackage.version, bootPackage.version)); } @@ -36,7 +36,9 @@ export const retrieveSimilarSbomPackages = async (bomFile) => { })); console.log('Mismatched Package Count -', mismatchedPackages.length); - console.log('Mismatched Packages', mismatchedPackages); + if (mismatchedPackages.length) { + console.log('Mismatched Packages -', mismatchedPackages); + } } else { console.log('Spring Boot default versions URL no longer exists.'); } diff --git a/shared.js b/shared.js index 3e37d63..ab44ebb 100644 --- a/shared.js +++ b/shared.js @@ -23,8 +23,8 @@ const getSpringDefaultVersions = async (sbVersion) => { await ensureDirExists(); if (!existsSync(`${cachePath}/dependencies_${sbVersion}.json`)) { await downloadSpringDefaultVersions(sbVersion); - } else { - console.log('Spring Boot default versions file already exists in cache.'); + // } else { + // console.log('Spring Boot default versions file already exists in cache.'); } } catch (err) { console.error('Error retrieving spring default versions', err); @@ -63,11 +63,11 @@ export const getDefaultSpringBootVersions = async (filename) => { }; export class Package { - constructor(group, name, sbomVersion, bootVersion) { + constructor(group, name, inputFileVersion, bootVersion) { this.group = group; this.name = name; - this.sbomVersion = sbomVersion; + this.inputFileVersion = inputFileVersion; this.bootVersion = bootVersion; } -} \ No newline at end of file +}