// The version, and the rule that there is only one of it. // // Three files declare a version and none of them can be derived from another: // Chrome and Firefox each need their own manifest, both are copied to dist/ // verbatim (tests/manifest.test.js asserts that what is in manifest/ is what // ships), and package.json's copy is what build.js compiles into the About // screen. So the single source of truth is enforced rather than generated — // they must all agree or there is no version and no build. // // Reading one of the three and ignoring the rest is what this replaces. That // shape cannot fail: it silently ships an extension whose About screen and // whose browser-reported version disagree, and whose release artifact is named // after whichever file the packager happened to read. // // Required by build.js, script/lib/package.js and tests/version.test.js, so // the build, the release artifacts and make check all apply the same rule to // the same files. "use strict"; const fs = require("fs"); const path = require("path"); const VERSION_SOURCES = [ "package.json", "manifest/chrome.json", "manifest/firefox.json", ]; // Every declared version, in VERSION_SOURCES order, as { source, version }. // A file that declares nothing usable fails here rather than being skipped: // a missing version is not agreement. function declaredVersions(root) { return VERSION_SOURCES.map((source) => { const file = path.join(root, source); let parsed; try { parsed = JSON.parse(fs.readFileSync(file, "utf8")); } catch (e) { throw new Error( `${source} could not be read as JSON: ${e.message}`, ); } const version = parsed.version; if (typeof version !== "string" || version.trim() === "") { throw new Error( `${source} declares no usable "version" (found ` + `${JSON.stringify(version)}). Every artifact is named and ` + `stamped with it, so there is nothing to build without it.`, ); } return { source, version }; }); } // The one version all three declare, or a failure naming every disagreeing // file and what it said. function resolveVersion(root) { const declared = declaredVersions(root); const distinct = [...new Set(declared.map((d) => d.version))]; if (distinct.length !== 1) { throw new Error( "the declared versions disagree, so this tree has no version: " + declared.map((d) => `${d.source}=${d.version}`).join(", ") + ". Set all of them to the same value: the manifests are what " + "the browser reports and package.json is what the About " + "screen shows, and a build that picked one of them would " + "ship the disagreement.", ); } return distinct[0]; } module.exports = { VERSION_SOURCES, declaredVersions, resolveVersion };