Home Manual Reference Source

src/services/building/buildCleaner.js

const fs = require('fs-extra');
const { provider } = require('jimple');
/**
 * Remove the builded files for the project and/or an specific target.
 */
class BuildCleaner {
  /**
   * Class constructor.
   * @param {Logger}                       appLogger            Used to inform the user when files
   *                                                            haven been removed of it there was
   *                                                            a problem removing them.
   * @param {Cleaner.clean}                cleaner              The function that removes
   *                                                            directories and files using glob
   *                                                            patterns.
   * @param {PathUtils}                    pathUtils            Necessary to build the paths to
   *                                                            clean.
   * @param {ProjectConfigurationSettings} projectConfiguration To read the project information and
   *                                                            get paths.
   * @param {Utils}                        utils                To replace plaholders on the targets
   *                                                            paths.
   */
  constructor(
    appLogger,
    cleaner,
    pathUtils,
    projectConfiguration,
    utils
  ) {
    /**
     * A local reference for the `appLogger` service.
     * @type {Logger}
     */
    this.appLogger = appLogger;
    /**
     * A local reference for the `cleaner` service function.
     * @type {Cleaner.clean}
     */
    this.cleaner = cleaner;
    /**
     * A local reference for the `pathUtils` service.
     * @type {PathUtils}
     */
    this.pathUtils = pathUtils;
    /**
     * All the project settings.
     * @type {ProjectConfigurationSettings}
     */
    this.projectConfiguration = projectConfiguration;
    /**
     * A local reference for the `utils` service.
     * @type {Utils}
     */
    this.utils = utils;
  }
  /**
   * Removes the entire distribution directory (where are the targets build are located).
   * @return {Promise<undefined,Error>}
   */
  cleanAll() {
    const { paths: { build } } = this.projectConfiguration;
    const dist = this.pathUtils.join(build);
    return this.cleaner(dist, '**')
    .then(() => {
      this.appLogger.success(
        `The distribution directory was successfully removed (${dist})`
      );
    })
    .catch((error) => {
      this.appLogger.error(
        `Error: There was an error while removing the distribution directory (${dist})`
      );

      return Promise.reject(error);
    });
  }
  /**
   * Removes the builded files of an specific target.
   * @param {Target} target The target information.
   * @return {Promise<undefined,Error>}
   */
  cleanTarget(target) {
    const { paths: { build } } = this.projectConfiguration;
    const dist = this.pathUtils.join(build);
    let firstStep;
    if (target.is.node && !target.bundle) {
      firstStep = fs.readdir(target.paths.source);
    } else {
      const items = [];
      const placeholders = {
        'target-name': target.name,
        hash: '*',
        name: '*',
        ext: '*',
      };
      Object.keys(target.originalOutput).forEach((type) => {
        const output = target.originalOutput[type];
        // JS
        const js = this.utils.replacePlaceholders(output.js, placeholders);
        items.push(js);
        if (target.is.browser) {
          items.push(`${js}.map`);
        }
        // Others
        items.push(...[
          this.utils.replacePlaceholders(output.css, placeholders),
          this.utils.replacePlaceholders(output.fonts, placeholders),
          this.utils.replacePlaceholders(output.images, placeholders),
        ]);
      });

      if (target.is.browser && target.html) {
        items.push(target.html.filename);
      }

      items.push(...items.map((item) => `${item}.gz`));
      firstStep = Promise.resolve(items);
    }

    return firstStep
    .then((items) => this.cleaner(target.paths.build, items))
    .then(() => {
      this.appLogger.success(
        `The files for '${target.name}' have been was successfully removed from ` +
        `the distribution directory (${dist})`
      );
    })
    .catch((error) => {
      this.appLogger.error(
        `Error: There was an error while removing the files for '${target.name}' ` +
        `from the distribution directory (${dist})`
      );

      return Promise.reject(error);
    });
  }
}
/**
 * The service provider that once registered on the app container will set an instance of
 * `BuildCleaner` as the `buildCleaner` service.
 * @example
 * // Register it on the container
 * container.register(buildCleaner);
 * // Getting access to the service instance
 * const buildCleaner = container.get('buildCleaner');
 * @type {Provider}
 */
const buildCleaner = provider((app) => {
  app.set('buildCleaner', () => new BuildCleaner(
    app.get('appLogger'),
    app.get('cleaner'),
    app.get('pathUtils'),
    app.get('projectConfiguration').getConfig(),
    app.get('utils')
  ));
});

module.exports = {
  BuildCleaner,
  buildCleaner,
};