docs: function buildMain(inpOptions, callback) {
    const options = Object.assign({}, inpOptions);
  
    // pre process app
    const tmpObj = tmp.dirSync({ mode: '0755', unsafeCleanup: true });
    const tmpPath = tmpObj.name;
  
    // todo check if this is still needed on later version of packager
    const packagerConsole = new PackagerConsole();
  
    const progress = new DishonestProgress(5);
  
    async.waterfall(
      [
        (cb) => {
          progress.tick('inferring');
          optionsFactory(options)
            .then((result) => {
              cb(null, result);
            })
            .catch((error) => {
              cb(error);
            });
        },
        (opts, cb) => {
          progress.tick('copying');
          buildApp(opts.dir, tmpPath, opts, (error) => {
            if (error) {
              cb(error);
              return;
            }
            // Change the reference file for the Electron app to be the temporary path
            const newOptions = Object.assign({}, opts, {
              dir: tmpPath,
            });
            cb(null, newOptions);
          });
        },
        (opts, cb) => {
          progress.tick('icons');
          iconBuild(opts, (error, optionsWithIcon) => {
            cb(null, optionsWithIcon);
          });
        },
        (opts, cb) => {
          progress.tick('packaging');
          // maybe skip passing icon parameter to electron packager
          let packageOptions = maybeNoIconOption(opts);
          // maybe skip passing other parameters to electron packager
          packageOptions = maybeNoAppCopyrightOption(packageOptions);
          packageOptions = maybeNoAppVersionOption(packageOptions);
          packageOptions = maybeNoBuildVersionOption(packageOptions);
          packageOptions = maybeNoVersionStringOption(packageOptions);
          packageOptions = maybeNoWin32metadataOption(packageOptions);
  
          packagerConsole.override();
  
          packager(packageOptions)
            .then((appPathArray) => {
              packagerConsole.restore(); // restore console.error
              cb(null, opts, appPathArray); // options still contain the icon to waterfall
            })
            .catch((error) => {
              packagerConsole.restore(); // restore console.error
              cb(error, opts); // options still contain the icon to waterfall
            });
        },
        (opts, appPathArray, cb) => {
          progress.tick('finalizing');
          // somehow appPathArray is a 1 element array
          const appPath = getAppPath(appPathArray);
          if (!appPath) {
            cb();
            return;
          }
  
          maybeCopyIcons(opts, appPath, (error) => {
            cb(error, appPath);
          });
        },
      ],
      (error, appPath) => {
        packagerConsole.playback();
        callback(error, appPath);
      },
    );
  }