Skip to content

Commit a79bd5a

Browse files
committed
chore: use bun semver
1 parent 312254a commit a79bd5a

File tree

3 files changed

+62
-63
lines changed

3 files changed

+62
-63
lines changed

src/buddy.ts

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,12 @@ export class Buddy {
422422
// const originalPrefix = prefixMatch ? prefixMatch[1] : ''
423423
const constraintVersion = dep.constraint.replace(/^[\^~>=<]+/, '')
424424

425+
// Ensure we only propose upgrades, never downgrades
426+
if (!this.isNewerVersion(constraintVersion, dep.version)) {
427+
this.logger.debug(`Skipping ${dep.name} - latest (${dep.version}) is not newer than constraint (${constraintVersion})`)
428+
continue
429+
}
430+
425431
// Determine update type
426432
const updateType = this.getUpdateType(constraintVersion, dep.version)
427433

@@ -552,27 +558,31 @@ export class Buddy {
552558
const cleanCurrent = current.replace(/^[v^~>=<@]+/, '')
553559
const cleanLatest = latest.replace(/^[v^~>=<@]+/, '')
554560

555-
const currentParts = cleanCurrent.split('.').map((part) => {
556-
const num = Number(part)
557-
return Number.isNaN(num) ? 0 : num
558-
})
559-
const latestParts = cleanLatest.split('.').map((part) => {
560-
const num = Number(part)
561-
return Number.isNaN(num) ? 0 : num
562-
})
561+
if (Bun.semver.order(cleanLatest, cleanCurrent) <= 0)
562+
return 'patch'
563563

564-
// Ensure we have at least major.minor.patch structure
565-
while (currentParts.length < 3) currentParts.push(0)
566-
while (latestParts.length < 3) latestParts.push(0)
564+
if (Bun.semver.satisfies(cleanLatest, `~${cleanCurrent}`))
565+
return 'patch'
567566

568-
if (latestParts[0] > currentParts[0])
569-
return 'major'
570-
if (latestParts[0] === currentParts[0] && latestParts[1] > currentParts[1])
567+
if (Bun.semver.satisfies(cleanLatest, `^${cleanCurrent}`))
571568
return 'minor'
569+
570+
return 'major'
571+
}
572+
catch {
572573
return 'patch'
573574
}
575+
}
576+
577+
/**
578+
* Check if latest version is strictly newer than current
579+
*/
580+
private isNewerVersion(current: string, latest: string): boolean {
581+
try {
582+
return Bun.semver.order(latest.replace(/^[v^~>=<@]+/, ''), current.replace(/^[v^~>=<@]+/, '')) > 0
583+
}
574584
catch {
575-
return 'patch' // Default to patch if parsing fails
585+
return false
576586
}
577587
}
578588

src/pr/pr-generator.ts

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -969,31 +969,21 @@ export class PullRequestGenerator {
969969
const cleanCurrent = currentVersion.replace(/^[v^~>=<@]+/, '')
970970
const cleanNew = newVersion.replace(/^[v^~>=<@]+/, '')
971971

972-
const currentParts = cleanCurrent.split('.').map((part) => {
973-
const num = Number(part)
974-
return Number.isNaN(num) ? 0 : num
975-
})
976-
const newParts = cleanNew.split('.').map((part) => {
977-
const num = Number(part)
978-
return Number.isNaN(num) ? 0 : num
979-
})
972+
try {
973+
if (Bun.semver.order(cleanNew, cleanCurrent) <= 0)
974+
return 'patch'
980975

981-
// Ensure we have at least major.minor.patch structure
982-
while (currentParts.length < 3) currentParts.push(0)
983-
while (newParts.length < 3) newParts.push(0)
976+
if (Bun.semver.satisfies(cleanNew, `~${cleanCurrent}`))
977+
return 'patch'
984978

985-
// Compare major version
986-
if (newParts[0] > currentParts[0]) {
987-
return 'major'
979+
if (Bun.semver.satisfies(cleanNew, `^${cleanCurrent}`))
980+
return 'minor'
988981
}
989-
990-
// Compare minor version
991-
if (newParts[0] === currentParts[0] && newParts[1] > currentParts[1]) {
992-
return 'minor'
982+
catch {
983+
return 'patch'
993984
}
994985

995-
// Everything else is patch
996-
return 'patch'
986+
return 'major'
997987
}
998988

999989
/**

src/utils/helpers.ts

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -305,45 +305,44 @@ export function getUpdateType(currentVersion: string, newVersion: string): 'majo
305305
const cleanCurrent = currentVersion.replace(/^[v^~>=<@]+/, '')
306306
const cleanNew = newVersion.replace(/^[v^~>=<@]+/, '')
307307

308-
// Handle version ranges with @ (like @1.1, @1, etc.)
309-
// For @1.1 -> 3.5.0, current should be interpreted as 1.1
310-
const currentParts = cleanCurrent.split('.').map((part) => {
311-
const num = Number(part)
312-
return Number.isNaN(num) ? 0 : num
313-
})
314-
const newParts = cleanNew.split('.').map((part) => {
315-
const num = Number(part)
316-
return Number.isNaN(num) ? 0 : num
317-
})
318-
319-
// Ensure we have at least major.minor.patch structure
320-
while (currentParts.length < 3) currentParts.push(0)
321-
while (newParts.length < 3) newParts.push(0)
308+
// If not an upgrade or equal, treat as patch (no-op or bugfix)
309+
try {
310+
if (Bun.semver.order(cleanNew, cleanCurrent) <= 0)
311+
return 'patch'
312+
}
313+
catch {
314+
// Fallback to patch if semver fails
315+
return 'patch'
316+
}
322317

323-
// Compare major version
324-
if (newParts[0] > currentParts[0]) {
325-
return 'major'
318+
// Patch: within same minor series
319+
try {
320+
if (Bun.semver.satisfies(cleanNew, `~${cleanCurrent}`))
321+
return 'patch'
326322
}
323+
catch {}
327324

328-
// Compare minor version
329-
if (newParts[0] === currentParts[0] && newParts[1] > currentParts[1]) {
330-
return 'minor'
325+
// Minor: within same major series
326+
try {
327+
if (Bun.semver.satisfies(cleanNew, `^${cleanCurrent}`))
328+
return 'minor'
331329
}
330+
catch {}
332331

333-
// Everything else is patch
334-
return 'patch'
332+
// Otherwise major
333+
return 'major'
335334
}
336335

337336
/**
338337
* Check if version satisfies semver range
339338
*/
340339
export function satisfiesRange(version: string, range: string): boolean {
341-
// This is a simplified implementation
342-
// In production, use a proper semver library
343-
const cleanVersion = version.replace(/^[\^~>=<]+/, '')
344-
const cleanRange = range.replace(/^[\^~>=<]+/, '')
345-
346-
return cleanVersion === cleanRange
340+
try {
341+
return Bun.semver.satisfies(version, range)
342+
}
343+
catch {
344+
return false
345+
}
347346
}
348347

349348
/**

0 commit comments

Comments
 (0)