• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2
3const { readFileSync, writeFileSync } = require('fs');
4const path = require('path');
5const srcRoot = path.join(__dirname, '..', '..');
6
7const isRelease = () => {
8  const re = /#define NODE_VERSION_IS_RELEASE 0/;
9  const file = path.join(srcRoot, 'src', 'node_version.h');
10  return !re.test(readFileSync(file, { encoding: 'utf8' }));
11};
12
13const getUrl = (url) => {
14  return new Promise((resolve, reject) => {
15    const https = require('https');
16    const request = https.get(url, { timeout: 30000 }, (response) => {
17      if (response.statusCode !== 200) {
18        reject(new Error(
19          `Failed to get ${url}, status code ${response.statusCode}`));
20      }
21      response.setEncoding('utf8');
22      let body = '';
23      response.on('aborted', () => reject());
24      response.on('data', (data) => body += data);
25      response.on('end', () => resolve(body));
26    });
27    request.on('error', (err) => reject(err));
28    request.on('timeout', () => request.abort());
29  });
30};
31
32const kNoInternet = !!process.env.NODE_TEST_NO_INTERNET;
33const outFile = (process.argv.length > 2 ? process.argv[2] : undefined);
34
35async function versions() {
36  // The CHANGELOG.md on release branches may not reference newer semver
37  // majors of Node.js so fetch and parse the version from the master branch.
38  const url =
39    'https://raw.githubusercontent.com/nodejs/node/master/CHANGELOG.md';
40  let changelog;
41  const file = path.join(srcRoot, 'CHANGELOG.md');
42  if (kNoInternet) {
43    changelog = readFileSync(file, { encoding: 'utf8' });
44  } else {
45    try {
46      changelog = await getUrl(url);
47    } catch (e) {
48      // Fail if this is a release build, otherwise fallback to local files.
49      if (isRelease()) {
50        throw e;
51      } else {
52        console.warn(`Unable to retrieve ${url}. Falling back to ${file}.`);
53        changelog = readFileSync(file, { encoding: 'utf8' });
54      }
55    }
56  }
57  const ltsRE = /Long Term Support/i;
58  const versionRE = /\* \[Node\.js ([0-9.]+)\]\S+ (.*)\r?\n/g;
59  const _versions = [];
60  let match;
61  while ((match = versionRE.exec(changelog)) != null) {
62    const entry = { num: `${match[1]}.x` };
63    if (ltsRE.test(match[2])) {
64      entry.lts = true;
65    }
66    _versions.push(entry);
67  }
68  return _versions;
69}
70
71versions().then((v) => {
72  if (outFile) {
73    writeFileSync(outFile, JSON.stringify(v));
74  } else {
75    console.log(JSON.stringify(v));
76  }
77}).catch((err) => {
78  console.error(err);
79  process.exit(1);
80});
81