Skip to content

chore: dont pass callback for thrown errors in invokeCommand #183

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

Merged
merged 1 commit into from
Apr 23, 2025
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
3 changes: 1 addition & 2 deletions src/providers/base_java.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
let matchedScope = target.match(/:compile|:provided|:runtime|:test|:system|:import/g)
let matchedScopeSrc = src.match(/:compile|:provided|:runtime|:test|:system|:import/g)
// only add dependency to sbom if it's not with test scope or if it's root
if ((matchedScope && matchedScope[0] !== ":test" && (matchedScopeSrc && matchedScopeSrc[0] !== ":test")) || (srcDepth == 0 && matchedScope && matchedScope[0] !== ":test")) {

Check warning on line 47 in src/providers/base_java.js

View workflow job for this annotation

GitHub Actions / Lint and test project (latest)

Expected '===' and instead saw '=='

Check warning on line 47 in src/providers/base_java.js

View workflow job for this annotation

GitHub Actions / Lint and test project (18)

Expected '===' and instead saw '=='
sbom.addDependency(sbom.purlToComponent(from), to)
}
} else {
Expand Down Expand Up @@ -109,8 +109,7 @@
/** this method invokes command string in a process in a synchronous way.
* @param bin - the command to be invoked
* @param args - the args to pass to the binary
* @param callback - function to invoke if an error was thrown
* @protected
*/
_invokeCommand(bin, args, callback, opts={}) { return invokeCommand(bin, args, callback, opts) }
_invokeCommand(bin, args, opts={}) { return invokeCommand(bin, args, opts) }
}
21 changes: 10 additions & 11 deletions src/providers/java_gradle.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import fs from 'node:fs'
import {getCustomPath} from "../tools.js";
import path from 'node:path'
import Sbom from '../sbom.js'

Check warning on line 4 in src/providers/java_gradle.js

View workflow job for this annotation

GitHub Actions / Lint and test project (latest)

Imports should be sorted alphabetically

Check warning on line 4 in src/providers/java_gradle.js

View workflow job for this annotation

GitHub Actions / Lint and test project (18)

Imports should be sorted alphabetically
import { EOL } from 'os'
import Base_java, { ecosystem_gradle } from "./base_java.js";
import TOML from 'fast-toml'
Expand Down Expand Up @@ -197,13 +197,12 @@
*/
#getProperties(manifestPath, opts) {
let gradle = getCustomPath("gradle", opts);
let properties
properties = this._invokeCommand(gradle, ['properties'], error => {
try {
let properties = this._invokeCommand(gradle, ['properties'], {cwd: path.dirname(manifestPath)})
return properties.toString()
} catch (error) {
throw new Error(`Couldn't get properties of ${this._getManifestName()} file , Error message returned from gradle binary => ${EOL} ${error.message}`)
}, {
cwd: path.dirname(manifestPath)
})
return properties.toString()
}
}

