Passed
Push — master ( e95921...ddbd1b )
by Dimas
13:28 queued 05:15
created

libs/src/compiler/gulpfile.ts   A

Complexity

Total Complexity 40
Complexity/F 4.44

Size

Lines of Code 373
Function Count 9

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 250
c 0
b 0
f 0
dl 0
loc 373
rs 9.2
wmc 40
mnd 31
bc 31
fnc 9
bpm 3.4444
cpm 4.4444
noi 0

9 Functions

Rating   Name   Duplication   Size   Complexity  
A gulpfile.ts ➔ build 0 22 4
A gulpfile.ts ➔ createApp 0 37 3
A gulpfile.ts ➔ single_tsCompile 0 24 2
A gulpfile.ts ➔ multiMinify 0 7 1
C gulpfile.ts ➔ node2browser 0 29 10
A gulpfile.ts ➔ assets_folder 0 13 1
A gulpfile.ts ➔ views 0 16 1
B gulpfile.ts ➔ typescriptCompiler 0 38 5
D gulpfile.ts ➔ minify 0 49 13

How to fix   Complexity   

Complexity

Complex classes like libs/src/compiler/gulpfile.ts often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
import * as gulp from "gulp";
2
import ts from "gulp-typescript";
3
import rename from "gulp-rename";
4
import * as fs from "fs";
5
import config from "../compiler/config";
6
import upath from "upath";
7
import path from "path";
8
import framework from "../compiler/index";
9
import log from "../compiler/log";
10
import process from "../compiler/process";
11
import core from "./core";
12
const root = process.root;
13
import sass from "sass"; // or require('node-sass');
14
import { exec, ExecException } from "child_process";
15
import sourcemaps from "gulp-sourcemaps";
16
import concat from "gulp-concat";
17
import uglify from "gulp-uglify";
18
import { localStorage } from "../node-localstorage/index";
19
import browserify from "browserify";
20
import browserify_source from "vinyl-source-stream";
21
import { fixDeps } from "./func";
22
localStorage.removeItem("compile");
23
console.clear();
24
25
/**
26
 * Build to /src/MVC/themes/assets/js/app.js
27
 * Minify Views Assets
28
 */
29
gulp.task("build", function () {
30
  return build();
31
});
32
33
gulp.task("build-clear", function () {
34
  return build(true);
35
});
36
37
/**
38
 * Build Project
39
 * @param withoutApp
40
 */
41
function build(withoutApp?: boolean) {
42
  try {
43
    var packageJson = root + "/package.json";
44
    if (fs.existsSync(packageJson)) {
45
      var json_pkg = JSON.parse(fs.readFileSync(packageJson).toString());
46
      fixDeps(json_pkg).then(function (json) {
47
        fs.writeFileSync(
48
          root + "/package.json",
49
          JSON.stringify(json, null, 2),
50
          {
51
            encoding: "utf-8",
52
          }
53
        );
54
      });
55
    }
56
  } catch (error) {}
57
  return createApp(withoutApp ? true : false);
58
}
59
60
// watch libs/js/**/* and views
61
gulp.task("watch", function () {
62
  console.clear();
63
  const files = [
64
    "./libs/js/**/*",
65
    "./libs/src/**/*",
66
    "./src/MVC/**/*",
67
    "./etc/**/*",
68
    "./" + config.app.views + "/**/*",
69
  ];
70
  log.log(
71
    log.random("Listening ") +
72
      files
73
        .map(function (item) {
74
          return log.random(upath.resolve(item));
75
        })
76
        .join(" ")
77
  );
78
79
  var compiler_runner: any = false;
80
  var run_watch = gulp
81
    .watch(files, null)
82
    .on("change", function (
83
      file: string | Buffer | import("url").URL | string[]
84
    ) {
85
      const trigger = function () {
86
        file = framework.normalize(path.resolve(file.toString()));
87
        /**
88
         * Check is library compiler or source compiler
89
         */
90
        const is_Lib = /libs\/(js|src)\//s.test(framework.normalize(file));
91
        const filename_log = framework.filelog(file);
92
93
        if (is_Lib) {
94
          var isCompiler = file.includes("/libs/compiler/");
95
          var isFramework = /((framework|app)\.(js|js.map)|\.map)$/s.test(file);
96
          if (isCompiler || isFramework) return;
97
          //console.log(file, isFramework);
98
          log.log(
99
            log.random("Library compiler triggered by ") +
100
              log.random(framework.filelog(file))
101
          );
102
          log.log(
103
            log
104
              .chalk()
105
              .yellow(`start compile ${log.random("src/MVC/themes/assets/js")}`)
106
          );
107
          if (compiler_runner) {
108
            log.log(log.error("Compiler still running"));
109
          } else {
110
            compiler_runner = setTimeout(function () {
111
              createApp(true);
112
              compiler_runner = null;
113
            }, 5000);
114
          }
115
        } else {
116
          if (/\.(js|scss|css)$/s.test(file)) {
117
            if (!/\.min\.(js|css)$/s.test(file)) {
118
              minify(file);
119
            }
120
          } else if (file.endsWith(".ts") && !file.endsWith(".d.ts")) {
121
            if (!/libs\/|libs\\/s.test(file)) {
122
              single_tsCompile(file);
123
            }
124
          } else {
125
            var reason = log.error(undefined);
126
            if (/\.(php|log|txt|htaccess)$/s.test(filename_log)) {
127
              reason = log.random("excluded");
128
            }
129
            log.log(`[${reason}] cannot modify ${log.random(filename_log)}`);
130
          }
131
        }
132
      };
133
      return trigger();
134
    });
135
  return run_watch;
136
});
137
138
gulp.task("default", gulp.series(["build", "watch"]));
139
140
/**
141
 * NodeJS to Browserify
142
 * @param target source javascript
143
 * @param destination destination folder
144
 * @param rename want to rename file ? give name or using default basename of target
145
 */
