1/* 2 * Copyright (c) 2024 - 2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import {ArkFile, BUILD_PROFILE_JSON5, parseJsonText, Scene} from 'arkanalyzer'; 17import {File, FileDepsGraph} from './fileComponent'; 18import {ArkFileDeps} from './fileDeps'; 19import Logger, {LOG_MODULE_TYPE} from 'arkanalyzer/lib/utils/logger'; 20import {Module, ModuleDepsGraph} from './moduleComponent'; 21import {ModuleDeps} from './moduleDeps'; 22import {getModuleKind} from './utils'; 23import path from 'path'; 24import fs from 'fs'; 25 26const logger = Logger.getLogger(LOG_MODULE_TYPE.TOOL, 'DepGraph'); 27 28export function buildFileDepGraph(arkFiles: ArkFile[]): FileDepsGraph { 29 let depGraph: FileDepsGraph = new FileDepsGraph(); 30 let arkFileDeps = ArkFileDeps.getInstance(); 31 arkFiles.forEach(arkFile => { 32 const nodeAttr: File = { 33 name: arkFile.getFilePath(), 34 kind: 0, 35 }; 36 let srcNode = depGraph.addDepsNode(arkFile.getFilePath(), nodeAttr); 37 arkFileDeps.addDeps(depGraph, srcNode, arkFile); 38 }); 39 return depGraph; 40} 41 42export function buildModuleDepGraph(scene: Scene): ModuleDepsGraph { 43 let moduleGraph: ModuleDepsGraph = new ModuleDepsGraph(); 44 let moduleDeps: ModuleDeps = ModuleDeps.getInstance(); 45 const modules = getModules(scene.getRealProjectDir()); 46 modules.forEach((modulePath) => { 47 logger.info(`Project module: ${modulePath} found.`); 48 const nodeAttr: Module = { 49 name: modulePath, 50 kind: getModuleKind(modulePath), 51 }; 52 if (!moduleGraph.hasDepsNode(modulePath)) { 53 let srcNode = moduleGraph.addDepsNode(modulePath, nodeAttr); 54 moduleDeps.addDeps(moduleGraph, srcNode); 55 } 56 }); 57 return moduleGraph; 58} 59 60function getModules(projectPath: string): string[] { 61 const buildProfile = path.join(projectPath, BUILD_PROFILE_JSON5); 62 let modulePaths: string[] = []; 63 if (fs.existsSync(buildProfile)) { 64 let configurationsText: string; 65 try { 66 configurationsText = fs.readFileSync(buildProfile, 'utf-8'); 67 } catch (error) { 68 logger.error(`Error reading file: ${error}`); 69 return modulePaths; 70 } 71 const buildProfileJson = parseJsonText(configurationsText); 72 const modules = buildProfileJson.modules; 73 if (modules instanceof Array) { 74 modules.forEach((module) => { 75 modulePaths.push(path.resolve(projectPath, module.srcPath as string)); 76 }); 77 } 78 } else { 79 logger.warn('There is no build-profile.json5 for this project.'); 80 } 81 return modulePaths; 82}