• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2* Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development 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*/
15const path = require("path");
16const stdio = require("stdio");
17const fs = require('fs');
18const re = require("../tools/re");
19
20const { NapiLog } = require("../tools/NapiLog");
21const { print } = require("../tools/tool");
22const analyze = require("./analyze");
23const gen =  require("./generate");
24const { writeFile, createFolder } = require("../tools/FileRW");
25
26let ops = stdio.getopt({
27    'filename': { key: 'f', args: 1, description: ".h file", default: "" },
28    'out': { key: 'o', args: 1, description: "output directory", default: "." },
29    'loglevel': { key: 'l', args: 1, description: "Log Level: 0~3", default: "1" },
30    'serviceId': { key: 's', args: 1, description: "service register id: 9000~16777214", default: "9000" }
31});
32
33NapiLog.init(ops.loglevel, path.join("" + ops.out, "napi_gen.log"));
34
35let fileNames = ops.filename;
36var pathDir = ops.directory;
37if (fileNames == null && pathDir == null) {
38    NapiLog.logInfo("fileNames and pathDir both cannot be empty at the same time");
39} else if (pathDir && pathDir != '') {
40    readDirFiles();
41} else if (fileNames && fileNames != '') {
42    readFiles();
43}
44
45function readFiles() {
46    fileNames = fileNames.replace(/(^\s*)|(\s*$)/g, ''); // trim before and after espace
47    let regex = ',';
48    let filenameArray = fileNames.toString().split(regex);
49
50    let n = filenameArray.length;
51    for (let i = 0; i < n; i++) {
52        let fileName = filenameArray[i];
53        if (fileName !== ' ') {
54            fileName = fileName.replace(/(^\s*)|(\s*$)/g, '');
55            checkGenerate(fileName);
56        }
57    }
58}
59
60function readDirFiles() {
61    fs.readdir(pathDir + '', function (err, files) {
62        if (err) {
63            NapiLog.logError('readdir file error' + err);
64            return;
65        }
66        (function iterator(i) {
67            if (i === files.length) {
68                return;
69            }
70            fs.stat(path.join(pathDir + '', files[i]), function (err, data) {
71                if (err) {
72                    NapiLog.logError('read file error' + err);
73                    return;
74                }
75                if (data.isFile()) {
76                    let fileName = files[i];
77                    checkGenerate(pathDir + '/' + fileName);
78                }
79                iterator(i + 1);
80            });
81        })(0);
82    });
83}
84
85function wirte2Disk(fileInfo, destDir) {
86    let filePath = re.pathJoin(destDir, fileInfo.name);
87    writeFile(filePath, fileInfo.content);
88}
89
90function genServiceFile(fileName) {
91    // 1. h文件解析保存为结构体
92    let rootInfo = analyze.doAnalyze(fileName, ops);
93
94    // 2. 根据结构体生成代码
95    let fileContent = gen.doGenerate(rootInfo);
96
97    // 3. 创建service工程目录
98    let servicePath = re.pathJoin(ops.out, rootInfo.serviceName.toLowerCase() + "service");
99    let etcPath = re.pathJoin(servicePath, "etc");
100    let includePath = re.pathJoin(servicePath, "include");
101    let interfacePath = re.pathJoin(servicePath, "interface");
102    let profilePath = re.pathJoin(servicePath, "sa_profile");
103    let srcPath = re.pathJoin(servicePath, "src");
104    createFolder(servicePath);
105    createFolder(etcPath);
106    createFolder(includePath);
107    createFolder(interfacePath);
108    createFolder(profilePath);
109    createFolder(srcPath);
110
111    // 4. 生成代码保存为文件
112    wirte2Disk(fileContent.serviceCfgFile, etcPath);
113    wirte2Disk(fileContent.serviceCfgGnFile, etcPath);
114    wirte2Disk(fileContent.proxyHFile, includePath);
115    wirte2Disk(fileContent.stubHFile, includePath);
116    wirte2Disk(fileContent.serviceHFile, includePath);
117    wirte2Disk(fileContent.iServiceHFile, interfacePath);
118    wirte2Disk(fileContent.profileGnFile, profilePath);
119    wirte2Disk(fileContent.profileXmlFile, profilePath);
120    wirte2Disk(fileContent.proxyCppFile, srcPath);
121    wirte2Disk(fileContent.stubCppFile, srcPath);
122    wirte2Disk(fileContent.serviceCppFile, srcPath);
123    wirte2Disk(fileContent.clientCppFile, srcPath);
124    wirte2Disk(fileContent.iServiceCppFile, srcPath);
125    wirte2Disk(fileContent.buildGnFile, servicePath);
126    wirte2Disk(fileContent.bundleJsonFile, servicePath);
127}
128
129function checkGenerate(fileName) {
130    NapiLog.logInfo("check file []".format(fileName));
131    let suffix = fileName.split('.').pop().toLowerCase();
132    if (suffix === 'h') {
133        NapiLog.logInfo("Generating service code from file " + fileName);
134        genServiceFile(fileName);
135    } else {
136        NapiLog.logError('Only .h file is supported.');
137    }
138}
139
140let ret = NapiLog.getResult();
141if (ret[0]) {
142    print('success');
143    NapiLog.logInfo('success');
144}
145else {
146    print('Finish with error: ' + ret[1]);
147    NapiLog.logInfo('Finish with error: ' + ret[1]);
148}
149