text: /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
  * regarding copyright ownership.  The ASF licenses this file
  * to you under the Apache License, Version 2.0 (the
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
  *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  * KIND, either express or implied.  See the License for the
  * specific language governing permissions and limitations
  * under the License.
  */
  
  
  // Prepare release materials like mail, release note
  
  const commander = require('commander');
  const fse = require('fs-extra');
  const pathTool = require('path');
  const https = require('https');
  
  commander
      .usage('[options]')
      .description([
          'Generate source release'
      ].join('\n'))
      .option(
          '--rcversion <version>',
          'Release version'
      )
      .option(
          '--commit <commit>',
          'Hash of commit'
      )
      .option(
          '--repo <repo>',
          'Repo'
      )
      .option(
          '--out <out>',
          'Out directory. Default to be tmp/release-mail'
      )
      .parse(process.argv);
  
  const outDir = pathTool.resolve(process.cwd(), commander.out || 'tmp/release-materials');
  const releaseCommit = commander.commit;
  if (!releaseCommit) {
      throw new Error('Release commit is required');
  }
  const repo = commander.repo || 'apache/echarts';
  
  let rcVersion = commander.rcversion + '';
  if (rcVersion.startsWith('v')) {   // tag may have v prefix, v5.1.0
      rcVersion = rcVersion.substr(1);
  }
  if (rcVersion.indexOf('-rc.') < 0) {
      throw new Error('Only rc version is accepeted.');
  }
  
  const parts = /(\d+)\.(\d+)\.(\d+)\-rc\.(\d+)/.exec(rcVersion);
  if (!parts) {
      throw new Error(`Invalid version number ${rcVersion}`);
  }
  
  const major = +parts[1];
  const minor = +parts[2];
  const patch = +parts[3];
  const rc = +parts[4];
  
  const stableVersion = `${major}.${minor}.${patch}`;
  const releaseFullName = `Apache ECharts ${stableVersion} (release candidate ${rc})`;
  
  console.log('[Release Repo] ' + repo);
  console.log('[Release Verion] ' + rcVersion);
  console.log('[Release Commit] ' + releaseCommit);
  console.log('[Release Name] ' + releaseFullName);
  
  const voteTpl = fse.readFileSync(pathTool.join(__dirname, './template/vote-release.tpl'), 'utf-8');
  const announceTpl = fse.readFileSync(pathTool.join(__dirname, './template/announce-release.tpl'), 'utf-8');
  const voteUntil = new Date(+new Date() + (72 + 12) * 3600 * 1000);   // 3.5 day.
  
  fse.ensureDirSync(outDir);
  fse.writeFileSync(
      pathTool.resolve(outDir, 'vote.txt'),
      voteTpl.replace(/{{ECHARTS_RELEASE_VERSION}}/g, rcVersion)
          .replace(/{{ECHARTS_RELEASE_VERSION_FULL_NAME}}/g, releaseFullName)
          .replace(/{{ECHARTS_RELEASE_COMMIT}}/g, releaseCommit)
          .replace(/{{VOTE_UNTIL}}/g, voteUntil.toISOString()),
      'utf-8'
  );
  
  fse.writeFileSync(
      pathTool.resolve(outDir, 'announce.txt'),
      announceTpl.replace(/{{ECHARTS_RELEASE_VERSION}}/g, stableVersion)
          .replace(/{{ECHARTS_RELEASE_COMMIT}}/g, releaseCommit),
      'utf-8'
  );
  
  
  // Fetch RELEASE_NOTE
  https.get({
      hostname: 'api.github.com',
      path: `/repos/${repo}/releases`,
      headers: {
          'User-Agent': 'NodeJS'
      }
  }, function (res) {
      console.log(`https://api.github.com/repos/${repo}/releases`);
      if (res.statusCode !== 200) {
          console.error(`Failed to fetch releases ${res.statusCode}`);
          res.resume();
          return;
      }
  
      res.setEncoding('utf8');
      let rawData = '';
      res.on('data', (chunk) => {
          rawData += chunk;
      });
      res.on('end', () => {
          let releaseNote = '';
          try {
              const releases = JSON.parse(rawData);
              const found = releases.find(release => release.name === rcVersion);
              if (!found) {
                  console.error('Can\'t found release');
              }
              else {
                  releaseNote = found.body.trim();
                  if (!releaseNote) {
                      console.error('Release description is empty');
                  }
              }
          }
          catch (e) {
              console.error(e.message);
          }
  
          const firstLine = releaseNote.split('\n')[0];
          if (firstLine.indexOf(stableVersion) < 0) {
              // Add version if release note is not start with version.
          }
          releaseNote = `## ${stableVersion}\n\n${releaseNote}`;
  
          fse.writeFileSync(
              pathTool.resolve(outDir, 'RELEASE_NOTE.txt'),
              releaseNote,
              'utf-8'
          );
      });
    }).on('error', (e) => {
        console.error('Error', e);
    });