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
3 changes: 2 additions & 1 deletion packages/npm/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@
},
"dependencies": {
"@simple-libs/child-process-utils": "^2.0.0",
"@simple-release/core": "workspace:^"
"@simple-release/core": "workspace:^",
"fast-glob": "^3.3.3"
},
"devDependencies": {
"test": "workspace:^"
Expand Down
25 changes: 25 additions & 0 deletions packages/npm/src/workspacesProject.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,30 @@ describe('npm', () => {
})
])
})

it('should parse workspace globs from package.json', async () => {
const { cwd } = await forkProject('npm-workspace-globs', packageJsonIndependentMonorepoProject())
const pkgJsonContent = await fs.readFile(join(cwd, 'package.json'), 'utf-8')
const pkgJson = JSON.parse(pkgJsonContent)

pkgJson.workspaces = [
'packages/*'
]

await fs.writeFile(join(cwd, 'package.json'), JSON.stringify(pkgJson))

const project = new NpmWorkspacesProject({
mode: 'independent',
root: cwd
})
const workspaces = await toArray(project.getProjects())
const manifestPaths = workspaces.map(workspace => workspace.manifest.manifestPath)

expect(manifestPaths).toEqual(expect.arrayContaining([
expect.stringContaining('packages/subproject-1/package.json'),
expect.stringContaining('packages/subproject-2/package.json'),
expect.stringContaining('packages/subproject-3/package.json')
]))
})
})
})
Comment on lines +55 to 80
35 changes: 30 additions & 5 deletions packages/npm/src/workspacesProject.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { join } from 'path'
/* oxlint-disable typescript/no-use-before-define */
import fg from 'fast-glob'
import {
type PackageJsonMonorepoProjectOptions,
type ProjectBumpOptions,
Expand All @@ -17,12 +18,34 @@ export type NpmWorkspacesProjectBumpOptions = ProjectBumpOptions

export type NpmWorkspacesProjectPublishOptions = Omit<PublishOptions, 'workspaces'>

interface NpmWorkspacesConfig {
packages?: string[]
}

async function getPackagesGlobPatterns(manifest: Promise<Record<string, unknown>>) {
const workspaces = (await manifest).workspaces as string[] | NpmWorkspacesConfig | undefined

return Array.isArray(workspaces)
? workspaces
: workspaces?.packages
}

async function* getProjects(options: GetProjectsOptions) {
const workspaces = (await options.manifest.readManifest()).workspaces as string[] | undefined
const { projectPath } = options.manifest
const packagesGlobPatterns = await getPackagesGlobPatterns(
options.manifest.readManifest()
)

if (packagesGlobPatterns) {
for (const globPattern of packagesGlobPatterns) {
const packages = fg.stream(globPattern.replace(/\/?$/, `/${PackageJsonManifest.Filename}`), {
cwd: projectPath,
ignore: NpmWorkspacesProject.GlobIgnore
})

if (workspaces) {
for (const workspacesPath of workspaces) {
yield join(workspacesPath, PackageJsonManifest.Filename)
for await (const packagePath of packages) {
yield packagePath.toString()
}
}
}
}
Expand All @@ -31,6 +54,8 @@ async function* getProjects(options: GetProjectsOptions) {
* A npm workspaces based monorepo project that uses package.json for configuration.
*/
export class NpmWorkspacesProject extends PackageJsonMonorepoProject {
static GlobIgnore = ['**/node_modules/**']

/**
* Creates a npm workspaces based monorepo project.
* @param options
Expand Down
67 changes: 35 additions & 32 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.