Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 55 additions & 13 deletions ruby/updater/index.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env node
import { writeFile } from 'fs/promises'
import { readFile, writeFile } from 'fs/promises'
import { join } from 'path'
import { pathToFileURL } from 'url'

const rootPath = process.env.ROOT_PATH || process.cwd()

Expand Down Expand Up @@ -37,6 +38,11 @@ async function writeJsonFile(filename, content) {
await writeFile(filename, JSON.stringify(content, null, 2) + '\n');
}

async function readJsonFile(filename) {
const content = await readFile(filename, { encoding: 'utf-8' });
return JSON.parse(content);
}

Array.prototype.groupBy = function(keyFn) {
return this.reduce((result, value) => {
const key = keyFn(value);
Expand Down Expand Up @@ -68,18 +74,30 @@ Object.prototype.map = function(mapFn) {
);
}

async function run() {
const response = await fetch('https://raw.githubusercontent.com/postmodern/ruby-versions/master/ruby/checksums.sha256')
const responseBody = await response.text()
const regex = /^(?<checksum>\w+) (?<filename>ruby-(?<version>(?<majorMinorVersion>\d+\.\d+)\.\d+(?:-(\w+))?)\.tar\.gz)$/mg

const sources = [...responseBody.matchAll(regex)]
.map(({ groups: { checksum, filename, version, majorMinorVersion }}) => [version, {
url: `https://cache.ruby-lang.org/pub/ruby/${majorMinorVersion}/${filename}`,
sha256: checksum
}])
function parseRssSources(responseBody) {
return responseBody
.split(/<item>/g)
.slice(1)
.map(item => {
const tarballMatch = item.match(/https:\/\/cache\.ruby-lang\.org\/pub\/ruby\/(?<majorMinorVersion>\d+\.\d+)\/(?<filename>ruby-(?<version>\d+(?:\.\d+)+(?:-\w+)?)\.tar\.gz)(?=&quot;|<)/);
const checksumMatch = item.match(/SHA256:\s*(?<checksum>[0-9a-f]{64})/i);

if (!tarballMatch || !checksumMatch) {
return null;
}

const { filename, version, majorMinorVersion } = tarballMatch.groups;
const { checksum } = checksumMatch.groups;
return [version, {
url: `https://cache.ruby-lang.org/pub/ruby/${majorMinorVersion}/${filename}`,
sha256: checksum.toLowerCase(),
}];
})
.filter(Boolean)
.toObject();
}

function buildAliases(sources) {
const stableVersions = Object.keys(sources)
.filter(version => /^\d+\.\d+\.\d+$/.test(version))
.sort(compareVersion);
Expand All @@ -102,10 +120,34 @@ async function run() {
...minorVersions.map(([majorMinor, version]) => [`${majorMinor}.*`, version]),
};

await writeJsonFile(join(rootPath, "versions.json"), {
return aliases;
}

export async function run({
versionsPath = join(rootPath, 'versions.json'),
fetch = globalThis.fetch,
} = {}) {
const response = await fetch('https://www.ruby-lang.org/en/feeds/news.rss');
if (!response.ok) {
throw new Error(`Failed to fetch Ruby news RSS: ${response.status}`);
}

const responseBody = await response.text();
const existingContent = await readJsonFile(versionsPath);
const sources = {
...existingContent.sources,
...parseRssSources(responseBody),
};
const aliases = buildAliases(sources);

await writeJsonFile(versionsPath, {
sources,
aliases
});
}

run()
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
await run();
}

export { buildAliases, parseRssSources };
16 changes: 12 additions & 4 deletions ruby/versions.json
Original file line number Diff line number Diff line change
Expand Up @@ -991,6 +991,14 @@
"4.0.4": {
"url": "https://cache.ruby-lang.org/pub/ruby/4.0/ruby-4.0.4.tar.gz",
"sha256": "f35f6edfa3dabb3f723f9d0cf1906c6512ae77f4e412ab1e68cc6e91d230fa80"
},
"3.2.11": {
"url": "https://cache.ruby-lang.org/pub/ruby/3.2/ruby-3.2.11.tar.gz",
"sha256": "b3eeabd6636f334531db3ffdc3229eb05e524740e6c84fdc043720573cf2f8b2"
},
"3.3.11": {
"url": "https://cache.ruby-lang.org/pub/ruby/3.3/ruby-3.3.11.tar.gz",
"sha256": "59f0fafb1a59a05dc3765117af3fa68e153eb48254708549f321c1e9e078d7a0"
}
},
"aliases": {
Expand All @@ -1000,8 +1008,8 @@
"latest": "4.0.4",
"4.0": "4.0.4",
"3.4": "3.4.9",
"3.3": "3.3.10",
"3.2": "3.2.10",
"3.3": "3.3.11",
"3.2": "3.2.11",
"3.1": "3.1.7",
"3.0": "3.0.7",
"2.7": "2.7.8",
Expand All @@ -1016,8 +1024,8 @@
"4.*": "4.0.4",
"4.0.*": "4.0.4",
"3.4.*": "3.4.9",
"3.3.*": "3.3.10",
"3.2.*": "3.2.10",
"3.3.*": "3.3.11",
"3.2.*": "3.2.11",
"3.1.*": "3.1.7",
"3.0.*": "3.0.7",
"2.7.*": "2.7.8",
Expand Down