@bscotch/stitch
Version:
Stitch: The GameMaker Studio 2 Asset Pipeline Development Kit.
97 lines • 4.2 kB
JavaScript
import { StitchError } from '../utility/errors.js';
import { gms2Platforms } from './StitchProject.constants.js';
import paths from '../utility/paths.js';
const switchSearchRegex = new RegExp(`(?<pre><DisplayVersion>)(?<versionString>.*)(?<post></DisplayVersion>)`);
function versionKeyForPlatform(platform) {
let versionKey = `option_${platform}_version`;
if (platform == 'xboxone') {
versionKey = 'option_xbone_version';
}
return versionKey;
}
function setSwitchVersion(project, normalizedVersionString, fileName) {
const oldContent = project.storage.readBlobSync(fileName).toString();
const newContent = oldContent.replace(switchSearchRegex, `$1${normalizedVersionString}$3`);
project.storage.writeBlobSync(fileName, newContent);
}
function getSwitchVersion(project, fileName) {
const content = project.storage.readBlobSync(fileName).toString();
const newContent = content.match(switchSearchRegex)?.groups;
if (newContent) {
return newContent['versionString'];
}
else {
throw new StitchError(`Cannot parse the Switch *.nmeta file to obtain the version`);
}
}
/**
* Set the project version in all options files.
* (Note that the Switch options files do not include the version
* -- that must be set outside of GameMaker in the *.nmeta file).
* Can use one of:
* + "0.0.0.0" syntax (exactly as GameMaker stores versions)
* + "0.0.0" syntax (semver without prereleases -- the 4th value will always be 0)
* + "0.0.0-rc.0" syntax (the 4th number will be the RC number)
* The four numbers will appear in all cases as the string "major.minor.patch.candidate"
*/
export function setProjectVersion(project, versionString) {
const parts = versionString.match(/^(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)((\.(?<revision>\d+))|(-rc.(?<candidate>\d+)))?$/);
if (!parts) {
throw new StitchError(`Version string ${versionString} is not a valid format.`);
}
const { major, minor, patch, revision, candidate } = parts.groups;
const normalizedVersionString = [
major,
minor,
patch,
candidate || revision || '0',
].join('.');
const optionsDir = paths.join(project.storage.yypDirAbsolute, 'options');
const optionsFiles = project.storage.listFilesSync(optionsDir, true, [
'yy',
'nmeta',
]);
for (const file of optionsFiles) {
// Load it, change the version, and save
if (paths.extname(file) == '.yy') {
const content = project.storage.readJsonSync(file);
const platform = paths.basename(paths.dirname(file));
if (gms2Platforms.includes(platform)) {
const versionKey = versionKeyForPlatform(platform);
// Only set the version if that field exists in the file,
// otherwise GameMaker will crash.
if (content[versionKey]) {
content[versionKey] = normalizedVersionString;
project.storage.writeYySync(file, content);
}
}
}
// Switch *.nmeta file needs special treatment
else if (paths.extname(file) == '.nmeta') {
setSwitchVersion(project, normalizedVersionString, file);
}
else {
throw new StitchError(`Found unsupported file format in the options dir: ${file}`);
}
}
}
export function versionOnPlatform(project, platform) {
const optionsDir = paths.join(project.storage.yypDirAbsolute, 'options');
if (platform != 'switch') {
const optionsFile = paths.join(optionsDir, platform, `options_${platform}.yy`);
const versionKey = versionKeyForPlatform(platform);
return project.storage.readJsonSync(optionsFile)[versionKey];
}
else {
const optionsFile = project.storage.listFilesSync(optionsDir, true, [
'nmeta',
])?.[0];
if (optionsFile) {
return getSwitchVersion(project, optionsFile);
}
else {
throw new StitchError(`The project does not contain a valid *.nmeta file with version info.`);
}
}
}
//# sourceMappingURL=StitchProject.version.js.map