1/* 2 * Copyright (c) 2023 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 childProcess from 'child_process'; 17import cluster from 'cluster'; 18import fs from 'fs'; 19import path from 'path'; 20import process from 'process'; 21 22import { 23 COMMONJS, 24 ESM, 25 ESMODULE, 26 EXTNAME_ABC, 27 JSBUNDLE, 28 FAIL, 29 SUCCESS 30} from './ark_define'; 31import { changeFileExtension} from '../utils'; 32 33function genAbcByWorkersOfBundleMode(jsonInput: string, cmd: string): Promise<void> { 34 const inputPaths: any = JSON.parse(jsonInput); 35 for (let i = 0; i < inputPaths.length; ++i) { 36 const cacheFilePath: string = inputPaths[i].cacheFilePath; 37 const cacheAbcFilePath: string = changeFileExtension(cacheFilePath, EXTNAME_ABC); 38 const sourceFile: string = inputPaths[i].sourceFile; 39 const singleCmd: any = `${cmd} "${cacheFilePath}" -o "${cacheAbcFilePath}" --source-file "${sourceFile}"`; 40 try { 41 childProcess.execSync(singleCmd, { windowsHide: true }); 42 } catch (e) { 43 process.send({ data: e.toString() }); 44 process.exit(FAIL); 45 } 46 } 47 48 return; 49} 50 51function genAbcByWorkersOfModuleMode(jsonInput: string, cmd: string, workerFileName: string, 52 cachePath: string): Promise<void> { 53 const inputPaths: any = JSON.parse(jsonInput); 54 const filePath: string = path.join(cachePath, workerFileName); 55 let content: string = ''; 56 for (let i = 0; i < inputPaths.length; ++i) { 57 const info: any = inputPaths[i]; 58 const moduleType: string = info.isCommonJs ? COMMONJS : ESM; 59 content += `${info.cacheFilePath};${info.recordName};${moduleType};${info.sourceFile};${info.packageName}`; 60 if (i < inputPaths.length - 1) { 61 content += '\n'; 62 } 63 } 64 fs.writeFileSync(filePath, content, 'utf-8'); 65 const singleCmd: any = `${cmd} "${filePath}"`; 66 try { 67 childProcess.execSync(singleCmd, { windowsHide: true }); 68 } catch (e) { 69 process.send({ data: e.toString() }); 70 process.exit(FAIL); 71 } 72 73 return; 74} 75 76process.stderr.write = function(chunk) { 77 const message = chunk.toString(); 78 if (message.length !== 0) { 79 // send only non-empty message. sometimes there will be empty stderr, 80 // if processed by parent process's logger.error, the gen_abc process will fail 81 process.send({ 82 data: message 83 }); 84 } 85 return true; 86}; 87 88if (cluster.isWorker && process.env['inputs'] !== undefined && process.env['cmd'] !== undefined && 89 process.env['mode'] !== undefined) { 90 if (process.env['mode'] === JSBUNDLE) { 91 genAbcByWorkersOfBundleMode(process.env['inputs'], process.env['cmd']); 92 process.exit(SUCCESS); 93 } else if (process.env['mode'] === ESMODULE && process.env['workerFileName'] && process.env['cachePath']) { 94 genAbcByWorkersOfModuleMode(process.env['inputs'], process.env['cmd'], process.env['workerFileName'], 95 process.env['cachePath']); 96 process.exit(SUCCESS); 97 } else { 98 process.exit(FAIL); 99 } 100} else { 101 process.send({ 102 data: 'Failed to invoke worker with uncomplete inputs' 103 }); 104 process.exit(FAIL); 105} 106