@jakubmazanec/carson 0.2.0 → 0.3.0-next.1b2cc9c
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -11
- package/dist/constants.d.ts +2 -1
- package/dist/constants.js +2 -1
- package/dist/constants.js.map +1 -1
- package/dist/template/applyTemplateRenders.d.ts +3 -2
- package/dist/template/applyTemplateRenders.js +5 -6
- package/dist/template/applyTemplateRenders.js.map +1 -1
- package/dist/template/internals/createUsingTemplateRender.js +49 -4
- package/dist/template/internals/createUsingTemplateRender.js.map +1 -1
- package/dist/template/internals/mergeUsingTemplateRender.js +26 -14
- package/dist/template/internals/mergeUsingTemplateRender.js.map +1 -1
- package/dist/workspace/Project.js +19 -14
- package/dist/workspace/Project.js.map +1 -1
- package/dist/workspace/Workspace.d.ts +3 -0
- package/dist/workspace/Workspace.js +29 -19
- package/dist/workspace/Workspace.js.map +1 -1
- package/dist/workspace/internals/containsProject.js +9 -4
- package/dist/workspace/internals/containsProject.js.map +1 -1
- package/dist/workspace/internals/containsWorkspace.d.ts +1 -0
- package/dist/workspace/internals/containsWorkspace.js +14 -0
- package/dist/workspace/internals/containsWorkspace.js.map +1 -0
- package/dist/workspace/internals.d.ts +1 -0
- package/dist/workspace/internals.js +1 -0
- package/dist/workspace/internals.js.map +1 -1
- package/package.json +2 -2
- package/src/constants.ts +2 -1
- package/src/template/applyTemplateRenders.ts +8 -12
- package/src/template/internals/createUsingTemplateRender.ts +42 -2
- package/src/template/internals/mergeUsingTemplateRender.ts +17 -9
- package/src/workspace/Project.ts +21 -12
- package/src/workspace/Workspace.ts +39 -22
- package/src/workspace/internals/containsProject.ts +19 -4
- package/src/workspace/internals/containsWorkspace.ts +24 -0
- package/src/workspace/internals.ts +1 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/workspace/Workspace.ts"],"sourcesContent":["import {ensureEmptyDirectory, findExistingDirectory, isRootPath} from '@jakubmazanec/fs-utils';\nimport {readFile, jsonSchema, packageJsonSchema, type PackageJson} from '@jakubmazanec/zod-utils';\nimport glob from 'fast-glob';\nimport fs from 'fs-extra';\nimport json5 from 'json5';\nimport path from 'node:path';\nimport {z} from 'zod';\n\nimport {\n compareProjectPath,\n containsProject,\n getPackageJsonWorkspaces,\n getRepositoryBranches,\n getRepositoryUrl,\n} from './internals.js';\nimport {Project} from './Project.js';\nimport {saveWorkspaceConfig} from './saveWorkspaceConfig.js';\nimport {workspaceConfigSchema} from './WorkspaceConfig.js';\nimport {type WorkspaceConfig} from './WorkspaceConfig.js';\nimport {type WorkspaceCreateOptions} from './WorkspaceCreateOptions.js';\nimport {type WorkspaceCreateProjectOptions} from './WorkspaceCreateProjectOptions.js';\nimport {WorkspaceDependencies} from './WorkspaceDependencies.js';\nimport {WorkspaceError} from './WorkspaceError.js';\nimport {type WorkspaceFindAndReadOptions} from './WorkspaceFindAndReadOptions.js';\nimport type {WorkspaceOptions} from './WorkspaceOptions.js';\nimport {type WorkspacePackageJson} from './WorkspacePackageJson.js';\nimport type {WorkspaceProjectGlobs} from './WorkspaceProjectGlobs.js';\nimport {type WorkspaceProjects} from './WorkspaceProjects.js';\nimport {type WorkspaceRepository} from './WorkspaceRepository.js';\nimport {type WorkspaceUpdateOptions} from './WorkspaceUpdateOptions.js';\nimport {CARSON_CONFIG_DIRECTORY, WORKSPACE_CONFIG_FILENAME} from '../constants.js';\nimport {applyTemplateRenders} from '../template/applyTemplateRenders.js';\nimport {renderCarsonTemplate} from '../template/renderCarsonTemplate.js';\n\n/**\n * Workspace represent a directory, usually a git repository, that contains {@link Project} instances.\n *\n * @typeParam M If true, the workspace is multi-project workspace (so-called \"monorepo\").\n */\nexport class Workspace<M extends boolean = true> {\n /** Workspace path. */\n readonly path: string;\n\n /** Does the workspace contain a multiple projects? */\n readonly isMultiProject: M;\n\n /** Globs used to find projects. */\n projectGlobs: WorkspaceProjectGlobs<M>;\n\n /** Workspace projects. */\n projects: WorkspaceProjects<M>;\n\n /** Workspace configuration; if it's not found, the default is an empty object. */\n config: WorkspaceConfig;\n\n /** Parsed workspace `package.json` file (if the workspace contains multiple projects); if it's not found, the default is an empty object. */\n packageJson: WorkspacePackageJson<M>;\n\n /** Workspace git repository. */\n repository?: WorkspaceRepository;\n\n /** Dependencies of all projects. */\n dependencies: WorkspaceDependencies<M> = [] as unknown as WorkspaceDependencies<M>;\n\n /** Development dependencies of all projects. */\n devDependencies: WorkspaceDependencies<M> = [] as unknown as WorkspaceDependencies<M>;\n\n /** All dependencies of all projects and workspace dependencies. */\n allDependencies: WorkspaceDependencies<M> = [] as unknown as WorkspaceDependencies<M>;\n\n /** Versions of each dependency. */\n dependencyVersions: Record<string, string[]> = {};\n\n /** Errors found during reading from the file system. */\n errors: Array<InstanceType<typeof WorkspaceError>> = [];\n\n constructor(options: WorkspaceOptions<M>) {\n this.path = options.path;\n\n if (typeof options.isMultiProject === 'undefined' || options.isMultiProject) {\n this.isMultiProject = true as M;\n\n let projectGlobOption = (options as WorkspaceOptions<true>).projectGlobs;\n\n if (projectGlobOption) {\n this.projectGlobs = projectGlobOption as WorkspaceProjectGlobs<M>;\n } else {\n this.projectGlobs = [] as string[] as WorkspaceProjectGlobs<M>;\n }\n\n this.projects = [] as Array<Project<M>> as WorkspaceProjects<M>;\n\n let {projects} = options as WorkspaceOptions<true>;\n\n if (projects) {\n this.addProjects(projects.map((project) => new Project({...project, workspace: this})));\n }\n\n let packageJsonOption = (options as WorkspaceOptions<true>).packageJson;\n\n if (packageJsonOption) {\n this.packageJson = packageJsonOption as M extends true ? PackageJson : null;\n } else {\n let emptyPackageJson: PackageJson = {};\n\n this.packageJson = emptyPackageJson as M extends true ? PackageJson : null;\n }\n } else {\n this.isMultiProject = false as M;\n this.projectGlobs = null as M extends true ? string[] : null;\n this.packageJson = null as M extends true ? PackageJson : null;\n this.projects = [] as Array<Project<M>> as WorkspaceProjects<M>;\n\n let {projects} = options as WorkspaceOptions<false>;\n\n if (projects) {\n this.addProjects(projects.map((project) => new Project({...project, workspace: this})));\n }\n }\n\n let configOption = options.config;\n\n if (configOption) {\n this.config = configOption;\n } else {\n let emptyWorkspaceConfig: WorkspaceConfig = {};\n\n this.config = emptyWorkspaceConfig;\n }\n\n if (options.repository) {\n this.repository = options.repository;\n }\n\n if (options.errors) {\n this.errors = options.errors;\n }\n\n // add missing project globs\n if (this.isMultiProject && !(this.projectGlobs as string[]).length) {\n let packageJsonWorkspaces = getPackageJsonWorkspaces(this.packageJson as PackageJson);\n\n if (packageJsonWorkspaces) {\n this.projectGlobs = [...packageJsonWorkspaces] as M extends true ? string[] : null;\n }\n }\n\n this.sortProjects();\n this.updateDependencies();\n }\n\n /**\n * Creates new workspace within the file system.\n *\n * @param options Options.\n * @returns The new workspace.\n */\n static async create({args, path: workspacePath, templateId}: WorkspaceCreateOptions) {\n // TODO: test that workspace returned by this method has the same value of isMultiProject when the same workspace is after its creation re-read with .read()\n let workspace = new this({\n path: workspacePath,\n config: {\n template: templateId,\n },\n });\n\n try {\n await ensureEmptyDirectory(workspace.path, {allowGit: true});\n } catch {\n throw new WorkspaceError('WORKSPACE_PATH_NOT_EMPTY', {\n messageParameters: [workspace.path],\n data: {\n path: workspace.path,\n },\n });\n }\n\n let templateRenders = await renderCarsonTemplate({\n templateId,\n templateData: {\n workspace,\n args,\n },\n });\n\n await applyTemplateRenders({\n templateRenders,\n path: workspace.path,\n ignoreStrategies: ['check'],\n });\n\n await saveWorkspaceConfig({\n workspacePath: workspace.path,\n workspaceConfig: {template: templateId},\n });\n\n return Workspace.read(workspace.path);\n }\n\n static async read(workspacePath: string): Promise<Workspace | Workspace<false>> {\n let resolvedWorkspacePath = path.resolve(workspacePath);\n\n if (!(await fs.pathExists(resolvedWorkspacePath))) {\n throw new WorkspaceError('NO_SUCH_WORKSPACE_PATH', {\n messageParameters: [resolvedWorkspacePath],\n data: {\n path: resolvedWorkspacePath,\n },\n });\n }\n\n // load root package.json\n let rootPackageJsonPath = path.join(resolvedWorkspacePath, 'package.json');\n let doesRootPackageJsonExist = await fs.pathExists(rootPackageJsonPath);\n let rootPackageJson: PackageJson | z.ZodError;\n\n if (doesRootPackageJsonExist) {\n rootPackageJson = await readFile(rootPackageJsonPath, packageJsonSchema, {\n parser: (rawString: string) => json5.parse<unknown>(rawString),\n });\n } else {\n rootPackageJson = {};\n }\n\n if (rootPackageJson instanceof z.ZodError) {\n rootPackageJson = {};\n\n // even if the package.json file has errors, maybe there's still a correct workspace field\n try {\n let rootJson = await readFile(rootPackageJsonPath, jsonSchema, {\n parser: (rawString: string) => json5.parse<unknown>(rawString),\n throwOnZodError: true,\n });\n let projectGlobs = getPackageJsonWorkspaces(rootJson);\n\n // add back to the empty package.json object\n if (projectGlobs) {\n rootPackageJson.workspaces = projectGlobs;\n }\n } catch {\n // no-op\n }\n }\n\n // add projects\n let projectGlobs = getPackageJsonWorkspaces(rootPackageJson);\n\n // we're dealing with single-project workspace\n if (!projectGlobs) {\n let workspace = new this({\n path: resolvedWorkspacePath,\n isMultiProject: false,\n });\n\n await workspace.read();\n await workspace.readProjects();\n\n return workspace;\n }\n\n // assemble workspace options\n let workspace = new this({\n path: resolvedWorkspacePath,\n isMultiProject: true,\n projectGlobs,\n packageJson: rootPackageJson,\n });\n\n await workspace.read();\n await workspace.readProjects();\n\n return workspace;\n }\n\n /**\n * Traverses file system up from the search path and tries to find a directory that is a root of a workspace.\n */\n static async find(searchPath: string): Promise<string | undefined> {\n let startingPath = await findExistingDirectory(path.resolve(searchPath));\n let currentPath = startingPath;\n let singlePackageWorkspacePath: string | undefined;\n let multiPackageWorkspacePath: string | undefined;\n\n while (\n !(isRootPath(currentPath) || (singlePackageWorkspacePath && multiPackageWorkspacePath))\n ) {\n let packageJsonPath = path.join(currentPath, 'package.json');\n let doesPackageJsonExist = await fs.pathExists(packageJsonPath);\n\n if (doesPackageJsonExist) {\n let packageJson = await readFile(packageJsonPath, jsonSchema, {\n parser: (rawString: string) => json5.parse<unknown>(rawString),\n });\n\n if (!(packageJson instanceof Error)) {\n let projectGlobs = getPackageJsonWorkspaces(packageJson);\n\n if (projectGlobs?.length) {\n multiPackageWorkspacePath ??= currentPath;\n } else {\n singlePackageWorkspacePath ??= currentPath;\n }\n }\n }\n\n currentPath = path.dirname(currentPath);\n }\n\n if (multiPackageWorkspacePath) {\n return multiPackageWorkspacePath;\n } else if (singlePackageWorkspacePath) {\n return singlePackageWorkspacePath;\n }\n\n return undefined;\n }\n\n /**\n * Traverses file system up from the search path and tries to find and read a workspace.\n */\n static async findAndRead<O extends WorkspaceFindAndReadOptions | undefined = undefined>(\n searchPath: string,\n options?: O,\n ): Promise<\n O extends undefined\n ? Workspace | Workspace<false> | undefined\n : NonNullable<O>['throwIfNotFound'] extends true\n ? Workspace | Workspace<false>\n : Workspace | Workspace<false> | undefined\n > {\n let workspacePath = await Workspace.find(searchPath);\n\n if (workspacePath) {\n return Workspace.read(workspacePath) as Promise<\n O extends undefined\n ? Workspace | Workspace<false> | undefined\n : NonNullable<O>['throwIfNotFound'] extends true\n ? Workspace | Workspace<false>\n : Workspace | Workspace<false> | undefined\n >;\n } else if (options?.throwIfNotFound) {\n throw new WorkspaceError('NO_WORKSPACE_FOUND', {\n messageParameters: [searchPath],\n data: {\n path: searchPath,\n },\n });\n }\n\n return undefined as unknown as Promise<\n O extends undefined\n ? Workspace | Workspace<false> | undefined\n : NonNullable<O>['throwIfNotFound'] extends true\n ? Workspace | Workspace<false>\n : Workspace | Workspace<false> | undefined\n >;\n }\n\n async read(): Promise<this> {\n if (!(await fs.pathExists(this.path))) {\n throw new WorkspaceError('NO_SUCH_WORKSPACE_PATH', {\n messageParameters: [this.path],\n data: {\n path: this.path,\n },\n });\n }\n\n let errors: Array<InstanceType<typeof WorkspaceError>> = [];\n let repositoryUrl = await getRepositoryUrl(this.path);\n let repositoryBranches = await getRepositoryBranches(this.path);\n\n // load workspace config\n let workspaceConfigPath = path.join(\n this.path,\n CARSON_CONFIG_DIRECTORY,\n WORKSPACE_CONFIG_FILENAME,\n );\n let doesWorkspaceConfigExist = await fs.pathExists(workspaceConfigPath);\n let workspaceConfig: WorkspaceConfig | z.ZodError;\n\n if (doesWorkspaceConfigExist) {\n workspaceConfig = await readFile(workspaceConfigPath, workspaceConfigSchema, {\n parser: (rawString: string) => json5.parse<unknown>(rawString),\n });\n } else {\n workspaceConfig = {};\n }\n\n if (workspaceConfig instanceof z.ZodError) {\n let zodError = workspaceConfig;\n let workspaceError = new WorkspaceError('INVALID_WORKSPACE_CONFIG', {\n messageParameters: [workspaceConfigPath],\n data: {\n path: workspaceConfigPath,\n zodIssues: zodError.issues,\n },\n });\n\n errors.push(workspaceError);\n\n workspaceConfig = {};\n }\n\n if (this.isMultiProject) {\n // load root package.json\n let rootPackageJsonPath = path.join(this.path, 'package.json');\n let doesRootPackageJsonExist = await fs.pathExists(rootPackageJsonPath);\n let rootPackageJson: PackageJson | z.ZodError;\n\n if (doesRootPackageJsonExist) {\n rootPackageJson = await readFile(rootPackageJsonPath, packageJsonSchema, {\n parser: (rawString: string) => json5.parse<unknown>(rawString),\n });\n } else {\n rootPackageJson = {};\n }\n\n if (rootPackageJson instanceof z.ZodError) {\n let zodError = rootPackageJson;\n let workspaceError = new WorkspaceError('INVALID_PACKAGE_JSON', {\n messageParameters: [rootPackageJsonPath],\n data: {\n path: rootPackageJsonPath,\n zodIssues: zodError.issues,\n },\n });\n\n errors.push(workspaceError);\n\n rootPackageJson = {};\n }\n\n let projectGlobs = getPackageJsonWorkspaces(rootPackageJson);\n\n this.projectGlobs = (projectGlobs ?? []) as WorkspaceProjectGlobs<M>;\n this.packageJson = rootPackageJson as WorkspacePackageJson<M>;\n this.config = workspaceConfig;\n this.errors = errors;\n\n if (repositoryUrl) {\n this.repository = {\n url: repositoryUrl,\n branches: repositoryBranches ?? [],\n };\n } else if (repositoryBranches) {\n this.repository = {\n branches: repositoryBranches,\n };\n }\n\n await this.readProjects();\n\n return this;\n }\n\n // we're dealing with single-project workspace\n this.config = workspaceConfig;\n this.errors = errors;\n\n if (repositoryUrl) {\n this.repository = {\n url: repositoryUrl,\n branches: repositoryBranches ?? [],\n };\n } else if (repositoryBranches) {\n this.repository = {\n branches: repositoryBranches,\n };\n }\n\n await this.readProjects();\n\n return this;\n }\n\n async update({args}: WorkspaceUpdateOptions): Promise<this> {\n if (!this.config.template) {\n throw new WorkspaceError('MISSING_CARSON_TEMPLATE_ID', {\n messageParameters: [\n path.join(this.path, CARSON_CONFIG_DIRECTORY, WORKSPACE_CONFIG_FILENAME),\n ],\n });\n }\n\n let templateRenders = await renderCarsonTemplate({\n templateId: this.config.template,\n templateData: {\n workspace: this,\n args,\n },\n });\n\n await applyTemplateRenders({\n templateRenders,\n path: this.path,\n ignoreStrategies: ['create'],\n });\n\n await this.read();\n\n return this;\n }\n\n getProject(projectName: Project<M> | string): Project<M> | undefined {\n for (let project of this.projects) {\n if (project.name === projectName || project === projectName) {\n return project;\n }\n }\n\n return undefined;\n }\n\n async createProject({\n templateId,\n projectPath,\n projectName,\n args,\n }: WorkspaceCreateProjectOptions): Promise<Project<M>> {\n let resolvedProjectPath = path.resolve(projectPath);\n\n if (this.projects.some((project) => resolvedProjectPath === project.path)) {\n throw new WorkspaceError('DUPLICATE_PROJECT_PATH', {\n messageParameters: [resolvedProjectPath],\n });\n }\n\n if (this.projects.some((project) => projectName === project.name)) {\n throw new WorkspaceError('DUPLICATE_PROJECT_NAME', {messageParameters: [projectName]});\n }\n\n if (!this.isMultiProject && this.projects.length >= 1) {\n throw new WorkspaceError('TOO_MANY_PROJECTS');\n }\n\n if (!this.isMultiProject && projectPath !== this.path) {\n throw new WorkspaceError('PATH_MISMATCH');\n }\n\n let newProject = await Project.create({\n templateId,\n projectPath,\n projectName,\n args,\n workspace: this,\n });\n\n this.addProject(newProject);\n\n return newProject;\n }\n\n addProject(newProject: Project<M>): this {\n if (this.projects.some((project) => newProject.path === project.path)) {\n throw new WorkspaceError('DUPLICATE_PROJECT_PATH', {\n messageParameters: [newProject.path],\n });\n }\n\n if (this.projects.some((project) => newProject.name === project.name)) {\n throw new WorkspaceError('DUPLICATE_PROJECT_NAME', {messageParameters: [newProject.name]});\n }\n\n if (!this.isMultiProject && this.projects.length >= 1) {\n throw new WorkspaceError('TOO_MANY_PROJECTS');\n }\n\n if (!this.isMultiProject && newProject.path !== this.path) {\n throw new WorkspaceError('PATH_MISMATCH');\n }\n\n this.projects.push(newProject);\n this.sortProjects();\n this.updateDependencies();\n\n return this;\n }\n\n addProjects(newProjects: Array<Project<M>>): this {\n for (let newProject of newProjects) {\n if (this.projects.some((project) => newProject.path === project.path)) {\n throw new WorkspaceError('DUPLICATE_PROJECT_PATH', {\n messageParameters: [newProject.path],\n });\n }\n\n if (this.projects.some((project) => newProject.name === project.name)) {\n throw new WorkspaceError('DUPLICATE_PROJECT_NAME', {messageParameters: [newProject.name]});\n }\n\n if (!this.isMultiProject && this.projects.length >= 1) {\n throw new WorkspaceError('TOO_MANY_PROJECTS');\n }\n\n if (!this.isMultiProject && newProject.path !== this.path) {\n throw new WorkspaceError('PATH_MISMATCH');\n }\n\n this.projects.push(newProject);\n }\n\n this.sortProjects();\n this.updateDependencies();\n\n return this;\n }\n\n async readProjects(): Promise<Array<Project<M>>> {\n if (this.projectGlobs) {\n let projects: Array<Project<M>> = [];\n let packagePaths = await glob(this.projectGlobs, {\n cwd: this.path,\n onlyDirectories: true,\n });\n\n for (let packagePath of packagePaths) {\n let projectPath = path.join(this.path, packagePath);\n\n if (await containsProject(projectPath)) {\n let project = await Project.read(projectPath, this);\n\n projects.push(project);\n }\n }\n\n this.projects = projects;\n } else {\n this.projects = [await Project.read(this.path, this)];\n }\n\n this.sortProjects();\n this.updateDependencies();\n\n return this.projects;\n }\n\n protected sortProjects(): void {\n this.projects.sort(compareProjectPath);\n }\n\n protected updateDependencies(): void {\n this.dependencies = WorkspaceDependencies.fromWorkspace(this);\n this.devDependencies = WorkspaceDependencies.fromWorkspace(this, {\n includeOnlyDevDependencies: true,\n });\n this.allDependencies = WorkspaceDependencies.fromWorkspace(this, {\n includeDevDependencies: true,\n includeWorkspaceDependencies: true,\n });\n this.dependencyVersions = this.allDependencies.getVersions({\n useExactVersions: true,\n });\n }\n}\n"],"names":["ensureEmptyDirectory","findExistingDirectory","isRootPath","readFile","jsonSchema","packageJsonSchema","glob","fs","json5","path","z","compareProjectPath","containsProject","getPackageJsonWorkspaces","getRepositoryBranches","getRepositoryUrl","Project","saveWorkspaceConfig","workspaceConfigSchema","WorkspaceDependencies","WorkspaceError","CARSON_CONFIG_DIRECTORY","WORKSPACE_CONFIG_FILENAME","applyTemplateRenders","renderCarsonTemplate","Workspace","isMultiProject","projectGlobs","projects","config","packageJson","repository","dependencies","devDependencies","allDependencies","dependencyVersions","errors","constructor","options","projectGlobOption","addProjects","map","project","workspace","packageJsonOption","emptyPackageJson","configOption","emptyWorkspaceConfig","length","packageJsonWorkspaces","sortProjects","updateDependencies","create","args","workspacePath","templateId","template","allowGit","messageParameters","data","templateRenders","templateData","ignoreStrategies","workspaceConfig","read","resolvedWorkspacePath","resolve","pathExists","rootPackageJsonPath","join","doesRootPackageJsonExist","rootPackageJson","parser","rawString","parse","ZodError","rootJson","throwOnZodError","workspaces","readProjects","find","searchPath","startingPath","currentPath","singlePackageWorkspacePath","multiPackageWorkspacePath","packageJsonPath","doesPackageJsonExist","Error","dirname","undefined","findAndRead","throwIfNotFound","repositoryUrl","repositoryBranches","workspaceConfigPath","doesWorkspaceConfigExist","zodError","workspaceError","zodIssues","issues","push","url","branches","update","getProject","projectName","name","createProject","projectPath","resolvedProjectPath","some","newProject","addProject","newProjects","packagePaths","cwd","onlyDirectories","packagePath","sort","fromWorkspace","includeOnlyDevDependencies","includeDevDependencies","includeWorkspaceDependencies","getVersions","useExactVersions"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/workspace/Workspace.ts"],"sourcesContent":["import {ensureEmptyDirectory, findExistingDirectory, isRootPath} from '@jakubmazanec/fs-utils';\nimport {readFile, jsonSchema, packageJsonSchema, type PackageJson} from '@jakubmazanec/zod-utils';\nimport glob from 'fast-glob';\nimport fs from 'fs-extra';\nimport json5 from 'json5';\nimport path from 'node:path';\nimport {z} from 'zod';\n\nimport {\n compareProjectPath,\n containsProject,\n containsWorkspace,\n getPackageJsonWorkspaces,\n getRepositoryBranches,\n getRepositoryUrl,\n} from './internals.js';\nimport {Project} from './Project.js';\nimport {saveWorkspaceConfig} from './saveWorkspaceConfig.js';\nimport {workspaceConfigSchema} from './WorkspaceConfig.js';\nimport {type WorkspaceConfig} from './WorkspaceConfig.js';\nimport {type WorkspaceCreateOptions} from './WorkspaceCreateOptions.js';\nimport {type WorkspaceCreateProjectOptions} from './WorkspaceCreateProjectOptions.js';\nimport {WorkspaceDependencies} from './WorkspaceDependencies.js';\nimport {WorkspaceError} from './WorkspaceError.js';\nimport {type WorkspaceFindAndReadOptions} from './WorkspaceFindAndReadOptions.js';\nimport type {WorkspaceOptions} from './WorkspaceOptions.js';\nimport {type WorkspacePackageJson} from './WorkspacePackageJson.js';\nimport type {WorkspaceProjectGlobs} from './WorkspaceProjectGlobs.js';\nimport {type WorkspaceProjects} from './WorkspaceProjects.js';\nimport {type WorkspaceRepository} from './WorkspaceRepository.js';\nimport {type WorkspaceUpdateOptions} from './WorkspaceUpdateOptions.js';\nimport {\n CARSON_CONFIG_DIRECTORY,\n WORKSPACE_CONFIG_FILENAME,\n PACKAGE_JSON_FILENAME,\n WORKSPACE_SNAPSHOT_FILENAME,\n} from '../constants.js';\nimport {applyTemplateRenders} from '../template/applyTemplateRenders.js';\nimport {renderCarsonTemplate} from '../template/renderCarsonTemplate.js';\n\n/**\n * Workspace represent a directory, usually a git repository, that contains {@link Project} instances.\n *\n * @typeParam M If true, the workspace is multi-project workspace (so-called \"monorepo\").\n */\nexport class Workspace<M extends boolean = true> {\n /** Workspace path. */\n readonly path: string;\n\n /** Does the workspace contain a multiple projects? */\n readonly isMultiProject: M;\n\n /** Globs used to find projects. */\n projectGlobs: WorkspaceProjectGlobs<M>;\n\n /** Workspace projects. */\n projects: WorkspaceProjects<M>;\n\n /** Workspace configuration; if it's not found, the default is an empty object. */\n config: WorkspaceConfig;\n\n /** Parsed workspace `package.json` file (if the workspace contains multiple projects); if it's not found, the default is an empty object. */\n packageJson: WorkspacePackageJson<M>;\n\n /** Workspace git repository. */\n repository?: WorkspaceRepository;\n\n /** Dependencies of all projects. */\n dependencies: WorkspaceDependencies<M> = [] as unknown as WorkspaceDependencies<M>;\n\n /** Development dependencies of all projects. */\n devDependencies: WorkspaceDependencies<M> = [] as unknown as WorkspaceDependencies<M>;\n\n /** All dependencies of all projects and workspace dependencies. */\n allDependencies: WorkspaceDependencies<M> = [] as unknown as WorkspaceDependencies<M>;\n\n /** Versions of each dependency. */\n dependencyVersions: Record<string, string[]> = {};\n\n /** Errors found during reading from the file system. */\n errors: Array<InstanceType<typeof WorkspaceError>> = [];\n\n constructor(options: WorkspaceOptions<M>) {\n this.path = options.path;\n\n if (typeof options.isMultiProject === 'undefined' || options.isMultiProject) {\n this.isMultiProject = true as M;\n\n let projectGlobOption = (options as WorkspaceOptions<true>).projectGlobs;\n\n if (projectGlobOption) {\n this.projectGlobs = projectGlobOption as WorkspaceProjectGlobs<M>;\n } else {\n this.projectGlobs = [] as string[] as WorkspaceProjectGlobs<M>;\n }\n\n this.projects = [] as Array<Project<M>> as WorkspaceProjects<M>;\n\n let {projects} = options as WorkspaceOptions<true>;\n\n if (projects) {\n this.addProjects(projects.map((project) => new Project({...project, workspace: this})));\n }\n\n let packageJsonOption = (options as WorkspaceOptions<true>).packageJson;\n\n if (packageJsonOption) {\n this.packageJson = packageJsonOption as M extends true ? PackageJson : null;\n } else {\n let emptyPackageJson: PackageJson = {};\n\n this.packageJson = emptyPackageJson as M extends true ? PackageJson : null;\n }\n } else {\n this.isMultiProject = false as M;\n this.projectGlobs = null as M extends true ? string[] : null;\n this.packageJson = null as M extends true ? PackageJson : null;\n this.projects = [] as Array<Project<M>> as WorkspaceProjects<M>;\n\n let {projects} = options as WorkspaceOptions<false>;\n\n if (projects) {\n this.addProjects(projects.map((project) => new Project({...project, workspace: this})));\n }\n }\n\n let configOption = options.config;\n\n if (configOption) {\n this.config = configOption;\n } else {\n let emptyWorkspaceConfig: WorkspaceConfig = {};\n\n this.config = emptyWorkspaceConfig;\n }\n\n if (options.repository) {\n this.repository = options.repository;\n }\n\n if (options.errors) {\n this.errors = options.errors;\n }\n\n // add missing project globs\n if (this.isMultiProject && !(this.projectGlobs as string[]).length) {\n let packageJsonWorkspaces = getPackageJsonWorkspaces(this.packageJson as PackageJson);\n\n if (packageJsonWorkspaces) {\n this.projectGlobs = [...packageJsonWorkspaces] as M extends true ? string[] : null;\n }\n }\n\n this.sortProjects();\n this.updateDependencies();\n }\n\n /**\n * Creates new workspace within the file system.\n *\n * @param options Options.\n * @returns The new workspace.\n */\n static async create({args, path: workspacePath, templateId}: WorkspaceCreateOptions) {\n // TODO: test that workspace returned by this method has the same value of isMultiProject when the same workspace is after its creation re-read with .read()\n let workspace = new this({\n path: workspacePath,\n config: {\n template: templateId,\n },\n });\n\n try {\n await ensureEmptyDirectory(workspace.path, {allowGit: true});\n } catch {\n throw new WorkspaceError('WORKSPACE_PATH_NOT_EMPTY', {\n messageParameters: [workspace.path],\n data: {\n path: workspace.path,\n },\n });\n }\n\n let templateRenders = await renderCarsonTemplate({\n templateId,\n templateData: {\n workspace,\n args,\n },\n });\n\n await applyTemplateRenders({\n templateRenders,\n targetPath: workspace.path,\n snapshotPath: path.join(workspace.path, CARSON_CONFIG_DIRECTORY, WORKSPACE_SNAPSHOT_FILENAME),\n ignoreStrategies: ['check'],\n });\n\n await saveWorkspaceConfig({\n workspacePath: workspace.path,\n workspaceConfig: {template: templateId},\n });\n\n return Workspace.read(workspace.path);\n }\n\n static async read(workspacePath: string): Promise<Workspace | Workspace<false>> {\n let resolvedWorkspacePath = path.resolve(workspacePath);\n\n if (!(await fs.pathExists(resolvedWorkspacePath))) {\n throw new WorkspaceError('NO_SUCH_WORKSPACE_PATH', {\n messageParameters: [resolvedWorkspacePath],\n data: {\n path: resolvedWorkspacePath,\n },\n });\n }\n\n // load root package.json\n let rootPackageJsonPath = path.join(resolvedWorkspacePath, 'package.json');\n let doesRootPackageJsonExist = await fs.pathExists(rootPackageJsonPath);\n let rootPackageJson: PackageJson | z.ZodError;\n\n if (doesRootPackageJsonExist) {\n rootPackageJson = await readFile(rootPackageJsonPath, packageJsonSchema, {\n parser: (rawString: string) => json5.parse<unknown>(rawString),\n });\n } else {\n rootPackageJson = {};\n }\n\n if (rootPackageJson instanceof z.ZodError) {\n rootPackageJson = {};\n\n // even if the package.json file has errors, maybe there's still a correct workspace field\n try {\n let rootJson = await readFile(rootPackageJsonPath, jsonSchema, {\n parser: (rawString: string) => json5.parse<unknown>(rawString),\n throwOnZodError: true,\n });\n let projectGlobs = getPackageJsonWorkspaces(rootJson);\n\n // add back to the empty package.json object\n if (projectGlobs) {\n rootPackageJson.workspaces = projectGlobs;\n }\n } catch {\n // no-op\n }\n }\n\n // add projects\n let projectGlobs = getPackageJsonWorkspaces(rootPackageJson);\n\n // we're dealing with single-project workspace\n if (!projectGlobs) {\n let workspace = new this({\n path: resolvedWorkspacePath,\n isMultiProject: false,\n });\n\n await workspace.read();\n await workspace.readProjects();\n\n return workspace;\n }\n\n // assemble workspace options\n let workspace = new this({\n path: resolvedWorkspacePath,\n isMultiProject: true,\n projectGlobs,\n packageJson: rootPackageJson,\n });\n\n await workspace.read();\n await workspace.readProjects();\n\n return workspace;\n }\n\n /**\n * Traverses file system up from the search path and tries to find a directory that is a root of a workspace.\n *\n * @param searchPath Search path.\n * @returns Workspace path, if found.\n */\n static async find(searchPath: string): Promise<string | undefined> {\n let startingPath = await findExistingDirectory(path.resolve(searchPath));\n let currentPath = startingPath;\n let singlePackageWorkspacePath: string | undefined;\n let multiPackageWorkspacePath: string | undefined;\n\n while (\n !(isRootPath(currentPath) || (singlePackageWorkspacePath && multiPackageWorkspacePath))\n ) {\n if (await containsWorkspace(currentPath)) {\n const packageJsonPath = path.join(currentPath, PACKAGE_JSON_FILENAME);\n\n if (await fs.pathExists(packageJsonPath)) {\n const packageJson = await readFile(packageJsonPath, jsonSchema, {\n parser: (rawString: string) => json5.parse<unknown>(rawString),\n });\n\n if (!(packageJson instanceof Error)) {\n const projectGlobs = getPackageJsonWorkspaces(packageJson);\n\n if (projectGlobs?.length) {\n multiPackageWorkspacePath ??= currentPath;\n } else {\n singlePackageWorkspacePath ??= currentPath;\n }\n }\n } else {\n singlePackageWorkspacePath ??= currentPath;\n }\n }\n\n currentPath = path.dirname(currentPath);\n }\n\n if (multiPackageWorkspacePath) {\n return multiPackageWorkspacePath;\n } else if (singlePackageWorkspacePath) {\n return singlePackageWorkspacePath;\n }\n\n return undefined;\n }\n\n /**\n * Traverses file system up from the search path and tries to find and read a workspace.\n */\n static async findAndRead<O extends WorkspaceFindAndReadOptions | undefined = undefined>(\n searchPath: string,\n options?: O,\n ): Promise<\n O extends undefined\n ? Workspace | Workspace<false> | undefined\n : NonNullable<O>['throwIfNotFound'] extends true\n ? Workspace | Workspace<false>\n : Workspace | Workspace<false> | undefined\n > {\n let workspacePath = await Workspace.find(searchPath);\n\n if (workspacePath) {\n return Workspace.read(workspacePath) as Promise<\n O extends undefined\n ? Workspace | Workspace<false> | undefined\n : NonNullable<O>['throwIfNotFound'] extends true\n ? Workspace | Workspace<false>\n : Workspace | Workspace<false> | undefined\n >;\n } else if (options?.throwIfNotFound) {\n throw new WorkspaceError('NO_WORKSPACE_FOUND', {\n messageParameters: [searchPath],\n data: {\n path: searchPath,\n },\n });\n }\n\n return undefined as unknown as Promise<\n O extends undefined\n ? Workspace | Workspace<false> | undefined\n : NonNullable<O>['throwIfNotFound'] extends true\n ? Workspace | Workspace<false>\n : Workspace | Workspace<false> | undefined\n >;\n }\n\n async read(): Promise<this> {\n if (!(await fs.pathExists(this.path))) {\n throw new WorkspaceError('NO_SUCH_WORKSPACE_PATH', {\n messageParameters: [this.path],\n data: {\n path: this.path,\n },\n });\n }\n\n let errors: Array<InstanceType<typeof WorkspaceError>> = [];\n let repositoryUrl = await getRepositoryUrl(this.path);\n let repositoryBranches = await getRepositoryBranches(this.path);\n\n // load workspace config\n let workspaceConfigPath = path.join(\n this.path,\n CARSON_CONFIG_DIRECTORY,\n WORKSPACE_CONFIG_FILENAME,\n );\n let doesWorkspaceConfigExist = await fs.pathExists(workspaceConfigPath);\n let workspaceConfig: WorkspaceConfig | z.ZodError;\n\n if (doesWorkspaceConfigExist) {\n workspaceConfig = await readFile(workspaceConfigPath, workspaceConfigSchema, {\n parser: (rawString: string) => json5.parse<unknown>(rawString),\n });\n } else {\n workspaceConfig = {};\n }\n\n if (workspaceConfig instanceof z.ZodError) {\n let zodError = workspaceConfig;\n let workspaceError = new WorkspaceError('INVALID_WORKSPACE_CONFIG', {\n messageParameters: [workspaceConfigPath],\n data: {\n path: workspaceConfigPath,\n zodIssues: zodError.issues,\n },\n });\n\n errors.push(workspaceError);\n\n workspaceConfig = {};\n }\n\n if (this.isMultiProject) {\n // load root package.json\n let rootPackageJsonPath = path.join(this.path, 'package.json');\n let doesRootPackageJsonExist = await fs.pathExists(rootPackageJsonPath);\n let rootPackageJson: PackageJson | z.ZodError;\n\n if (doesRootPackageJsonExist) {\n rootPackageJson = await readFile(rootPackageJsonPath, packageJsonSchema, {\n parser: (rawString: string) => json5.parse<unknown>(rawString),\n });\n } else {\n rootPackageJson = {};\n }\n\n if (rootPackageJson instanceof z.ZodError) {\n let zodError = rootPackageJson;\n let workspaceError = new WorkspaceError('INVALID_PACKAGE_JSON', {\n messageParameters: [rootPackageJsonPath],\n data: {\n path: rootPackageJsonPath,\n zodIssues: zodError.issues,\n },\n });\n\n errors.push(workspaceError);\n\n rootPackageJson = {};\n }\n\n let projectGlobs = getPackageJsonWorkspaces(rootPackageJson);\n\n this.projectGlobs = (projectGlobs ?? []) as WorkspaceProjectGlobs<M>;\n this.packageJson = rootPackageJson as WorkspacePackageJson<M>;\n this.config = workspaceConfig;\n this.errors = errors;\n\n if (repositoryUrl) {\n this.repository = {\n url: repositoryUrl,\n branches: repositoryBranches ?? [],\n };\n } else if (repositoryBranches) {\n this.repository = {\n branches: repositoryBranches,\n };\n }\n\n await this.readProjects();\n\n return this;\n }\n\n // we're dealing with single-project workspace\n this.config = workspaceConfig;\n this.errors = errors;\n\n if (repositoryUrl) {\n this.repository = {\n url: repositoryUrl,\n branches: repositoryBranches ?? [],\n };\n } else if (repositoryBranches) {\n this.repository = {\n branches: repositoryBranches,\n };\n }\n\n await this.readProjects();\n\n return this;\n }\n\n async update({args}: WorkspaceUpdateOptions): Promise<this> {\n if (!this.config.template) {\n throw new WorkspaceError('MISSING_CARSON_TEMPLATE_ID', {\n messageParameters: [\n path.join(this.path, CARSON_CONFIG_DIRECTORY, WORKSPACE_CONFIG_FILENAME),\n ],\n });\n }\n\n let templateRenders = await renderCarsonTemplate({\n templateId: this.config.template,\n templateData: {\n workspace: this,\n args,\n },\n });\n\n await applyTemplateRenders({\n templateRenders,\n targetPath: this.path,\n snapshotPath: path.join(this.path, CARSON_CONFIG_DIRECTORY, WORKSPACE_SNAPSHOT_FILENAME),\n ignoreStrategies: ['create'],\n });\n\n await this.read();\n\n return this;\n }\n\n getProject(projectName: Project<M> | string): Project<M> | undefined {\n for (let project of this.projects) {\n if (project.name === projectName || project === projectName) {\n return project;\n }\n }\n\n return undefined;\n }\n\n async createProject({\n templateId,\n projectPath,\n projectName,\n args,\n }: WorkspaceCreateProjectOptions): Promise<Project<M>> {\n let resolvedProjectPath = path.resolve(projectPath);\n\n if (this.projects.some((project) => resolvedProjectPath === project.path)) {\n throw new WorkspaceError('DUPLICATE_PROJECT_PATH', {\n messageParameters: [resolvedProjectPath],\n });\n }\n\n if (this.projects.some((project) => projectName === project.name)) {\n throw new WorkspaceError('DUPLICATE_PROJECT_NAME', {messageParameters: [projectName]});\n }\n\n if (!this.isMultiProject && this.projects.length >= 1) {\n throw new WorkspaceError('TOO_MANY_PROJECTS');\n }\n\n if (!this.isMultiProject && projectPath !== this.path) {\n throw new WorkspaceError('PATH_MISMATCH');\n }\n\n let newProject = await Project.create({\n templateId,\n projectPath,\n projectName,\n args,\n workspace: this,\n });\n\n this.addProject(newProject);\n\n return newProject;\n }\n\n addProject(newProject: Project<M>): this {\n if (this.projects.some((project) => newProject.path === project.path)) {\n throw new WorkspaceError('DUPLICATE_PROJECT_PATH', {\n messageParameters: [newProject.path],\n });\n }\n\n if (this.projects.some((project) => newProject.name === project.name)) {\n throw new WorkspaceError('DUPLICATE_PROJECT_NAME', {messageParameters: [newProject.name]});\n }\n\n if (!this.isMultiProject && this.projects.length >= 1) {\n throw new WorkspaceError('TOO_MANY_PROJECTS');\n }\n\n if (!this.isMultiProject && newProject.path !== this.path) {\n throw new WorkspaceError('PATH_MISMATCH');\n }\n\n this.projects.push(newProject);\n this.sortProjects();\n this.updateDependencies();\n\n return this;\n }\n\n addProjects(newProjects: Array<Project<M>>): this {\n for (let newProject of newProjects) {\n if (this.projects.some((project) => newProject.path === project.path)) {\n throw new WorkspaceError('DUPLICATE_PROJECT_PATH', {\n messageParameters: [newProject.path],\n });\n }\n\n if (this.projects.some((project) => newProject.name === project.name)) {\n throw new WorkspaceError('DUPLICATE_PROJECT_NAME', {messageParameters: [newProject.name]});\n }\n\n if (!this.isMultiProject && this.projects.length >= 1) {\n throw new WorkspaceError('TOO_MANY_PROJECTS');\n }\n\n if (!this.isMultiProject && newProject.path !== this.path) {\n throw new WorkspaceError('PATH_MISMATCH');\n }\n\n this.projects.push(newProject);\n }\n\n this.sortProjects();\n this.updateDependencies();\n\n return this;\n }\n\n async readProjects(): Promise<Array<Project<M>>> {\n if (this.projectGlobs) {\n let projects: Array<Project<M>> = [];\n let packagePaths = await glob(this.projectGlobs, {\n cwd: this.path,\n onlyDirectories: true,\n });\n\n for (let packagePath of packagePaths) {\n let projectPath = path.join(this.path, packagePath);\n\n if (await containsProject(projectPath)) {\n let project = await Project.read(projectPath, this);\n\n projects.push(project);\n }\n }\n\n this.projects = projects;\n\n this.sortProjects();\n this.updateDependencies();\n } else if (await containsProject(this.path)) {\n this.projects = [await Project.read(this.path, this)];\n\n this.sortProjects();\n this.updateDependencies();\n }\n\n return this.projects;\n }\n\n protected sortProjects(): void {\n this.projects.sort(compareProjectPath);\n }\n\n protected updateDependencies(): void {\n this.dependencies = WorkspaceDependencies.fromWorkspace(this);\n this.devDependencies = WorkspaceDependencies.fromWorkspace(this, {\n includeOnlyDevDependencies: true,\n });\n this.allDependencies = WorkspaceDependencies.fromWorkspace(this, {\n includeDevDependencies: true,\n includeWorkspaceDependencies: true,\n });\n this.dependencyVersions = this.allDependencies.getVersions({\n useExactVersions: true,\n });\n }\n}\n"],"names":["ensureEmptyDirectory","findExistingDirectory","isRootPath","readFile","jsonSchema","packageJsonSchema","glob","fs","json5","path","z","compareProjectPath","containsProject","containsWorkspace","getPackageJsonWorkspaces","getRepositoryBranches","getRepositoryUrl","Project","saveWorkspaceConfig","workspaceConfigSchema","WorkspaceDependencies","WorkspaceError","CARSON_CONFIG_DIRECTORY","WORKSPACE_CONFIG_FILENAME","PACKAGE_JSON_FILENAME","WORKSPACE_SNAPSHOT_FILENAME","applyTemplateRenders","renderCarsonTemplate","Workspace","isMultiProject","projectGlobs","projects","config","packageJson","repository","dependencies","devDependencies","allDependencies","dependencyVersions","errors","constructor","options","projectGlobOption","addProjects","map","project","workspace","packageJsonOption","emptyPackageJson","configOption","emptyWorkspaceConfig","length","packageJsonWorkspaces","sortProjects","updateDependencies","create","args","workspacePath","templateId","template","allowGit","messageParameters","data","templateRenders","templateData","targetPath","snapshotPath","join","ignoreStrategies","workspaceConfig","read","resolvedWorkspacePath","resolve","pathExists","rootPackageJsonPath","doesRootPackageJsonExist","rootPackageJson","parser","rawString","parse","ZodError","rootJson","throwOnZodError","workspaces","readProjects","find","searchPath","startingPath","currentPath","singlePackageWorkspacePath","multiPackageWorkspacePath","packageJsonPath","Error","dirname","undefined","findAndRead","throwIfNotFound","repositoryUrl","repositoryBranches","workspaceConfigPath","doesWorkspaceConfigExist","zodError","workspaceError","zodIssues","issues","push","url","branches","update","getProject","projectName","name","createProject","projectPath","resolvedProjectPath","some","newProject","addProject","newProjects","packagePaths","cwd","onlyDirectories","packagePath","sort","fromWorkspace","includeOnlyDevDependencies","includeDevDependencies","includeWorkspaceDependencies","getVersions","useExactVersions"],"mappings":"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"}
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import fs from 'fs-extra';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import { CARSON_CONFIG_DIRECTORY, PACKAGE_JSON_FILENAME } from '../../constants.js';
|
|
3
|
+
import { CARSON_CONFIG_DIRECTORY, PACKAGE_JSON_FILENAME, PROJECT_CONFIG_FILENAME } from '../../constants.js';
|
|
4
4
|
export async function containsProject(directoryPath) {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
let packageJsonPath = path.join(directoryPath, PACKAGE_JSON_FILENAME);
|
|
6
|
+
if (await fs.pathExists(packageJsonPath)) {
|
|
7
|
+
let packageJson = await fs.readJson(packageJsonPath);
|
|
8
|
+
if (packageJson?.name) {
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
return false;
|
|
7
12
|
}
|
|
8
|
-
if (await fs.pathExists(path.join(directoryPath, CARSON_CONFIG_DIRECTORY))) {
|
|
13
|
+
if (await fs.pathExists(path.join(directoryPath, CARSON_CONFIG_DIRECTORY, PROJECT_CONFIG_FILENAME))) {
|
|
9
14
|
return true;
|
|
10
15
|
}
|
|
11
16
|
return false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/workspace/internals/containsProject.ts"],"sourcesContent":["import fs from 'fs-extra';\nimport path from 'node:path';\n\nimport {CARSON_CONFIG_DIRECTORY
|
|
1
|
+
{"version":3,"sources":["../../../src/workspace/internals/containsProject.ts"],"sourcesContent":["import {type PackageJson} from '@jakubmazanec/zod-utils';\nimport fs from 'fs-extra';\nimport path from 'node:path';\n\nimport {\n CARSON_CONFIG_DIRECTORY,\n PACKAGE_JSON_FILENAME,\n PROJECT_CONFIG_FILENAME,\n} from '../../constants.js';\n\nexport async function containsProject(directoryPath: string): Promise<boolean> {\n let packageJsonPath = path.join(directoryPath, PACKAGE_JSON_FILENAME);\n\n if (await fs.pathExists(packageJsonPath)) {\n let packageJson = (await fs.readJson(packageJsonPath)) as PackageJson | undefined;\n\n if (packageJson?.name) {\n return true;\n }\n\n return false;\n }\n\n if (\n await fs.pathExists(path.join(directoryPath, CARSON_CONFIG_DIRECTORY, PROJECT_CONFIG_FILENAME))\n ) {\n return true;\n }\n\n return false;\n}\n"],"names":["fs","path","CARSON_CONFIG_DIRECTORY","PACKAGE_JSON_FILENAME","PROJECT_CONFIG_FILENAME","containsProject","directoryPath","packageJsonPath","join","pathExists","packageJson","readJson","name"],"mappings":"AACA,OAAOA,QAAQ,WAAW;AAC1B,OAAOC,UAAU,YAAY;AAE7B,SACEC,uBAAuB,EACvBC,qBAAqB,EACrBC,uBAAuB,QAClB,qBAAqB;AAE5B,OAAO,eAAeC,gBAAgBC,aAAqB;IACzD,IAAIC,kBAAkBN,KAAKO,IAAI,CAACF,eAAeH;IAE/C,IAAI,MAAMH,GAAGS,UAAU,CAACF,kBAAkB;QACxC,IAAIG,cAAe,MAAMV,GAAGW,QAAQ,CAACJ;QAErC,IAAIG,aAAaE,MAAM;YACrB,OAAO;QACT;QAEA,OAAO;IACT;IAEA,IACE,MAAMZ,GAAGS,UAAU,CAACR,KAAKO,IAAI,CAACF,eAAeJ,yBAAyBE,2BACtE;QACA,OAAO;IACT;IAEA,OAAO;AACT"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function containsWorkspace(directoryPath: string): Promise<boolean>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { CARSON_CONFIG_DIRECTORY, PACKAGE_JSON_FILENAME, WORKSPACE_CONFIG_FILENAME } from '../../constants.js';
|
|
4
|
+
export async function containsWorkspace(directoryPath) {
|
|
5
|
+
if (await fs.pathExists(path.join(directoryPath, PACKAGE_JSON_FILENAME))) {
|
|
6
|
+
return true;
|
|
7
|
+
}
|
|
8
|
+
if (await fs.pathExists(path.join(directoryPath, CARSON_CONFIG_DIRECTORY, WORKSPACE_CONFIG_FILENAME))) {
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
//# sourceMappingURL=containsWorkspace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/workspace/internals/containsWorkspace.ts"],"sourcesContent":["import fs from 'fs-extra';\nimport path from 'node:path';\n\nimport {\n CARSON_CONFIG_DIRECTORY,\n PACKAGE_JSON_FILENAME,\n WORKSPACE_CONFIG_FILENAME,\n} from '../../constants.js';\n\nexport async function containsWorkspace(directoryPath: string): Promise<boolean> {\n if (await fs.pathExists(path.join(directoryPath, PACKAGE_JSON_FILENAME))) {\n return true;\n }\n\n if (\n await fs.pathExists(\n path.join(directoryPath, CARSON_CONFIG_DIRECTORY, WORKSPACE_CONFIG_FILENAME),\n )\n ) {\n return true;\n }\n\n return false;\n}\n"],"names":["fs","path","CARSON_CONFIG_DIRECTORY","PACKAGE_JSON_FILENAME","WORKSPACE_CONFIG_FILENAME","containsWorkspace","directoryPath","pathExists","join"],"mappings":"AAAA,OAAOA,QAAQ,WAAW;AAC1B,OAAOC,UAAU,YAAY;AAE7B,SACEC,uBAAuB,EACvBC,qBAAqB,EACrBC,yBAAyB,QACpB,qBAAqB;AAE5B,OAAO,eAAeC,kBAAkBC,aAAqB;IAC3D,IAAI,MAAMN,GAAGO,UAAU,CAACN,KAAKO,IAAI,CAACF,eAAeH,yBAAyB;QACxE,OAAO;IACT;IAEA,IACE,MAAMH,GAAGO,UAAU,CACjBN,KAAKO,IAAI,CAACF,eAAeJ,yBAAyBE,6BAEpD;QACA,OAAO;IACT;IAEA,OAAO;AACT"}
|
|
@@ -2,6 +2,7 @@ export * from './internals/compareProjectPath.js';
|
|
|
2
2
|
export * from './internals/compareSemver.js';
|
|
3
3
|
export * from './internals/compareWorkspaceDependencyProjectName.js';
|
|
4
4
|
export * from './internals/containsProject.js';
|
|
5
|
+
export * from './internals/containsWorkspace.js';
|
|
5
6
|
export * from './internals/getPackageJsonWorkspaces.js';
|
|
6
7
|
export * from './internals/getRepositoryBranches.js';
|
|
7
8
|
export * from './internals/getRepositoryUrl.js';
|
|
@@ -2,6 +2,7 @@ export * from './internals/compareProjectPath.js';
|
|
|
2
2
|
export * from './internals/compareSemver.js';
|
|
3
3
|
export * from './internals/compareWorkspaceDependencyProjectName.js';
|
|
4
4
|
export * from './internals/containsProject.js';
|
|
5
|
+
export * from './internals/containsWorkspace.js';
|
|
5
6
|
export * from './internals/getPackageJsonWorkspaces.js';
|
|
6
7
|
export * from './internals/getRepositoryBranches.js';
|
|
7
8
|
export * from './internals/getRepositoryUrl.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/workspace/internals.ts"],"sourcesContent":["export * from './internals/compareProjectPath.js';\nexport * from './internals/compareSemver.js';\nexport * from './internals/compareWorkspaceDependencyProjectName.js';\nexport * from './internals/containsProject.js';\nexport * from './internals/getPackageJsonWorkspaces.js';\nexport * from './internals/getRepositoryBranches.js';\nexport * from './internals/getRepositoryUrl.js';\n"],"names":[],"mappings":"AAAA,cAAc,oCAAoC;AAClD,cAAc,+BAA+B;AAC7C,cAAc,uDAAuD;AACrE,cAAc,iCAAiC;AAC/C,cAAc,0CAA0C;AACxD,cAAc,uCAAuC;AACrD,cAAc,kCAAkC"}
|
|
1
|
+
{"version":3,"sources":["../../src/workspace/internals.ts"],"sourcesContent":["export * from './internals/compareProjectPath.js';\nexport * from './internals/compareSemver.js';\nexport * from './internals/compareWorkspaceDependencyProjectName.js';\nexport * from './internals/containsProject.js';\nexport * from './internals/containsWorkspace.js';\nexport * from './internals/getPackageJsonWorkspaces.js';\nexport * from './internals/getRepositoryBranches.js';\nexport * from './internals/getRepositoryUrl.js';\n"],"names":[],"mappings":"AAAA,cAAc,oCAAoC;AAClD,cAAc,+BAA+B;AAC7C,cAAc,uDAAuD;AACrE,cAAc,iCAAiC;AAC/C,cAAc,mCAAmC;AACjD,cAAc,0CAA0C;AACxD,cAAc,uCAAuC;AACrD,cAAc,kCAAkC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jakubmazanec/carson",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0-next.1b2cc9c",
|
|
4
4
|
"description": "Tool for managing workspace and project configuration.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"typecheck": "tsc --project tsconfig.typecheck.json"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@jakubmazanec/args": "
|
|
34
|
+
"@jakubmazanec/args": "1.0.3-next.1b2cc9c",
|
|
35
35
|
"@jakubmazanec/cli": "^0.2.0",
|
|
36
36
|
"@jakubmazanec/error": "^2.0.0",
|
|
37
37
|
"@jakubmazanec/fs-utils": "^0.1.0",
|
package/src/constants.ts
CHANGED
|
@@ -8,7 +8,8 @@ export const PACKAGE_PATH = path.resolve(directory, '..');
|
|
|
8
8
|
export const CARSON_CONFIG_DIRECTORY = '.carson';
|
|
9
9
|
export const PROJECT_CONFIG_FILENAME = 'project.json';
|
|
10
10
|
export const WORKSPACE_CONFIG_FILENAME = 'workspace.json';
|
|
11
|
-
export const
|
|
11
|
+
export const PROJECT_SNAPSHOT_FILENAME = 'project.snapshot';
|
|
12
|
+
export const WORKSPACE_SNAPSHOT_FILENAME = 'workspace.snapshot';
|
|
12
13
|
export const TEMPLATES_PATH = 'templates';
|
|
13
14
|
export const TEMPLATE_CONFIG_FILENAME = 'config.json';
|
|
14
15
|
export const PACKAGE_JSON_FILENAME = 'package.json';
|
|
@@ -17,11 +17,12 @@ import {
|
|
|
17
17
|
unmergeUsingTemplateRender,
|
|
18
18
|
} from './internals.js';
|
|
19
19
|
import {type TemplateRenders} from './TemplateRenders.js';
|
|
20
|
-
import {CARSON_CONFIG_DIRECTORY
|
|
20
|
+
import {CARSON_CONFIG_DIRECTORY} from '../constants.js';
|
|
21
21
|
|
|
22
22
|
export type ApplyTemplateRendersOptions = {
|
|
23
23
|
templateRenders: TemplateRenders;
|
|
24
|
-
|
|
24
|
+
targetPath: string;
|
|
25
|
+
snapshotPath: string;
|
|
25
26
|
ignoreStrategies: string[];
|
|
26
27
|
};
|
|
27
28
|
|
|
@@ -30,21 +31,16 @@ export type ApplyTemplateRendersOptions = {
|
|
|
30
31
|
*/
|
|
31
32
|
export async function applyTemplateRenders({
|
|
32
33
|
templateRenders,
|
|
33
|
-
|
|
34
|
+
targetPath,
|
|
35
|
+
snapshotPath,
|
|
34
36
|
ignoreStrategies,
|
|
35
37
|
}: ApplyTemplateRendersOptions) {
|
|
36
38
|
// we need to clear Prettier cache, because we are changing file system
|
|
37
39
|
await prettier.clearConfigCache();
|
|
38
40
|
|
|
39
41
|
// first, we read the existing snapshots and use them to undo previous changes
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
CARSON_CONFIG_DIRECTORY,
|
|
43
|
-
SNAPSHOTS_FILENAME,
|
|
44
|
-
);
|
|
45
|
-
|
|
46
|
-
if (await fs.pathExists(templateRenderSnapshotsPath)) {
|
|
47
|
-
let templateRenderSnapshots = await loadTemplateRenderSnapshots(templateRenderSnapshotsPath);
|
|
42
|
+
if (await fs.pathExists(snapshotPath)) {
|
|
43
|
+
let templateRenderSnapshots = await loadTemplateRenderSnapshots(snapshotPath);
|
|
48
44
|
|
|
49
45
|
for (let templateRenderSnapshot of templateRenderSnapshots) {
|
|
50
46
|
let strategy =
|
|
@@ -141,5 +137,5 @@ export async function applyTemplateRenders({
|
|
|
141
137
|
|
|
142
138
|
await fs.ensureDir(path.join(targetPath, CARSON_CONFIG_DIRECTORY));
|
|
143
139
|
|
|
144
|
-
await saveTemplateRenderSnapshots(templateRenders,
|
|
140
|
+
await saveTemplateRenderSnapshots(templateRenders, snapshotPath);
|
|
145
141
|
}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
+
import {type Json} from '@jakubmazanec/zod-utils';
|
|
1
2
|
import fs from 'fs-extra';
|
|
3
|
+
import json from 'json5';
|
|
2
4
|
import path from 'node:path';
|
|
5
|
+
import yaml from 'yaml';
|
|
3
6
|
|
|
7
|
+
import {merge} from './merge.js';
|
|
4
8
|
import {prettify} from './prettify.js';
|
|
5
9
|
import {type TemplateRenderSnapshot} from './TemplateRenderSnapshot.js';
|
|
6
10
|
import {type TemplateRender} from '../TemplateRender.js';
|
|
@@ -10,7 +14,43 @@ export async function createUsingTemplateRender(
|
|
|
10
14
|
basePath: string,
|
|
11
15
|
) {
|
|
12
16
|
let to = path.join(basePath, templateRender.attributes.to);
|
|
17
|
+
let extension = path.extname(to);
|
|
13
18
|
|
|
14
|
-
|
|
15
|
-
|
|
19
|
+
switch (extension) {
|
|
20
|
+
case '.json': {
|
|
21
|
+
if (await fs.pathExists(to)) {
|
|
22
|
+
let targetFile = (await fs.readJson(to)) as Json;
|
|
23
|
+
let fileToMerge = json.parse<Json>(templateRender.content);
|
|
24
|
+
let newFile = JSON.stringify(merge(targetFile, fileToMerge), null, 2);
|
|
25
|
+
|
|
26
|
+
await fs.writeFile(to, await prettify(newFile, to), {encoding: 'utf8'});
|
|
27
|
+
} else {
|
|
28
|
+
await fs.ensureDir(path.dirname(to));
|
|
29
|
+
await fs.writeFile(to, await prettify(templateRender.content, to), {encoding: 'utf8'});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
case '.yaml': {
|
|
36
|
+
if (await fs.pathExists(to)) {
|
|
37
|
+
let targetFile = yaml.parse(await fs.readFile(to, {encoding: 'utf8'})) as unknown;
|
|
38
|
+
let fileToMerge = yaml.parse(templateRender.content) as unknown;
|
|
39
|
+
let newFile = yaml.stringify(merge(targetFile, fileToMerge));
|
|
40
|
+
|
|
41
|
+
await fs.writeFile(to, await prettify(newFile, to), {encoding: 'utf8'});
|
|
42
|
+
} else {
|
|
43
|
+
await fs.writeFile(to, await prettify(templateRender.content, to), {encoding: 'utf8'});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
default: {
|
|
50
|
+
await fs.ensureDir(path.dirname(to));
|
|
51
|
+
await fs.writeFile(to, await prettify(templateRender.content, to), {encoding: 'utf8'});
|
|
52
|
+
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
16
56
|
}
|
|
@@ -19,21 +19,29 @@ export async function mergeUsingTemplateRender(
|
|
|
19
19
|
|
|
20
20
|
switch (extension) {
|
|
21
21
|
case '.json': {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
if (await fs.pathExists(to)) {
|
|
23
|
+
let targetFile = (await fs.readJson(to)) as Json;
|
|
24
|
+
let fileToMerge = json.parse<Json>(templateRender.content);
|
|
25
|
+
let newFile = JSON.stringify(merge(targetFile, fileToMerge), null, 2);
|
|
25
26
|
|
|
26
|
-
|
|
27
|
+
await fs.writeFile(to, await prettify(newFile, to), {encoding: 'utf8'});
|
|
28
|
+
} else {
|
|
29
|
+
await fs.writeFile(to, await prettify(templateRender.content, to), {encoding: 'utf8'});
|
|
30
|
+
}
|
|
27
31
|
|
|
28
32
|
break;
|
|
29
33
|
}
|
|
30
34
|
|
|
31
35
|
case '.yaml': {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
if (await fs.pathExists(to)) {
|
|
37
|
+
let targetFile = yaml.parse(await fs.readFile(to, {encoding: 'utf8'})) as unknown;
|
|
38
|
+
let fileToMerge = yaml.parse(templateRender.content) as unknown;
|
|
39
|
+
let newFile = yaml.stringify(merge(targetFile, fileToMerge));
|
|
40
|
+
|
|
41
|
+
await fs.writeFile(to, await prettify(newFile, to), {encoding: 'utf8'});
|
|
42
|
+
} else {
|
|
43
|
+
await fs.writeFile(to, await prettify(templateRender.content, to), {encoding: 'utf8'});
|
|
44
|
+
}
|
|
37
45
|
|
|
38
46
|
break;
|
|
39
47
|
}
|
package/src/workspace/Project.ts
CHANGED
|
@@ -12,7 +12,11 @@ import {type ProjectOptions} from './ProjectOptions.js';
|
|
|
12
12
|
import {type ProjectUpdateOptions} from './ProjectUpdateOptions.js';
|
|
13
13
|
import {saveProjectConfig} from './saveProjectConfig.js';
|
|
14
14
|
import {type Workspace} from './Workspace.js';
|
|
15
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
CARSON_CONFIG_DIRECTORY,
|
|
17
|
+
PROJECT_CONFIG_FILENAME,
|
|
18
|
+
PROJECT_SNAPSHOT_FILENAME,
|
|
19
|
+
} from '../constants.js';
|
|
16
20
|
import {applyTemplateRenders} from '../template/applyTemplateRenders.js';
|
|
17
21
|
import {renderCarsonTemplate} from '../template/renderCarsonTemplate.js';
|
|
18
22
|
|
|
@@ -99,15 +103,18 @@ export class Project<M extends boolean = true> {
|
|
|
99
103
|
workspace,
|
|
100
104
|
});
|
|
101
105
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
106
|
+
// if the workspace is single-project, it shares a directory with the project, so we can't insist on it being an empty directory
|
|
107
|
+
if (workspace.isMultiProject) {
|
|
108
|
+
try {
|
|
109
|
+
await ensureEmptyDirectory(project.path);
|
|
110
|
+
} catch {
|
|
111
|
+
throw new ProjectError('PROJECT_PATH_NOT_EMPTY', {
|
|
112
|
+
messageParameters: [project.path],
|
|
113
|
+
data: {
|
|
114
|
+
path: project.path,
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
}
|
|
111
118
|
}
|
|
112
119
|
|
|
113
120
|
let templateRenders = await renderCarsonTemplate({
|
|
@@ -121,7 +128,8 @@ export class Project<M extends boolean = true> {
|
|
|
121
128
|
|
|
122
129
|
await applyTemplateRenders({
|
|
123
130
|
templateRenders,
|
|
124
|
-
|
|
131
|
+
targetPath: project.path,
|
|
132
|
+
snapshotPath: path.join(project.path, CARSON_CONFIG_DIRECTORY, PROJECT_SNAPSHOT_FILENAME),
|
|
125
133
|
ignoreStrategies: ['check'],
|
|
126
134
|
});
|
|
127
135
|
|
|
@@ -245,7 +253,8 @@ export class Project<M extends boolean = true> {
|
|
|
245
253
|
|
|
246
254
|
await applyTemplateRenders({
|
|
247
255
|
templateRenders,
|
|
248
|
-
|
|
256
|
+
targetPath: this.path,
|
|
257
|
+
snapshotPath: path.join(this.path, CARSON_CONFIG_DIRECTORY, PROJECT_SNAPSHOT_FILENAME),
|
|
249
258
|
ignoreStrategies: ['create'],
|
|
250
259
|
});
|
|
251
260
|
|
|
@@ -9,6 +9,7 @@ import {z} from 'zod';
|
|
|
9
9
|
import {
|
|
10
10
|
compareProjectPath,
|
|
11
11
|
containsProject,
|
|
12
|
+
containsWorkspace,
|
|
12
13
|
getPackageJsonWorkspaces,
|
|
13
14
|
getRepositoryBranches,
|
|
14
15
|
getRepositoryUrl,
|
|
@@ -28,7 +29,12 @@ import type {WorkspaceProjectGlobs} from './WorkspaceProjectGlobs.js';
|
|
|
28
29
|
import {type WorkspaceProjects} from './WorkspaceProjects.js';
|
|
29
30
|
import {type WorkspaceRepository} from './WorkspaceRepository.js';
|
|
30
31
|
import {type WorkspaceUpdateOptions} from './WorkspaceUpdateOptions.js';
|
|
31
|
-
import {
|
|
32
|
+
import {
|
|
33
|
+
CARSON_CONFIG_DIRECTORY,
|
|
34
|
+
WORKSPACE_CONFIG_FILENAME,
|
|
35
|
+
PACKAGE_JSON_FILENAME,
|
|
36
|
+
WORKSPACE_SNAPSHOT_FILENAME,
|
|
37
|
+
} from '../constants.js';
|
|
32
38
|
import {applyTemplateRenders} from '../template/applyTemplateRenders.js';
|
|
33
39
|
import {renderCarsonTemplate} from '../template/renderCarsonTemplate.js';
|
|
34
40
|
|
|
@@ -185,7 +191,8 @@ export class Workspace<M extends boolean = true> {
|
|
|
185
191
|
|
|
186
192
|
await applyTemplateRenders({
|
|
187
193
|
templateRenders,
|
|
188
|
-
|
|
194
|
+
targetPath: workspace.path,
|
|
195
|
+
snapshotPath: path.join(workspace.path, CARSON_CONFIG_DIRECTORY, WORKSPACE_SNAPSHOT_FILENAME),
|
|
189
196
|
ignoreStrategies: ['check'],
|
|
190
197
|
});
|
|
191
198
|
|
|
@@ -274,6 +281,9 @@ export class Workspace<M extends boolean = true> {
|
|
|
274
281
|
|
|
275
282
|
/**
|
|
276
283
|
* Traverses file system up from the search path and tries to find a directory that is a root of a workspace.
|
|
284
|
+
*
|
|
285
|
+
* @param searchPath Search path.
|
|
286
|
+
* @returns Workspace path, if found.
|
|
277
287
|
*/
|
|
278
288
|
static async find(searchPath: string): Promise<string | undefined> {
|
|
279
289
|
let startingPath = await findExistingDirectory(path.resolve(searchPath));
|
|
@@ -284,22 +294,25 @@ export class Workspace<M extends boolean = true> {
|
|
|
284
294
|
while (
|
|
285
295
|
!(isRootPath(currentPath) || (singlePackageWorkspacePath && multiPackageWorkspacePath))
|
|
286
296
|
) {
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
297
|
+
if (await containsWorkspace(currentPath)) {
|
|
298
|
+
const packageJsonPath = path.join(currentPath, PACKAGE_JSON_FILENAME);
|
|
299
|
+
|
|
300
|
+
if (await fs.pathExists(packageJsonPath)) {
|
|
301
|
+
const packageJson = await readFile(packageJsonPath, jsonSchema, {
|
|
302
|
+
parser: (rawString: string) => json5.parse<unknown>(rawString),
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
if (!(packageJson instanceof Error)) {
|
|
306
|
+
const projectGlobs = getPackageJsonWorkspaces(packageJson);
|
|
307
|
+
|
|
308
|
+
if (projectGlobs?.length) {
|
|
309
|
+
multiPackageWorkspacePath ??= currentPath;
|
|
310
|
+
} else {
|
|
311
|
+
singlePackageWorkspacePath ??= currentPath;
|
|
312
|
+
}
|
|
302
313
|
}
|
|
314
|
+
} else {
|
|
315
|
+
singlePackageWorkspacePath ??= currentPath;
|
|
303
316
|
}
|
|
304
317
|
}
|
|
305
318
|
|
|
@@ -493,7 +506,8 @@ export class Workspace<M extends boolean = true> {
|
|
|
493
506
|
|
|
494
507
|
await applyTemplateRenders({
|
|
495
508
|
templateRenders,
|
|
496
|
-
|
|
509
|
+
targetPath: this.path,
|
|
510
|
+
snapshotPath: path.join(this.path, CARSON_CONFIG_DIRECTORY, WORKSPACE_SNAPSHOT_FILENAME),
|
|
497
511
|
ignoreStrategies: ['create'],
|
|
498
512
|
});
|
|
499
513
|
|
|
@@ -625,12 +639,15 @@ export class Workspace<M extends boolean = true> {
|
|
|
625
639
|
}
|
|
626
640
|
|
|
627
641
|
this.projects = projects;
|
|
628
|
-
|
|
642
|
+
|
|
643
|
+
this.sortProjects();
|
|
644
|
+
this.updateDependencies();
|
|
645
|
+
} else if (await containsProject(this.path)) {
|
|
629
646
|
this.projects = [await Project.read(this.path, this)];
|
|
630
|
-
}
|
|
631
647
|
|
|
632
|
-
|
|
633
|
-
|
|
648
|
+
this.sortProjects();
|
|
649
|
+
this.updateDependencies();
|
|
650
|
+
}
|
|
634
651
|
|
|
635
652
|
return this.projects;
|
|
636
653
|
}
|