diff --git a/ruby/updater/index.mjs b/ruby/updater/index.mjs index 88375ee..ac63d5d 100644 --- a/ruby/updater/index.mjs +++ b/ruby/updater/index.mjs @@ -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() @@ -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); @@ -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 = /^(?\w+) (?ruby-(?(?\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(//g) + .slice(1) + .map(item => { + const tarballMatch = item.match(/https:\/\/cache\.ruby-lang\.org\/pub\/ruby\/(?\d+\.\d+)\/(?ruby-(?\d+(?:\.\d+)+(?:-\w+)?)\.tar\.gz)(?="|<)/); + const checksumMatch = item.match(/SHA256:\s*(?[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); @@ -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() \ No newline at end of file +if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) { + await run(); +} + +export { buildAliases, parseRssSources }; diff --git a/ruby/versions.json b/ruby/versions.json index 93e8447..e8b07f6 100644 --- a/ruby/versions.json +++ b/ruby/versions.json @@ -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": { @@ -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", @@ -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",