• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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;