146
function node2browser(target?: string, destination?: string, rename?: string) {
147
  if (typeof rename != "string" || !rename || !rename.length) {
148
    rename = path.basename(target);
149
  }
150
151
  log.log(
152
    `Browserify ${log
153
      .chalk()
154
      .magentaBright(framework.filelog(target))} to ${log
155
      .chalk()
156
      .magentaBright(framework.filelog(destination))} renamed to ${log.success(
157
      rename
158
    )}`
159
  );
160
  return (
161
    browserify()
162
      .add(target) //"src/MVC/themes/assets/js/app.js"
163
      .bundle()
164
      //Pass desired output filename to vinyl-source-stream
165
      .pipe(browserify_source(rename)) //"app.js"
166
      // Start piping stream to tasks!
167
      .pipe(gulp.dest(destination))
168
  ); //"src/MVC/themes/assets/js/"
169
}
170
/**
171
 * minify assets
172
 * @param file
173
 */
174
export function minify(item: string | Buffer) {
175
  const exists = fs.existsSync(item);
176
  if (exists) {
177
    item = item.toString();
178
    var config:
179
      | string
180
      | {
181
          obfuscate: boolean;
182
        } = upath.normalizeSafe(
183
      root + "/src/MVC/config/" + item.replace(framework.root(), "")
184
    );
185
    config = framework.normalize(framework.root() + config);
186
    config = config.replace(/\.(js|css)/s, ".json");
187
    if (fs.existsSync(config)) {
188
      config = require(config);
189
    }
190
    if (item.endsWith(".scss") && !item.endsWith(".min.scss")) {
191
      framework.scss(item);
192
    } else if (item.endsWith(".css") && !item.endsWith(".min.css")) {
193
      framework.minCSS(item);
194
    } else if (item.endsWith(".js") && !item.endsWith(".min.js")) {
195
      if (!item.endsWith(".babel.js")) {
196
        framework.minJS(item);
197
        var deleteObfuscated = false;
198
        if (typeof config == "object") {
199
          if (config.hasOwnProperty("obfuscate")) {
200
            if (config.obfuscate) {
201
              framework.obfuscate(item);
202
            } else {
203
              deleteObfuscated = true;
204
            }
205
          } else {
206
            deleteObfuscated = true;
207
          }
208
        }
209
        if (deleteObfuscated) {
210
          var obfuscatedjs = item.replace(/\.js$/s, ".obfuscated.js");
211
          var obfuscatedminjs = item.replace(/\.js$/s, ".obfuscated.min.js");
212
          framework.unlink(obfuscatedjs);
213
          framework.unlink(obfuscatedminjs);
214
        }
215
      }
216
    } else if (item.endsWith(".ts") && !item.endsWith(".d.ts")) {
217
      if (!/libs\/|libs\\/s.test(item)) {
218
        single_tsCompile(item);
219
      }
220
    }
221
  }
222
}
223
224
/**
225
 * List views folder
226
 */
