Skip to content
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
12 changes: 8 additions & 4 deletions index.js
Original file line number Diff line number Diff line change
@@ -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.');
}
Expand Down
50 changes: 30 additions & 20 deletions pom.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand All @@ -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) {
Expand All @@ -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) {
Expand All @@ -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.');
}
Expand All @@ -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);
Expand All @@ -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;
}
Expand Down
8 changes: 5 additions & 3 deletions sbom.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,24 @@ 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));
}
}
}));

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.');
}
Expand Down
10 changes: 5 additions & 5 deletions shared.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;

}
}
}