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 16const { ApiCollector, MultiProjectApiCollector } = require('./api_collector'); 17const { Logger } = require('./utils'); 18const path = require('path'); 19const fs = require('fs'); 20 21class AppApiCollectorPlugin { 22 constructor() { 23 this.logTag = 'AppApiCollectorPlugin'; 24 } 25 getPluginOptions() { 26 return { 27 name: 'api-collector', 28 version: '0.1.0', 29 description: 'collect api from app\'s source code.', 30 commands: [ 31 { 32 isRequiredOption: false, 33 options: ['--app <string>', 'app root directory'], 34 }, 35 { 36 isRequiredOption: false, 37 options: ['--appDir <string>', 'a path that contains multiple applications'], 38 }, 39 { 40 isRequiredOption: false, 41 options: ['--sdk <string>', 'sdk path, need to specify the ets directory, e.g sdk-root/version/ets'], 42 }, 43 { 44 isRequiredOption: false, 45 options: ['--sdkRoot <string>', 'sdk root path'], 46 }, 47 { 48 isRequiredOption: false, 49 options: ['--output <string>', 'the path to output the report'], 50 }, 51 { 52 isRequiredOption: false, 53 options: ['--format <json,excel>', 'format of the output report'], 54 }, 55 { 56 isRequiredOption: false, 57 options: ['--scanTest', 'scan ohosTest'], 58 }, 59 { 60 isRequiredOption: false, 61 options: ['--debug', 'output debug logs'], 62 } 63 ], 64 }; 65 } 66 67 async start(argv) { 68 if (!this.checkArguments(argv)) { 69 return; 70 } 71 const startTime = Date.now(); 72 if (argv.app) { 73 await this.scanSingleProject(argv); 74 } else if (argv.appDir) { 75 await this.scanMultiProject(argv); 76 } else if (argv.dir) { 77 await this.scanNonProject(argv); 78 } else { 79 Logger.info(this.logTag, 'see --help'); 80 } 81 Logger.info(this.logTag, `elapsed time ${Date.now() - startTime}`); 82 if (argv.debug) { 83 Logger.flush(this.getLogPath(argv)); 84 } 85 } 86 87 async scanSingleProject(argv) { 88 const collector = new ApiCollector(argv); 89 await collector.setLibPath(this.findLibPath()).setIncludeTest(argv.scanTest).start(); 90 } 91 92 async scanMultiProject(argv) { 93 if (!argv.sdk) { 94 const collector = new MultiProjectApiCollector(argv); 95 await collector.setLibPath(this.findLibPath()).setIncludeTest(argv.scanTest).start(); 96 } else { 97 Logger.error(this.logTag, '--appDir and --sdkRoot are used together, replace --sdk with --sdkRoot'); 98 } 99 } 100 101 async scanNonProject(argv) { 102 if (!argv.sdk) { 103 Logger.error(this.logTag, 'the --sdk is required when scanning non-project'); 104 return; 105 } 106 const apiCollector = new ApiCollector(argv); 107 await apiCollector.setLibPath(this.findLibPath()).start(); 108 } 109 110 getLogPath(argv) { 111 if (argv.output) { 112 return argv.output; 113 } 114 if (argv.appDir) { 115 return argv.appDir; 116 } 117 if (argv.app) { 118 return argv.app; 119 } 120 return __dirname; 121 } 122 123 findLibPath() { 124 if (process.env.bundleMode) { 125 return path.resolve(__dirname, 'libs'); 126 } 127 return path.resolve(__dirname, '..', 'libs'); 128 } 129 130 stop() { 131 132 } 133 134 checkArguments(argv) { 135 if (argv.sdk) { 136 const apiPath = path.resolve(argv.sdk, 'api'); 137 const componentPath = path.resolve(argv.sdk, 'component'); 138 if (!fs.existsSync(apiPath) || !fs.existsSync(componentPath)) { 139 Logger.error(this.logTag, '--sdk option need to specify the ets directory'); 140 return false; 141 } 142 } 143 return this.checkPathIsValid(argv.app) && 144 this.checkPathIsValid(argv.output) && 145 this.checkPathIsValid(argv.sdkRoot) && 146 this.checkPathIsValid(argv.appDir); 147 } 148 149 checkPathIsValid(path) { 150 if (path && !fs.existsSync(path)) { 151 Logger.error(this.logTag, `${path} not exists`); 152 return false; 153 } 154 return true; 155 } 156} 157 158module.exports = AppApiCollectorPlugin;