async downloadAndUnzip(url, saveDir) {
    await new Promise((resolve, reject) => {
      rimraf.sync(saveDir);
      fs.mkdirSync(saveDir);
      function handleError(err) {
        rimraf.sync(saveDir);
        reject(err);
      }

      urllib.request(
        url,
        {
          followRedirect: true,
          streaming: true,
        },
        (err, _, res) => {
          if (err) {
            return reject(err);
          }

          const extractor = tar.x({ C: saveDir, strip: 1 });
          extractor.on('error', handleError);
          extractor.on('end', resolve);

          res.pipe(extractor);
        }
      );
    });
  }
download tgz and extract
@param {String} url - tgzball url
@param {String} saveDir - target dir, will rm it first