summaryrefslogtreecommitdiff
path: root/tools/doc/versions.js
blob: 7a4e2c3ff76b1ac7464c4df1c23fd54092e2bfc9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
'use strict';

const { readFileSync } = require('fs');
const path = require('path');
const srcRoot = path.join(__dirname, '..', '..');

let _versions;

const isRelease = () => {
  const re = /#define NODE_VERSION_IS_RELEASE 0/;
  const file = path.join(srcRoot, 'src', 'node_version.h');
  return !re.test(readFileSync(file, { encoding: 'utf8' }));
};

const getUrl = (url) => {
  return new Promise((resolve, reject) => {
    const https = require('https');
    const request = https.get(url, { timeout: 5000 }, (response) => {
      if (response.statusCode !== 200) {
        reject(new Error(
          `Failed to get ${url}, status code ${response.statusCode}`));
      }
      response.setEncoding('utf8');
      let body = '';
      response.on('aborted', () => reject());
      response.on('data', (data) => body += data);
      response.on('end', () => resolve(body));
    });
    request.on('error', (err) => reject(err));
    request.on('timeout', () => request.abort());
  });
};

module.exports = {
  async versions() {
    if (_versions) {
      return _versions;
    }

    // The CHANGELOG.md on release branches may not reference newer semver
    // majors of Node.js so fetch and parse the version from the master branch.
    const url =
      'https://raw.githubusercontent.com/nodejs/node/master/CHANGELOG.md';
    let changelog;
    try {
      changelog = await getUrl(url);
    } catch (e) {
      // Fail if this is a release build, otherwise fallback to local files.
      if (isRelease()) {
        throw e;
      } else {
        const file = path.join(srcRoot, 'CHANGELOG.md');
        console.warn(`Unable to retrieve ${url}. Falling back to ${file}.`);
        changelog = readFileSync(file, { encoding: 'utf8' });
      }
    }
    const ltsRE = /Long Term Support/i;
    const versionRE = /\* \[Node\.js ([0-9.]+)\][^-—]+[-—]\s*(.*)\r?\n/g;
    _versions = [];
    let match;
    while ((match = versionRE.exec(changelog)) != null) {
      const entry = { num: `${match[1]}.x` };
      if (ltsRE.test(match[2])) {
        entry.lts = true;
      }
      _versions.push(entry);
    }
    return _versions;
  }
};