import { errorLog } from '../log/error' ; import { Package } from '../package' ; import { getMonorepoBaseData } from '../parse-config/monorepo' ; import { getProjetsByPackageConfig , syncGetProjetsByPackageConfig , } from './get-projects-by-packages-config' ; import { getProjectsByWorkspaceFile , syncGetProjectsByWorkspaceFile , } from './get-projects-by-workspace-file' ; export interface IFindSubProjectConfig { packagesMatchs ? : string [ ] | { enableAutoFinder ? : boolean ; workspaceFile ? : string ; } ; projectsConfig ? : { name : string ; path : string ; } [ ] ; /**
     * https://github.com/mrmlnc/fast-glob#ignore
     */ packagesIgnoreMatchs ? : string [ ] ; } export interface IProjectNode { name : string ; dependency ? : IProjectNode [ ] ; dependent ? : IProjectNode [ ] ; extra : { path : string ; } & Record < string , any > ; dependencyEdge : number ; dependentEdge : number ; checkedCircle : boolean ; circlePath : string [ ] ; criticalPathLength ? : number ; } export type IMonorepoSubProject = IProjectNode ; enum FindProjectsMode { Rough , Precise } const getProjectsByProjectsConfig = ( rootPath , configs = [ ] ) : IMonorepoSubProject [ ] => { const subProjects = [ ] ; for ( const config of configs ) { subProjects . push ( { name : config . name , extra : { path : config . path } , dependencyEdge : 0 , dependentEdge : 0 , checkedCircle : false , circlePath : [ ] , } ) ; } return subProjects ; } ; const getProjectsByPackagesMatch = async ( rootPath , match , ignore ) : Promise < IMonorepoSubProject [ ] > => { let projects = [ ] ; if ( Array . isArray ( match ) ) { projects = await getProjetsByPackageConfig ( rootPath , match , ignore ) ; } else { projects = await getProjectsByWorkspaceFile ( rootPath , match as { workspaceFile : string ; } , ignore ) ; } const subProjects = [ ] ; for ( const project of projects ) { subProjects . push ( { name : project . name , extra : { path : project . path , ... project . json , } , dependencyEdge : 0 , dependentEdge : 0 , checkedCircle : false , circlePath : [ ] , } ) ; } return subProjects ; } ; const syncGetProjectsByPackagesMatch = ( rootPath , match , ignore ) : IMonorepoSubProject [ ] => { let projects = [ ] ; if ( Array . isArray ( match ) ) { projects = syncGetProjetsByPackageConfig ( rootPath , match , ignore ) ; } else { projects = syncGetProjectsByWorkspaceFile ( rootPath , match as { workspaceFile : string ; } , ignore ) ; } const subProjects = [ ] ; for ( const project of projects ) { subProjects . push ( { name : project . name , extra : { path : project . path , ... project . json , } , dependencyEdge : 0 , dependentEdge : 0 , checkedCircle : false , circlePath : [ ] , } ) ; } return subProjects ; } ; const checkFindProjectsMode = ( config ) : FindProjectsMode | undefined => { if ( config . packagesMatchs && Array . isArray ( config . packagesMatchs ) ) { return FindProjectsMode . Rough ; } if ( config . packagesMatchs && typeof config . packagesMatchs === 'object' && ( config . packagesMatchs . workspaceFile || config . packagesMatchs . enableAutoFinder ) ) { return FindProjectsMode . Rough ; } if ( config . projectsConfig && Array . isArray ( config . projectsConfig ) ) { return FindProjectsMode . Precise ; } if ( config . projectsConfig && config . packagesMatchs ) { errorLog ( 'There can not be both `pakcagesMatchs` and `projectsConfig`' ) ; } errorLog ( 'No `pakcagesMatchs` and `projectsConfig` configurations found' ) ; } ; export const getProjects = async ( config , currentDir = process . cwd ( ) ) : Promise < IMonorepoSubProject [ ] > => { const { rootPath } = getMonorepoBaseData ( currentDir ) ; const mode = checkFindProjectsMode ( config ) ; let projects = [ ] ; if ( mode === FindProjectsMode . Rough ) { projects = await getProjectsByPackagesMatch ( rootPath , config . packagesMatchs , config . packagesIgnoreMatchs || [ ] ) ; } else if ( mode === FindProjectsMode . Precise ) { projects = getProjectsByProjectsConfig ( rootPath , config . projectsConfig ) ; } return projects ; } ; export const syncGetProjects = ( config , currentDir = process . cwd ( ) ) : IMonorepoSubProject [ ] => { const { rootPath } = getMonorepoBaseData ( currentDir ) ; const mode = checkFindProjectsMode ( config ) ; let projects = [ ] ; if ( mode === FindProjectsMode . Rough ) { projects = syncGetProjectsByPackagesMatch ( rootPath , config . packagesMatchs , config . packagesIgnoreMatchs || [ ] ) ; } else if ( mode === FindProjectsMode . Precise ) { projects = getProjectsByProjectsConfig ( rootPath , config . projectsConfig ) ; } return projects ; } ;