1/* 2 * Copyright (c) 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 * as crypto from 'crypto'; 17import * as fs from 'fs'; 18import * as os from 'os'; 19import * as path from 'path'; 20import { DECL_ETS_SUFFIX, LANGUAGE_VERSION } from './pre_define'; 21import { BuildConfig } from './types'; 22 23const WINDOWS: string = 'Windows_NT'; 24const LINUX: string = 'Linux'; 25const MAC: string = 'Darwin'; 26 27export function isWindows(): boolean { 28 return os.type() === WINDOWS; 29} 30 31export function isLinux(): boolean { 32 return os.type() === LINUX; 33} 34 35export function isMac(): boolean { 36 return os.type() === MAC; 37} 38 39export function changeFileExtension(file: string, targetExt: string, originExt = ''): string { 40 let currentExt = originExt.length === 0 ? path.extname(file) : originExt; 41 let fileWithoutExt = file.substring(0, file.lastIndexOf(currentExt)); 42 return fileWithoutExt + targetExt; 43} 44 45export function changeDeclgenFileExtension(file: string, targetExt: string): string { 46 if (file.endsWith(DECL_ETS_SUFFIX)) { 47 return changeFileExtension(file, targetExt, DECL_ETS_SUFFIX); 48 } 49 return changeFileExtension(file, targetExt); 50} 51 52export function ensurePathExists(filePath: string): void { 53 try { 54 const dirPath: string = path.dirname(filePath); 55 if (!fs.existsSync(dirPath)) { 56 fs.mkdirSync(dirPath, { recursive: true }); 57 } 58 } catch (error) { 59 if (error instanceof Error) { 60 console.error(`Error: ${error.message}`); 61 } 62 } 63} 64 65export function getFileHash(filePath: string): string { 66 const content = fs.readFileSync(filePath, 'utf8'); 67 return crypto.createHash('sha256').update(content).digest('hex'); 68} 69 70export function toUnixPath(path: string): string { 71 return path.replace(/\\/g, '/'); 72} 73 74export function readFirstLineSync(filePath: string): string | null { 75 76 const fd = fs.openSync(filePath, 'r'); 77 const buffer = Buffer.alloc(256); 78 const bytesRead = fs.readSync(fd, buffer, 0, buffer.length, 0); 79 fs.closeSync(fd); 80 81 const content = buffer.toString('utf-8', 0, bytesRead); 82 const firstLine = content.split(/\r?\n/, 1)[0].trim(); 83 84 return firstLine; 85} 86 87export function isSubPathOf(targetPath: string, parentDir: string): boolean { 88 const resolvedParent = toUnixPath(path.resolve(parentDir)); 89 const resolvedTarget = toUnixPath(path.resolve(targetPath)); 90 return resolvedTarget === resolvedParent || resolvedTarget.startsWith(resolvedParent + '/'); 91} 92 93export function createFileIfNotExists(filePath: string, content: string): boolean { 94 try { 95 const normalizedPath = path.normalize(filePath); 96 if (fs.existsSync(normalizedPath)) { 97 return false; 98 } 99 100 const dir = path.dirname(normalizedPath); 101 if (!fs.existsSync(dir)) { 102 fs.mkdirSync(dir, { recursive: true }); 103 } 104 105 fs.writeFileSync(normalizedPath, content, { encoding: 'utf-8' }); 106 return true; 107 } catch (error) { 108 return false; 109 } 110} 111 112export function isHybrid(buildConfig: BuildConfig): boolean { 113 return buildConfig.dependentModuleList.some( 114 module => module.language === LANGUAGE_VERSION.ARKTS_1_1 || 115 module.language === LANGUAGE_VERSION.ARKTS_HYBRID 116 ); 117} 118