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