227
export function views() {
228
  var views = framework.readdir(root + `/${config.app.views}`);
229
  return views
230
    .filter(function (item) {
231
      return (
232
        /\.(js|scss|css|sass|less)$/.test(item) &&
233
        !/\.min\.(js|css)$/.test(item) &&
234
        !/\-ori|\-original|\-backup|\.bak/s.test(item)
235
      );
236
    })
237
    .map(function (asset) {
238
      return framework.normalize(asset);
239
    });
240
}
241
242
export function assets_folder() {
243
  var views = framework.readdir(root + "/assets");
244
  return views
245
    .filter(function (item) {
246
      return (
247
        /\.(js|scss|css|sass|less)$/.test(item) &&
248
        !/\.min\.(js|css)$/.test(item) &&
249
        !/\-ori|\-original|\-backup|\.bak/s.test(item)
250
      );
251
    })
252
    .map(function (asset) {
253
      return framework.normalize(asset);
254
    });
255
}
256
257
/**
258
 * minify multiple assets
259
 * @param assets
260
 */
261
export function multiMinify(assets: any[]) {
262
  assets.map(minify);
263
}
264
265
localStorage.removeItem("compile");
266
/**
267
 * Create App.js
268
 * @param withoutView false to not compile views javascripts
269
 */
270
export async function createApp(withoutView: boolean) {
271
  var exists = localStorage.getItem("compile");
272
  if (!exists) {
273
    localStorage.setItem("compile", "running");
274
    var target = upath.normalizeSafe(
275
      upath.resolve(upath.join(root, "src/MVC/themes/assets/js/app.js"))
276
    );
277
    await typescriptCompiler("tsconfig.build.json", root + "/").catch(function (
278
      err
279
    ) {
280
      log.log(log.error(err));
281
    });
282
    await typescriptCompiler("tsconfig.precompiler.json", root + "/").catch(
283
      function (err) {
284
        log.log(log.error(err));
285
      }
286
    );
287
    await typescriptCompiler("tsconfig.compiler.json", root + "/libs/").catch(
288
      function (err) {
289
        log.log(log.error(err));
290
      }
291
    );
292
    minify(target);
293
    if (!withoutView) {
294
      multiMinify(views());
295
    }
296
    localStorage.removeItem("compile");
297
    //node2browser(target, path.dirname(target));
298
  } else {
299
    log.log(
300
      log.error("Compiler lock process already exists ") +
301
        log.chalk().yellow("node index.js fix") +
302
        log.chalk().green(" to fix it")
303
    );
304
  }
305
}
306
307
/**
308
 * Single Typescript Compiler
309
 * @param target
310
 * @todo universal-framework typescript compiler support
311
 */
312
export function single_tsCompile(target: string) {
313
  var targetlog = log.chalk().magentaBright(framework.filelog(target));
314
  if (target.endsWith(".d.ts")) {
315
    log.log(`${targetlog} is declaration file`);
316
    return;
317
  }
318
  var dest = path.dirname(target);
319
  var filename = path.basename(target);
320
  log.log(
321
    `${targetlog} > ${log
322
      .chalk()
323
      .yellow(framework.filelog(target.replace(/\.ts$/, ".js")))} start`
324
  );
325
  var tsProject = ts.createProject({
326
    declaration: false,
327
    skipLibCheck: true,
328
  });
329
  return gulp.src(target).pipe(tsProject()).pipe(gulp.dest(dest));
330
}
331
332
/**
333
 * Typescript compiler
334
 * @param source
335
 * @param destination
336
 * @param callback
337
 */
338
export function typescriptCompiler(
339
  source: string,
340
  destination: string,
341
  callback: (arg0: any, arg1: any) => void = null
342
) {
343
  return new Promise((resolve, reject) => {
344
    exec(`tsc -p ${source}`, function (
345
      err: ExecException,
346
      stdout: string,
347
      stderr: string
348
    ) {
349
      if (!err) {
350
        if (typeof callback == "function") {
351
          callback(source, destination);
352
        }
353
        if (stdout.trim().length) {
354
          console.log(stdout);
355
        }
356
        if (stderr.trim().length) {
357
          console.log(stderr);
358
        }
359
        log.log(
360
          log.random("successfully compiled ") +
361
            log.success(path.basename(source))
362
        );
363
        resolve();
364
      } else {
365
        log.log(
366
          log.random("failed compile ") + log.error(path.basename(source))
367
        );
368
        reject(err.message);
369
      }
370
    });
371
  });
372
}
373