Skip to content
Snippets Groups Projects

Task update2024

Merged Johannes Kreiner requested to merge task_update2024 into master
Compare and Show latest version
2 files
+ 55
28
Compare changes
  • Side-by-side
  • Inline
Files
2
+ 72
50
const chalk = require('chalk');
const globby = require('globby');
const path = require('path');
const fs = require('fs');
const { argv } = require('yargs');
const { spawn } = require('child_process');
const Task = require('../task');
import chalk from 'chalk';
import * as globby from 'globby';
import path from 'node:path';
import fs from 'node:fs';
import yargs from 'yargs';
import { hideBin } from 'yargs/helpers';
import { spawn } from 'node:child_process';
import Task from '../task.js';
import process from 'node:process';
const argv = yargs(hideBin(process.argv)).argv;
/**
* This task handles the quality assurance
* @type {Lint}
*/
module.exports = class SizeGuard extends Task {
export default class SizeGuard extends Task {
async run(_subTask) {
if (!this._config.sizeGuard) {
this._logger.warning(`SizeGuard config not found in your sgc-config.`);
@@ -40,58 +43,52 @@ module.exports = class SizeGuard extends Task {
await this.createConfig(false);
const config = this.loadBranchConfig();
Object.keys(config).forEach((filename) => {
// Check if file exists
if (!fs.existsSync(config[filename].path)) {
return;
}
for (const filename of Object.keys(config)) {
const fileInfo = config[filename];
if (!fs.existsSync(fileInfo.path)) continue;
const stats = fs.statSync(config[filename].path);
const size = config[filename].filesize;
let diff = size - stats.size;
let diffPercentage = Math.round((1 - stats.size / size) * 10000) / 100;
const fileExtension = filename.split('.').pop();
const { maxIncrease } = this._config.sizeGuard[fileExtension];
const stableSize = await this.getStableFileSize(fileInfo.path);
const oldSize = fileInfo.filesize;
const diff = stableSize - oldSize;
let diffPercentage = Math.round((1 - stableSize / oldSize) * 10_000) / 100;
// No changes
if (diff === 0) {
return;
continue;
}
// Size of file decreased
if (diff > 0) {
if (diff < 0) {
this._logger.success(
`${filename} decreased ${diffPercentage}% (${diff / 1000} kB) in size.`,
`${filename} decreased ${diffPercentage}% (${Math.abs(diff / 1000)} kB) in size.`,
);
this.acceptSize(filename, true);
return;
await this.acceptSize(filename, true);
continue;
}
// Size of file increased
diff = Math.abs(diff);
diffPercentage = Math.round((1 - size / stats.size) * 10000) / 100;
// File got bigger
const fileExtension = path.extname(filename).replace('.', '');
const maxIncrease = (this._config.sizeGuard[fileExtension] || {}).maxIncrease || 0;
// Below the threshold
if (diff <= maxIncrease) {
this._logger.info(
`${filename} increased ${diffPercentage}% (${
`${filename} increased ${Math.abs(diffPercentage)}% (${
diff / 1000
} kB) and is below the threshold of ${maxIncrease / 1000} kB.`,
);
this.acceptSize(filename, true);
return;
await this.acceptSize(filename, true);
continue;
}
// Above the threshold
this._logger.error(
`${filename} increased ${diffPercentage}% (${
`${filename} increased ${Math.abs(diffPercentage)}% (${
diff / 1000
} kB) and is above the threshold (${
maxIncrease / 1000
} kB).\nPlease reduce your file size or accept this change with "sgc sizeGuard:accept ${filename}".`,
false,
);
});
}
}
/**
@@ -102,7 +99,7 @@ module.exports = class SizeGuard extends Task {
* @returns {Promise<void>}
*/
async acceptSize(file = '', hideMessage = false) {
const filename = argv._[1] ? argv._[1] : file;
const filename = argv._[1] || file;
const config = this.loadBranchConfig();
if (filename === '') {
await this.createConfig();
@@ -118,7 +115,7 @@ module.exports = class SizeGuard extends Task {
}
const stats = fs.statSync(config[filename].path);
const prevSize = config[filename].filesize;
const previousSize = config[filename].filesize;
config[filename].filesize = stats.size;
config[filename].timestamp = stats.mtimeMs;
@@ -126,7 +123,7 @@ module.exports = class SizeGuard extends Task {
this._logger.success(
`Accepted new file size of ${chalk.bold(
`${stats.size / 1000} kB`,
)} for ${filename}. (Previously: ${chalk.bold(`${prevSize / 1000} kB`)})`,
)} for ${filename}. (Previously: ${chalk.bold(`${previousSize / 1000} kB`)})`,
);
}
@@ -215,11 +212,11 @@ module.exports = class SizeGuard extends Task {
* @returns {Promise<{}>}
*/
async getCssSizes() {
const dist = this._getFullPath(this._config.directories.css);
const cssPaths = await globby([`${dist}/*.css`]);
const distribution = this._getFullPath(this._config.directories.css);
const cssPaths = await globby.globby([`${distribution}/*.css`]);
const sizes = await SizeGuard.getFileSizes(cssPaths);
if (Object.keys(sizes).length < 1) {
if (Object.keys(sizes).length === 0) {
this._logger.info('No css files found. Run "sgc css" to compile your sass files.');
}
@@ -232,11 +229,11 @@ module.exports = class SizeGuard extends Task {
* @returns {Promise<{}>}
*/
async getJsSizes() {
const dist = this._getFullPath(this._config.directories.javascriptDest);
const jsPaths = await globby([`${dist}/*.js`]);
const distribution = this._getFullPath(this._config.directories.javascriptDest);
const jsPaths = await globby.globby([`${distribution}/*.js`]);
const sizes = await SizeGuard.getFileSizes(jsPaths);
if (Object.keys(sizes).length < 1) {
if (Object.keys(sizes).length === 0) {
this._logger.info('No minified js files found. Run "sgc js" to compile your js files.');
}
@@ -250,19 +247,19 @@ module.exports = class SizeGuard extends Task {
* @returns {Promise<{}>}
*/
static async getFileSizes(paths) {
if (paths.length < 1) {
if (paths.length === 0) {
return {};
}
const sizes = {};
for (let i = 0; i < paths.length; i++) {
const stats = fs.statSync(paths[i]);
const filename = path.basename(paths[i]);
for (const path_ of paths) {
const stats = fs.statSync(path_);
const filename = path.basename(path_);
sizes[filename] = {
filesize: stats.size,
timestamp: stats.mtimeMs,
path: paths[i],
path: path_,
};
}
@@ -290,4 +287,29 @@ module.exports = class SizeGuard extends Task {
});
return `${currentBranch}`.trim();
}
};
/**
* Gets the stable file size as sometimes the file contents are
* cleared temporarily, resulting in wrongly reported sizes.
*
* @param {string} filePath
* @param {number} retries
* @param {number} delayMs
* @returns {Promise<number>}
*/
async getStableFileSize(filePath, retries = 3, delayMs = 100) {
for (let index = 0; index < retries; index++) {
const stats = fs.statSync(filePath);
if (stats.size > 0 || index === retries - 1) {
return stats.size;
}
await new Promise((resolve) => setTimeout(resolve, delayMs));
}
return new Promise((resolve) => {
const stats = fs.statSync(filePath);
resolve(stats.size);
});
}
}
Loading