Skip to content

Commit

Permalink
Merge pull request #126 from lishaduck/ignorepackages
Browse files Browse the repository at this point in the history
feat: allow ignoring workspace members
  • Loading branch information
jeffijoe authored Oct 24, 2024
2 parents 511cf39 + 75218f6 commit 19ac36d
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 34 deletions.
5 changes: 3 additions & 2 deletions src/__tests__/globber.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { join } from 'node:path'
import { createGlobber } from '../globber'

test('returns the current directory as a match', async () => {
const result = await createGlobber().globPackageFiles(process.cwd())
const result = await createGlobber().glob(process.cwd(), 'package.json')
expect(result).toHaveLength(1)
expect(result[0]).toBe(process.cwd() + '/package.json')
expect(result[0]).toBe(join(process.cwd(), 'package.json'))
})
6 changes: 4 additions & 2 deletions src/__tests__/type-syncer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,15 +174,17 @@ function buildSyncer() {
}

workspaces ??= []
const globPromises = workspaces.map((w) => globber.globPackageFiles(w))
const globPromises = workspaces.map((w) =>
globber.glob(w, 'package.json'),
)
const globbed = await Promise.all(globPromises)

return globbed.flat()
}),
}

const globber: IGlobber = {
globPackageFiles: jest.fn(async (pattern) => {
glob: jest.fn(async (pattern, _filename) => {
switch (pattern) {
case 'packages/*':
return [
Expand Down
19 changes: 14 additions & 5 deletions src/__tests__/workspace-resolver.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,23 @@ import {

describe('workspace resolver', () => {
const globber: IGlobber = {
globPackageFiles: jest.fn(async (_root: string) => {
return ['packages/package1', 'packages/package2']
glob: jest.fn(async (_root, filename) => {
if (filename === 'packages/*') {
return ['packages/package1', 'packages/package2', 'packages/package3']
}

if (filename === 'packages/package3') {
return ['packages/package3']
}

return []
}),
}

describe('getWorkspaces', () => {
describe('returns workspaces for all package managers', () => {
const subject = createWorkspaceResolverService({
readFileContents: jest.fn(async (_filePath: string) => {
readFileContents: jest.fn(async (_filePath) => {
return JSON.stringify({
packages: ['packages/*'],
} satisfies PnpmWorkspacesConfig)
Expand Down Expand Up @@ -58,11 +66,12 @@ describe('workspace resolver', () => {
},
},
},
])(`returns $pm workspaces`, async ({ pm, files }) => {
])(`returns $pm workspaces`, async ({ files }) => {
const workspaces = await subject.getWorkspaces(
files['package.json'],
'/',
globber,
['packages/package3'],
)

expect(workspaces).toEqual(['packages/package1', 'packages/package2'])
Expand All @@ -75,7 +84,7 @@ describe('workspace resolver', () => {
}),
})

expect(await subject.getWorkspaces({}, '/', globber)).toEqual([])
expect(await subject.getWorkspaces({}, '/', globber, [])).toEqual([])
})
})
})
Expand Down
1 change: 1 addition & 0 deletions src/config-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ function readCliConfig(flags: ICLIArguments['flags']): ISyncOptions {
return {
ignoreDeps: readValues('ignoredeps', isIgnoreDepConfigValue),
ignorePackages: readValues('ignorepackages'),
ignoreProjects: readValues('ignoreprojects'),
}
}

Expand Down
13 changes: 5 additions & 8 deletions src/globber.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,20 @@ import { uniq } from './util'
*/
export interface IGlobber {
/**
* Globs for `package.json` files.
* Globs for a filename.
*
* @param root
*/
globPackageFiles(root: string): Promise<Array<string>>
glob(root: string, filename: string): Promise<Array<string>>
}

/**
* Creates a globber.
*/
export function createGlobber() {
export function createGlobber(): IGlobber {
return {
async globPackageFiles(
root: string,
file = 'package.json',
): Promise<Array<string>> {
const source = await glob(path.join(root, file), {
async glob(root: string, filename): Promise<Array<string>> {
const source = await glob(path.join(root, filename), {
ignore: '**/node_modules/**',
})

Expand Down
22 changes: 16 additions & 6 deletions src/type-syncer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ import {
uniq,
} from './util'
import { getClosestMatchingVersion } from './versioning'
import type { IWorkspaceResolverService } from './workspace-resolver'
import type {
IWorkspaceResolverService,
IWorkspacesArray,
} from './workspace-resolver'

/**
* Creates a type syncer.
Expand Down Expand Up @@ -53,10 +56,12 @@ export function createTypeSyncer(
flags: ICLIArguments['flags'],
): Promise<ISyncResult> {
const dryRun = !!flags.dry
const [{ file, subPackages }, syncOpts] = await Promise.all([
getManifests(filePath, globber),
configService.readConfig(filePath, flags),
])
const syncOpts = await configService.readConfig(filePath, flags)
const { file, subPackages } = await getManifests(
filePath,
globber,
syncOpts.ignoreProjects ?? [],
)

const syncedFiles: Array<ISyncedFile> = await Promise.all([
syncFile(filePath, file, syncOpts, dryRun),
Expand All @@ -74,12 +79,17 @@ export function createTypeSyncer(
* @param filePath
* @param globber
*/
async function getManifests(filePath: string, globber: IGlobber) {
async function getManifests(
filePath: string,
globber: IGlobber,
ignoredWorkspaces: IWorkspacesArray,
) {
const file = await packageJSONService.readPackageFile(filePath)
const subPackages = await workspaceResolverService.getWorkspaces(
file,
path.dirname(filePath),
globber,
ignoredWorkspaces,
)

return {
Expand Down
8 changes: 7 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { IWorkspacesSection } from './workspace-resolver'
import type { IWorkspacesArray, IWorkspacesSection } from './workspace-resolver'

/**
* The guts of the program.
Expand All @@ -15,10 +15,16 @@ export interface ISyncOptions {
* Ignore certain deps.
*/
ignoreDeps?: Array<IDependencySection>

/**
* Ignore certain packages.
*/
ignorePackages?: Array<string>

/**
* Skip resolution of certain projects in the workspace.
*/
ignoreProjects?: IWorkspacesArray
}

/**
Expand Down
38 changes: 28 additions & 10 deletions src/workspace-resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export interface IWorkspaceResolverService {
packageJson: IPackageFile,
root: string,
globber: IGlobber,
ignored: IWorkspacesArray,
): Promise<IWorkspacesArray>
}

Expand Down Expand Up @@ -98,17 +99,34 @@ export function createWorkspaceResolverService({
readFileContents: typeof fsUtils.readFileContents
}): IWorkspaceResolverService {
return {
getWorkspaces: async (packageJson, root, globber) => {
const workspaces = await getWorkspaces(packageJson, root)
const workspacesArray = ensureWorkspacesArray(workspaces)

const manifests = await Promise.all(
workspacesArray.map(
async (workspace) => await globber.globPackageFiles(workspace),
),
)
getWorkspaces: async (packageJson, root, globber, ignored) => {
const [manifests, ignoredWorkspaces] = await Promise.all([
(async () => {
const workspaces = await getWorkspaces(packageJson, root)
const workspacesArray = ensureWorkspacesArray(workspaces)
const globbedArrays = await Promise.all(
workspacesArray.map(
async (workspace) => await globber.glob(root, workspace),
),
)

return uniq(globbedArrays.flat())
})(),
(async () => {
const ignoredWorkspacesArrays = await Promise.all(
ignored.map(
async (ignoredWorkspace) =>
await globber.glob(root, ignoredWorkspace),
),
)

return uniq(manifests.flat())
return uniq(ignoredWorkspacesArrays.flat())
})(),
])

return manifests.filter(
(manifest) => !ignoredWorkspaces.includes(manifest),
)
},
}

Expand Down

0 comments on commit 19ac36d

Please sign in to comment.