Skip to content

Commit 67927c4

Browse files
Strum355claude
andcommitted
refactor: extract normalizePath and resolveBinary to shared tools.js
Move normalizePath from Base_java class and resolveGradleBinary from java_gradle.js into tools.js as shared standalone functions. Update traverseForWrapper to normalize paths consistently on Windows. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 280323f commit 67927c4

4 files changed

Lines changed: 40 additions & 51 deletions

File tree

src/providers/base_java.js

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,6 @@ export default class Base_Java {
144144

145145
const useWrapper = getWrapperPreference(this.globalBinary, opts)
146146
if (useWrapper) {
147-
const manifestDir = path.dirname(this.normalizePath(manifestPath))
148147
const wrapper = traverseForWrapper(manifestDir, this.localWrapper)
149148
if (wrapper !== undefined) {
150149
try {
@@ -168,8 +167,4 @@ export default class Base_Java {
168167
return toolPath
169168
}
170169

171-
normalizePath(thePath) {
172-
const normalized = path.resolve(thePath).normalize();
173-
return process.platform === 'win32' ? normalized.toLowerCase() : normalized;
174-
}
175170
}

src/providers/java_gradle.js

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import TOML from 'fast-toml'
88

99
import { readLicenseFile } from '../license/license_utils.js'
1010
import Sbom from '../sbom.js'
11-
import { getCustomPath, getWrapperPreference, invokeCommand, traverseForWrapper } from '../tools.js'
11+
import { invokeCommand, resolveBinary } from '../tools.js'
1212
import { filterManifestPathsByDiscoveryIgnore, resolveWorkspaceDiscoveryIgnore } from '../workspace.js'
1313

1414
import Base_java, { ecosystem_gradle } from "./base_java.js";
@@ -476,25 +476,6 @@ const DEFAULT_GRADLE_DISCOVERY_IGNORE = [
476476
'**/.gradle/**',
477477
]
478478

479-
/**
480-
* Resolve the Gradle binary, respecting wrapper preference.
481-
*
482-
* @param {string} startDir - Directory from which to start the wrapper search
483-
* @param {import('../index.js').Options} [opts={}]
484-
* @returns {string} Path to the Gradle binary
485-
*/
486-
function resolveGradleBinary(startDir, opts = {}) {
487-
const localWrapper = 'gradlew' + (process.platform === 'win32' ? '.bat' : '')
488-
const useWrapper = getWrapperPreference('gradle', opts)
489-
if (useWrapper) {
490-
const wrapper = traverseForWrapper(startDir, localWrapper)
491-
if (wrapper !== undefined) {
492-
return wrapper
493-
}
494-
}
495-
return getCustomPath('gradle', opts)
496-
}
497-
498479
/** Gradle init script that emits structured project listing. */
499480
const GRADLE_INIT_SCRIPT = `allprojects {
500481
task daListProjects {
@@ -522,7 +503,8 @@ export async function discoverGradleSubprojects(workspaceRoot, opts = {}) {
522503
return []
523504
}
524505

525-
const gradleBin = resolveGradleBinary(root, opts)
506+
const localWrapper = 'gradlew' + (process.platform === 'win32' ? '.bat' : '')
507+
const gradleBin = resolveBinary('gradle', localWrapper, root, opts)
526508
const manifestPaths = []
527509

528510
const rootBuildKts = path.join(root, 'build.gradle.kts')

src/tools.js

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,17 @@ export function getGitRootDir(cwd) {
139139
}
140140
}
141141

142+
/**
143+
* Normalize a filesystem path, lowercasing on Windows for case-insensitive comparison.
144+
*
145+
* @param {string} thePath
146+
* @returns {string}
147+
*/
148+
export function normalizePath(thePath) {
149+
const normalized = path.resolve(thePath).normalize()
150+
return process.platform === 'win32' ? normalized.toLowerCase() : normalized
151+
}
152+
142153
/**
143154
* Walk up from `startDir` to `repoRoot` looking for an executable wrapper script.
144155
*
@@ -148,7 +159,7 @@ export function getGitRootDir(cwd) {
148159
* @returns {string | undefined}
149160
*/
150161
export function traverseForWrapper(startDir, wrapperName, repoRoot = undefined) {
151-
const currentDir = path.resolve(startDir)
162+
const currentDir = normalizePath(startDir)
152163
repoRoot = repoRoot || getGitRootDir(currentDir) || path.parse(currentDir).root
153164
const wrapperPath = path.join(currentDir, wrapperName)
154165
try {
@@ -167,6 +178,25 @@ export function traverseForWrapper(startDir, wrapperName, repoRoot = undefined)
167178
}
168179
}
169180

181+
/**
182+
* Resolve a build-tool binary, preferring a wrapper when configured.
183+
*
184+
* @param {string} globalBinary - Global binary name (e.g. `mvn`, `gradle`)
185+
* @param {string} localWrapper - Wrapper filename (e.g. `mvnw`, `gradlew.bat`)
186+
* @param {string} startDir - Directory from which to start the wrapper search
187+
* @param {import('./index.js').Options} [opts={}]
188+
* @returns {string} Path to the resolved binary
189+
*/
190+
export function resolveBinary(globalBinary, localWrapper, startDir, opts = {}) {
191+
if (getWrapperPreference(globalBinary, opts)) {
192+
const wrapper = traverseForWrapper(startDir, localWrapper)
193+
if (wrapper !== undefined) {
194+
return wrapper
195+
}
196+
}
197+
return getCustomPath(globalBinary, opts)
198+
}
199+
170200
/** this method invokes command string in a process in a synchronous way.
171201
* @param {string} bin - the command to be invoked
172202
* @param {Array<string>} args - the args to pass to the binary

test/providers/workspace.test.js

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -206,10 +206,7 @@ suite('discoverGradleSubprojects', () => {
206206

207207
const { discoverGradleSubprojects } = await esmock('../../src/providers/java_gradle.js', {
208208
'../../src/tools.js': {
209-
getCustom: () => null,
210-
getCustomPath: () => 'gradle',
211-
getGitRootDir: () => null,
212-
getWrapperPreference: () => false,
209+
resolveBinary: () => 'gradle',
213210
invokeCommand: () => Buffer.from(initScriptOutput),
214211
},
215212
})
@@ -231,10 +228,7 @@ suite('discoverGradleSubprojects', () => {
231228

232229
const { discoverGradleSubprojects } = await esmock('../../src/providers/java_gradle.js', {
233230
'../../src/tools.js': {
234-
getCustom: () => null,
235-
getCustomPath: () => 'gradle',
236-
getGitRootDir: () => null,
237-
getWrapperPreference: () => false,
231+
resolveBinary: () => 'gradle',
238232
invokeCommand: () => Buffer.from(initScriptOutput),
239233
},
240234
})
@@ -256,10 +250,7 @@ suite('discoverGradleSubprojects', () => {
256250

257251
const { discoverGradleSubprojects } = await esmock('../../src/providers/java_gradle.js', {
258252
'../../src/tools.js': {
259-
getCustom: () => null,
260-
getCustomPath: () => 'gradle',
261-
getGitRootDir: () => null,
262-
getWrapperPreference: () => false,
253+
resolveBinary: () => 'gradle',
263254
invokeCommand: () => Buffer.from(initScriptOutput),
264255
},
265256
})
@@ -277,10 +268,7 @@ suite('discoverGradleSubprojects', () => {
277268

278269
const { discoverGradleSubprojects } = await esmock('../../src/providers/java_gradle.js', {
279270
'../../src/tools.js': {
280-
getCustom: () => null,
281-
getCustomPath: () => 'gradle',
282-
getGitRootDir: () => null,
283-
getWrapperPreference: () => false,
271+
resolveBinary: () => 'gradle',
284272
invokeCommand: () => Buffer.from(initScriptOutput),
285273
},
286274
})
@@ -294,10 +282,7 @@ suite('discoverGradleSubprojects', () => {
294282
const root = path.resolve('test/providers/tst_manifests/gradle/gradle_multi_project')
295283
const { discoverGradleSubprojects } = await esmock('../../src/providers/java_gradle.js', {
296284
'../../src/tools.js': {
297-
getCustom: () => null,
298-
getCustomPath: () => 'gradle',
299-
getGitRootDir: () => null,
300-
getWrapperPreference: () => false,
285+
resolveBinary: () => 'gradle',
301286
invokeCommand: () => { throw new Error('gradle not found') },
302287
},
303288
})
@@ -317,10 +302,7 @@ suite('discoverGradleSubprojects', () => {
317302

318303
const { discoverGradleSubprojects } = await esmock('../../src/providers/java_gradle.js', {
319304
'../../src/tools.js': {
320-
getCustom: () => null,
321-
getCustomPath: () => 'gradle',
322-
getGitRootDir: () => null,
323-
getWrapperPreference: () => false,
305+
resolveBinary: () => 'gradle',
324306
invokeCommand: () => Buffer.from(initScriptOutput),
325307
},
326308
})

0 commit comments

Comments
 (0)