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
49 changes: 49 additions & 0 deletions depsynky/src/__tests__/bump.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,4 +160,53 @@ describe('bumpVersion', () => {
// dependency should NOT be updated because sync is false
expect(pkgB.dependencies?.['pkg-a']).toBe('^1.0.0')
})

test('does not bump dependent when the link is devDependency', async () => {
const { app, pkg } = buildApp(
{
packages: [
{ name: 'pkg-a', version: '1.0.0' },
{ name: 'pkg-b', version: '1.0.0', devDependencies: { 'pkg-a': 'workspace:*' } },
{ name: 'pkg-c', version: '1.0.0', devDependencies: { 'pkg-a': '^1.0.0' } }
]
},
async () => 'patch'
)

await app.bumpVersion({ pkgName: 'pkg-a', sync: true })

const pkgA = await pkg.read('pkg-a')
const pkgB = await pkg.read('pkg-b')
const pkgC = await pkg.read('pkg-c')

expect(pkgA.version).toBe('1.0.1')
expect(pkgB.version).toBe('1.0.0')
expect(pkgC.version).toBe('1.0.0')

expect(pkgB.devDependencies?.['pkg-a']).toBe('workspace:*')
expect(pkgC.devDependencies?.['pkg-a']).toBe('^1.0.1') // synced but not bumped
})

test('does not bump recursive dependents when "none" is picked', async () => {
const { app, pkg } = buildApp(
{
packages: [
{ name: 'pkg-a', version: '1.0.0' },
{ name: 'pkg-b', version: '1.0.0', dependencies: { 'pkg-a': '1.0.0' } },
{ name: 'pkg-c', version: '1.0.0', dependencies: { 'pkg-b': '1.0.0' } }
]
},
async ({ pkgName }) => (pkgName === 'pkg-b' ? 'none' : 'patch')
)

await app.bumpVersion({ pkgName: 'pkg-a', sync: true })

const pkgA = await pkg.read('pkg-a')
const pkgB = await pkg.read('pkg-b')
const pkgC = await pkg.read('pkg-c')

expect(pkgA.version).toBe('1.0.1')
expect(pkgB.version).toBe('1.0.0')
expect(pkgC.version).toBe('1.0.0') // not bumped because pkg-b was not bumped
})
})
28 changes: 21 additions & 7 deletions depsynky/src/application/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,21 @@ export class DepSynkyApplication {
) {}

public async bumpVersion(args: BumpVersionArgs) {
let pkgName = args.pkgName
const { dependency } = await this._pnpm.findDirectReferences(args.pkgName)

const { dependency, dependents } = await this._pnpm.findRecursiveReferences(pkgName)
const targetPackages = [dependency, ...dependents]
const allPackages = await this._pnpm.searchWorkspaces()
const targetVersions = this._pnpmVersions(allPackages)

const visited = new Set<string>()
const queue: types.PnpmWorkspace[] = [dependency]

const currentVersions = this._pnpmVersions(targetPackages)
const targetVersions = { ...currentVersions }
while (queue.length > 0) {
const { path: pkgPath, content } = queue.shift()!
if (visited.has(content.name)) {
continue
}
visited.add(content.name)

for (const { path: pkgPath, content } of targetPackages) {
if (content.private) {
continue // no need to bump the version of private packages
}
Expand All @@ -61,12 +67,20 @@ export class DepSynkyApplication {

targetVersions[content.name] = next
await this._pkgJson.update(pkgPath, { version: next })

// only follow dependents of packages that were actually bumped
const { dependents } = await this._pnpm.findDirectReferences(content.name)
for (const dep of dependents) {
if (!visited.has(dep.content.name)) {
queue.push(dep)
}
}
}

await this.listVersions()
if (args.sync) {
logger.info('Syncing versions...')
this.syncVersions({ ...args, targetVersions })
await this.syncVersions({ ...args, targetVersions })
}
}

Expand Down
8 changes: 2 additions & 6 deletions depsynky/src/application/pnpm-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,8 @@ export class PnpmWorkspaceService implements types.PnpmService {
public isLocalVersion = (version: string) => version.startsWith(LOCAL_VERSION_PREFIX)

private _findDirectDependents = (workspaces: types.PnpmWorkspace[], pkgName: string): types.PnpmWorkspace[] => {
return workspaces.filter(
(w) =>
w.content.dependencies?.[pkgName] ||
w.content.devDependencies?.[pkgName] ||
w.content.peerDependencies?.[pkgName]
)
// devDependencies are'nt considered as real dependencies for the purpose of bumping versions, so we ignore them here
return workspaces.filter((w) => w.content.dependencies?.[pkgName] || w.content.peerDependencies?.[pkgName])
}

public listPublicPackages = async (): Promise<string[]> => {
Expand Down
Loading