/**
Expand Down Expand Up @@ -241,12 +240,12 @@

#getDependencies(manifest) {
const gradle = getCustomPath("gradle")
const commandResult = this._invokeCommand(gradle, ['dependencies'], error => {
try {
const commandResult = this._invokeCommand(gradle, ['dependencies'], {cwd: path.dirname(manifest)})
return commandResult.toString()
} catch (error) {
throw new Error(`Couldn't run gradle dependencies command, error message returned from gradle binary => ${EOL} ${error.message}`)
}, {
cwd: path.dirname(manifest)
})
return commandResult.toString()
}
}

/**
Expand Down
30 changes: 20 additions & 10 deletions src/providers/java_maven.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,11 @@ export default class Java_maven extends Base_java {
const mvn = this.#selectMvnRuntime(manifest, opts)

// clean maven target
this._invokeCommand(mvn, ['-q', 'clean', '-f', manifest], error => {
try {
this._invokeCommand(mvn, ['-q', 'clean', '-f', manifest])
} catch (error) {
throw new Error(`failed to clean maven target`, {cause: error})
})
}

// create dependency graph in a temp file
let tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'exhort_'))
Expand All @@ -93,9 +95,11 @@ export default class Java_maven extends Base_java {
}
})
// execute dependency tree command
this._invokeCommand(mvn, depTreeCmdArgs, error => {
try {
this._invokeCommand(mvn, depTreeCmdArgs)
} catch (error) {
throw new Error(`failed creating maven dependency tree`, {cause: error})
})
}
// read dependency tree from temp file
let content = fs.readFileSync(`${tmpDepTree}`)
if (process.env["EXHORT_DEBUG"] === "true") {
Expand Down Expand Up @@ -138,9 +142,11 @@ export default class Java_maven extends Base_java {
const targetPom = manifestPath

// create effective pom and save to temp file
this._invokeCommand(mvn, ['-q', 'help:effective-pom', `-Doutput=${tmpEffectivePom}`, '-f', targetPom], error => {
try {
this._invokeCommand(mvn, ['-q', 'help:effective-pom', `-Doutput=${tmpEffectivePom}`, '-f', targetPom])
} catch (error) {
throw new Error(`failed creating maven effective pom`, {cause: error})
})
}
// iterate over all dependencies in original pom and collect all ignored ones
let ignored = this.#getDependencies(targetPom).filter(d => d.ignore)
// iterate over all dependencies and create a package for every non-ignored one
Expand Down Expand Up @@ -205,24 +211,28 @@ export default class Java_maven extends Base_java {
if (useMvnw) {
const mvnw = this.#traverseForMvnw(manifestPath)
if (mvnw !== undefined) {
this._invokeCommand(mvnw, ['--version'], error => {
try {
this._invokeCommand(mvnw, ['--version'])
} catch (error) {
if (error.code === 'ENOENT') {
useMvnw = false
} else {
throw new Error(`failed to check for mvnw`, {cause: error})
}
})
}
mvn = useMvnw ? mvnw : mvn
}
} else {
// verify maven is accessible
this._invokeCommand(mvn, ['--version'], error => {
try {
this._invokeCommand(mvn, ['--version'])
} catch (error) {
if (error.code === 'ENOENT') {
throw new Error(`maven not accessible at "${mvn}"`)
} else {
throw new Error(`failed to check for maven`, {cause: error})
}
})
}
}
return mvn
}
Expand Down
27 changes: 8 additions & 19 deletions src/tools.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,42 +106,31 @@ function hasSpaces(path) {
return path.trim().includes(" ")
}


/**
*
* @param {string} cwd - directory for which to find the root of the git repository.
*/
export function getGitRootDir(cwd) {
const root = invokeCommand('git', ['rev-parse', '--show-toplevel'], () => {}, {cwd: cwd})
if (!root) {
try {
const root = invokeCommand('git', ['rev-parse', '--show-toplevel'], {cwd: cwd})
return root.toString().trim()
} catch (error) {
return undefined
}
return root.toString().trim()
}

/** this method invokes command string in a process in a synchronous way.
* @param {string} bin - the command to be invoked
* @param {Array<string>} args - the args to pass to the binary
* @param callback - function to invoke if an error was thrown
* @protected
*/
export function invokeCommand(bin, args, callback, opts={}) {
export function invokeCommand(bin, args, opts={}) {
// .bat and .cmd files can't be executed in windows with execFileSync, so we special case them
// to use execSync here to keep the amount of escaping we need to do to a minimum.
// https://nodejs.org/docs/latest-v20.x/api/child_process.html#spawning-bat-and-cmd-files-on-windows
if (process.platform === 'win32' && (bin.endsWith(".bat") || bin.endsWith(".cmd"))) {
try {
args = args.map(arg => handleSpacesInPath(arg))
return execSync(`${handleSpacesInPath(bin)} ${args.join(" ")}`, {...{stdio: 'pipe'}, ...opts})
} catch(error) {
callback(error)
}
return
args = args.map(arg => handleSpacesInPath(arg))
return execSync(`${handleSpacesInPath(bin)} ${args.join(" ")}`, {...{stdio: 'pipe', encoding: 'utf-8'}, ...opts})
}

try {
return execFileSync(bin, args, {...{stdio: 'pipe'}, ...opts})
} catch(error) {
callback(error)
}
return execFileSync(bin, args, {...{stdio: 'pipe', encoding: 'utf-8'}, ...opts})
}
Loading