-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathui-build.js
More file actions
381 lines (337 loc) · 14.6 KB
/
ui-build.js
File metadata and controls
381 lines (337 loc) · 14.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
/* NOTE: This is a Studio Managed File. DO NOT EDIT THIS FILE. Your changes may be reverted by Studio.*/
/**
* Check the node version to be make sure user installed project supported node.
* If ui-build runs with generatedAngularApp mode it should generate the angular app for the project.
* Build the angular app in WM mode or angular.
* If it is WM mode install app-runtime-wm-build npm package and copy the script to src/main/webapp based on the platform type(web/mobile)
* If it angular mode install codegen package and run the generate and build angular app script.
*
* CONSOLE ARGUMENTS:-
* nodeVMArgs:String: Node environment params (Eg: '--max-old-space-size=2040')
* ngBuildParams:String: Anglar build params (Eg: '--prod=true --source-map=false')
* runtimeUIVersion:String: Runtime version (Eg: 10.6.6-next.10243) and wavemaker-app-runtime-wm-build
* appSrc:String: Source folder to generate the angular app (current directory Eg: '.')
* appTarget: Target folder to save the generated app (Eg: 'target/ui-build/generated-app')
* buildType: Application build type (Eg: angular/wm)
* platformType: Application platform (Eg: web/mobile)
* optimizeUIBuild : By default this flag will be true. If it's windows platform we are making the flag to false, it means no optimisation for windows.
* generateAngularApp: To generate the angular app for the project
*/
const { execSync } = require("child_process");
const fs = require('fs');
const os = require('os');
const UI_BUILD_ERROR_LOG = 'UI BUILD ERROR';
const MSG_CODEGEN_LOG = 'CODEGEN ANGULAR APP: ';
const MSG_APP_RUNTIME_WM_BUILD_LOG = 'APP RUNTIME WM BUILD : ';
const MSG_ANGULAR_CODEGEN_SUCCESS = 'ANGULAR_CODEGEN_SUCCESS';
const MSG_APP_RUNTIME_WM_BUILD_SUCCESS = 'WAVEMAKER_APP_RUNTIME_WM_BUILD_SUCCESS';
const NPM_PACKAGE_SCOPE = '@wavemaker';
/**
* Read the console arguments and prepare the object.
* @returns console arguments as key value pairs
*/
const getArgs = (customArgs) => {
const args = {};
let arguments = customArgs || process.argv;
arguments
.slice(2, arguments.length)
.forEach(arg => {
if (arg.slice(0, 2) === '--') {
const longArg = arg.split('=');
const longArgFlag = longArg[0].slice(2, longArg[0].length);
const longArgValue = longArg.length > 2 ? longArg.slice(1, longArg.length).join('=') : longArg[1];
args[longArgFlag] = longArgValue;
}
});
return args;
}
const args = getArgs();
// TO capture the ctrl+C signal
process.on('SIGINT', function (e) {
console.log("Caught interrupt signal", e);
process.exit(1);
});
const EXECUTE_SYNC_CONFIG = { stdio: 'inherit' };
/**
* To check the npm package installation successs or not
* @param {*} path File path where installation success message was written
* @param {*} msg Success messsage to confirm that package was installed
* @returns boolean true/false
*/
const isNPMPackageExist = (path, msg) => {
if (fs.existsSync(path)) {
const successMsg = fs.readFileSync(path, { encoding: 'utf8', flag: 'r' });
if (successMsg == msg) {
return true;
}
} else {
return false;
}
}
/**
* Copy source to destination each file by navigating to the folder recursively
* @param {string} src Source folder to copy.
* @param {string} dest Destination folder to copy.
*/
const copyRecursiveSync = (src, dest) => {
let exists = fs.existsSync(src), stats = exists && fs.statSync(src), isDirectory = exists && stats.isDirectory();
if (isDirectory) {
if (!fs.existsSync(dest)) {
fs.mkdirSync(dest, { recursive: true });
}
fs.readdirSync(src).forEach(function (childItemName) {
copyRecursiveSync(src + '/' + childItemName, dest + '/' + childItemName);
});
} else {
fs.copyFileSync(src, dest);
}
};
/**
* To run the system command via node child process.
* @param {*} cmd Command in string format to execute in node environment
* @param {*} errorCallback callback if anything needs to be handled on command failure
*/
const executeSyncCmd = (cmd, errorCallback, msg) => {
try {
console.log(msg + 'Current running cmd: ' + cmd);
execSync(cmd, { stdio: 'inherit' });
console.log(msg + ' : ' + 'SUCCESS');
} catch (err) {
if (errorCallback) {
errorCallback(err);
}
console.log(msg + 'FAILED command: ' + cmd, err);
process.exit(err.code || err.pid);
}
}
/**
* Check node modules package were installed or not
* Create dir for packages with the version name
* Copy the generated angular app package.json to PATH_NPM_PACKAGE folder
* Run npm install
* Write success file to be make sure it was installed successfully.
*/
const downloadNPMPackage = (packageInfo) => {
const HOME_DIR = os.homedir();
const PATH_NPM_PACKAGE = (packageInfo.baseDir || HOME_DIR + '/.wm/node_modules/') + packageInfo.name + '/' + packageInfo.version;
const PATH_NPM_PACKAGE_SUCCESS = PATH_NPM_PACKAGE + '/.SUCCESS';
let isError = false;
// To check global app runtime node modules.
if (!isNPMPackageExist(PATH_NPM_PACKAGE_SUCCESS, packageInfo.successMsg)) {
fs.mkdirSync(PATH_NPM_PACKAGE, { recursive: true });
let npmInstallCMD = 'npm install ';
if (packageInfo.packageJsonFile && fs.existsSync(packageInfo.packageJsonFile)) {
fs.copyFileSync(packageInfo.packageJsonFile, PATH_NPM_PACKAGE + '/package.json');
} else {
let packageJsonFile = fs.openSync(PATH_NPM_PACKAGE + '/package.json', 'w');
fs.writeSync(packageJsonFile, '{}');
fs.closeSync(packageJsonFile);
npmInstallCMD = npmInstallCMD + '--prefix ' + PATH_NPM_PACKAGE + ' ';
npmInstallCMD = npmInstallCMD + packageInfo.scope + '/' + packageInfo.name + '@' + packageInfo.version;
}
executeSyncCmd(npmInstallCMD, () => {
isError = true;
console.log(packageInfo.infoMsg + ' Something wrong with npm installation');
}, packageInfo.infoMsg);
//only create a .SUCCESS file when there is no error
if(!isError) {
isError = false;
fs.writeFileSync(PATH_NPM_PACKAGE_SUCCESS, packageInfo.successMsg);
}
} else {
console.log(packageInfo.infoMsg + ' Node packages already installed!');
}
return PATH_NPM_PACKAGE;
}
/**
* Check the app-runtime-wm-build npm package already installed or not.
* Install the app-runtime-wm-build if package not yet installed.
* Based on the platform type copy the bundle script into '/src/main/webapp'
* @param {*} sourceDir
* @returns
*/
const buildAppInWMMode = (sourceDir, baseDir) => {
/**
* Download app-runtime-wm-build package and install if it doesn't exist
*/
let appRuntimeWMBuildPackageInfo = {
scope: NPM_PACKAGE_SCOPE,
version: args.runtimeUIVersion,
name: 'app-runtime-wm-build',
packageJsonFile: '',
successMsg: MSG_APP_RUNTIME_WM_BUILD_SUCCESS,
infoMsg: MSG_APP_RUNTIME_WM_BUILD_LOG
};
appRuntimeWMBuildPackageInfo.baseDir = baseDir;
const PATH_WAVEMAKER_APP_RUNTIME_WM_BUILD = downloadNPMPackage(appRuntimeWMBuildPackageInfo);
const FILE_PATH_WAVEMAKER_APP_RUNTIME_WM_BUILD = PATH_WAVEMAKER_APP_RUNTIME_WM_BUILD + '/node_modules/' + appRuntimeWMBuildPackageInfo.scope + '/' + appRuntimeWMBuildPackageInfo.name + '/';
const PLATFORM_TYPE = { WEB: 'wmapp', MOBILE: 'wmmobile' }
let bundleFolder = '';
if (args.platformType === PLATFORM_TYPE.WEB) {
bundleFolder = 'wmapp/';
} else if (args.platformType = PLATFORM_TYPE.MOBILE) {
bundleFolder = 'wmmobile/';
} else {
console.log(UI_BUILD_ERROR_LOG + ' Invalid script path!');
return;
}
copyRecursiveSync(FILE_PATH_WAVEMAKER_APP_RUNTIME_WM_BUILD + bundleFolder, sourceDir + '/target/ui-build/output-files/' + bundleFolder);
}
/**
* To check the platform is windows or not
* @returns boolean
*/
const isWindows = () => {
return process.platform === "win32";
}
/**
* Download angular codegen package and install if it is doesn't exist
* @returns Return the codegen package path
*/
const downloadCodegenAndGetTheInstallationPath = (basedir) => {
let codegenPackageInfo = {
scope: NPM_PACKAGE_SCOPE,
version: args.runtimeUIVersion,
name: 'angular-codegen',
packageJsonFile: '',
successMsg: MSG_ANGULAR_CODEGEN_SUCCESS,
infoMsg: MSG_CODEGEN_LOG
};
codegenPackageInfo.baseDir = basedir;
const PATH_ANGULAR_CODEGEN = downloadNPMPackage(codegenPackageInfo);
return PATH_ANGULAR_CODEGEN + '/node_modules/' + codegenPackageInfo.scope + '/' + codegenPackageInfo.name + '/';
}
/**
*
* @param {*} sourceDir project source directory to generate the angular app
* @param {*} ngBuildParams angular app build params along with cdn URL
* @param {*} codegenPath codegen path to generate the angular app
* Generate the angular app from codegen in target folder
*/
const generateAngularApp = async (sourceDir, ngBuildParams, codegenPath, appTarget) => {
const CODEGEN_PATH = codegenPath + 'src/codegen-cli.js';
if (fs.existsSync(CODEGEN_PATH)) {
let deployUrl = 'ng-bundle/';
if(ngBuildParams) {
let buildArgs = getArgs(ngBuildParams.split(' '));
if (buildArgs && buildArgs["deploy-url"]) {
deployUrl = buildArgs["deploy-url"];
}
}
const { generateCodegenAngularApp } = require(CODEGEN_PATH);
console.log(MSG_CODEGEN_LOG + 'Generating the angular App...');
await generateCodegenAngularApp(sourceDir, appTarget, deployUrl, (args.pwa === 'true' ? true : false), codegenPath, args.csp === 'true', args.spa === 'true');
console.log(MSG_CODEGEN_LOG + 'Angular app generated !');
} else {
console.log(MSG_CODEGEN_LOG + " : CODEGEN-CLI not found")
}
}
/**
*
* @param {*} sourceDir
* @param {*} appTarget
* @param {*} generate_page The generated page name
* @param {*} codegenPath
*/
const generateAngularAppPage = async (sourceDir, appTarget, generate_page, codegenPath) => {
const CODEGEN_PATH = codegenPath + 'src/codegen-cli.js';
if (fs.existsSync(CODEGEN_PATH)) {
const { generatePage } = require(CODEGEN_PATH);
await generatePage(sourceDir, appTarget, generate_page, codegenPath, args.csp === 'true');
} else {
console.log(MSG_CODEGEN_LOG + " : CODEGEN-CLI not found")
}
}
/**
* validate the cdn url and returns the angular build params
* @returns build params
*/
const getNgBuildParams = () => {
let cdnUrl = args.cdnUrl ? args.cdnUrl.trim() : "";
let ngBuildParams = args.ngBuildParams;
// If cdn-url exist add the build params as deploy-url
if (cdnUrl) {
ngBuildParams += ` --deploy-url=${cdnUrl}`;
}
return ngBuildParams;
}
/**
* Check codgen npm package already installed or not.
* Install the codegen if package not yet installed.
* Run generate and build angular script.
* Prepare the ng-build params deploy url if cdn url present in arguments
* @param {*} angularBuildConfig
* Properties: sourceDir,appTarget, baseDir
*/
const buildAppInAngularMode = async (angularBuildConfig) => {
let ngBuildParams = getNgBuildParams();
/**
* Download angular codegen package and install if it doesn't exist
*/
let pathAngularCodegen = downloadCodegenAndGetTheInstallationPath(angularBuildConfig.baseDir);
await generateAngularApp(angularBuildConfig.sourceDir, ngBuildParams, pathAngularCodegen, angularBuildConfig.appTarget);
const SCRIPT_PATH_ANGULAR_APP_GENERATOR = pathAngularCodegen + 'build-angular-app.js';
// build angular app.
if (fs.existsSync(SCRIPT_PATH_ANGULAR_APP_GENERATOR)) {
const { buildAngularApp } = require(SCRIPT_PATH_ANGULAR_APP_GENERATOR);
buildAngularApp({
runtimeUIVersion: args.runtimeUIVersion ,
codegenPath: pathAngularCodegen,
optimizeUIBuild: angularBuildConfig.optimizeUIBuild,
appTarget: angularBuildConfig.appTarget,
appSrc: angularBuildConfig.sourceDir,
nodeVMArgs: args.nodeVMArgs,
ngBuildParams: ngBuildParams
});
copyRecursiveSync(angularBuildConfig.sourceDir + '/target/ui-build/generated-app/dist/', angularBuildConfig.sourceDir + '/target/ui-build/output-files/');
} else {
console.log(UI_BUILD_ERROR_LOG + " build-angular-app.js not found! ");
}
}
/**
* generateAngularApp : If it is just to generate the angular app in project.
* If wm buildType , do the build in wavemaker mode.
* If angular buildType, do the build in angular mode.
*/
const init = async () => {
const BUILD_TYPE = { WM: 'wm', ANGULAR: 'angular' };
const sourceDir = (args.appSrc || '.');
let appTarget = (args.appTarget || 'target/ui-build/generated-app');
/**
* By default optimizeUIBuild will be true.
* If environment is windows then optimizeUIBuild flag will be false which install all node modules.
* If otherhen windows symlink the node_modules
*/
let optimizeUIBuild;
if(args.optimizeUIBuild) {
optimizeUIBuild = args.optimizeUIBuild === 'true';
} else {
optimizeUIBuild = !isWindows();
}
/**
* If optimization enabled download it in .wm folder at homedir
* If optimization not enabled download it in appTarget folder
*/
let baseDir = optimizeUIBuild ? undefined : appTarget.split('/').slice(0, 2).join('/') + '/';
if(args.generate_page){
// To generate the angular app specific page
const FILE_PATH_CODEGEN_INSTALLATION = downloadCodegenAndGetTheInstallationPath(baseDir);
await generateAngularAppPage(sourceDir, appTarget, args.generate_page, FILE_PATH_CODEGEN_INSTALLATION);
} else if (args.generateAngularApp) {
// TO generate the angular app
console.log('Angular app generation mode');
const FILE_PATH_CODEGEN_INSTALLATION = downloadCodegenAndGetTheInstallationPath(baseDir);
await generateAngularApp(sourceDir, getNgBuildParams(), FILE_PATH_CODEGEN_INSTALLATION, appTarget);
} else if (args.buildType === BUILD_TYPE.WM) {
buildAppInWMMode(sourceDir, baseDir);
} else if (args.buildType === BUILD_TYPE.ANGULAR) {
let angularBuildConfig = {
sourceDir: sourceDir,
appTarget: appTarget,
baseDir: baseDir,
optimizeUIBuild: optimizeUIBuild
};
await buildAppInAngularMode(angularBuildConfig);
}
}
init();