Automatic resolution of latest and recommended forge builds.

You can now use 'latest' or 'recommended' as the forge version option in the generate commands.
Two new commands are provided to query the latest/recommended version of forge.
This commit is contained in:
Daniel Scalzi
2020-01-19 15:40:52 -05:00
parent f7173c4f5c
commit 8911f54039
4 changed files with 114 additions and 1 deletions

View File

@@ -79,6 +79,7 @@ Options:
* `--forge <string>` Specify forge version. This is WITHOUT the minecraft version (ex. 14.23.5.2847)
* OPTIONAL (default: null)
* If not provided forge will not be enabled.
* You can provide either `latest` or `recommended` to use the latest/recommended version of forge.
* `--liteloader <string>` Specify liteloader version.
* OPTIONAL (default: null)
* If not provided liteloader will not be enabled.
@@ -112,6 +113,23 @@ Options:
> `generate distribution --root C:/TestRoot --baseUrl https://myhost.com`
>
---
### Latest Forge
Get the latest version of Forge.
`latest-forge <version>`
---
### Recommended Forge
Get the recommended version of Forge. If no recommended build is available, it will pull the latest version.
`recommended-forge <version>`
---
## File Structure Setup (Tentative)

View File

@@ -8,6 +8,7 @@ import yargs from 'yargs'
import { DistributionStructure } from './model/struct/model/distribution.struct'
import { ServerStructure } from './model/struct/model/server.struct'
import { VersionSegmentedRegistry } from './util/VersionSegmentedRegistry'
import { VersionUtil } from './util/versionutil'
dotenv.config()
@@ -135,7 +136,7 @@ const generateServerCommand: yargs.CommandModule = {
default: null
})
},
handler: (argv) => {
handler: async (argv) => {
argv.root = getRoot()
console.debug(`Root set to ${argv.root}`)
@@ -143,6 +144,13 @@ const generateServerCommand: yargs.CommandModule = {
`\n\t├ Forge version: ${argv.forge}`,
`\n\t└ LiteLoader version: ${argv.liteloader}`)
if (VersionUtil.isPromotionVersion(argv.forge as string)) {
console.debug(`Resolving ${argv.forge} Forge Version..`)
const version = await VersionUtil.getPromotedForgeVersion(argv.version as string, argv.forge as string)
console.debug(`Forge version set to ${version}`)
argv.forge = version
}
const serverStruct = new ServerStructure(argv.root as string, getBaseURL())
serverStruct.createServer(
argv.id as string,
@@ -208,6 +216,42 @@ const validateCommand: yargs.CommandModule = {
}
}
const latestForgeCommand: yargs.CommandModule = {
command: 'latest-forge <version>',
describe: 'Get the latest version of forge.',
handler: async (argv) => {
console.debug(`Invoked latest-forge with version ${argv.version}.`)
const forgeVer = await VersionUtil.getPromotedForgeVersion(argv.version as string, 'latest')
console.log(`Latest version: Forge ${forgeVer} (${argv.version})`)
}
}
const recommendedForgeCommand: yargs.CommandModule = {
command: 'recommended-forge <version>',
describe: 'Get the recommended version of forge. Returns latest if there is no recommended build.',
handler: async (argv) => {
console.debug(`Invoked recommended-forge with version ${argv.version}.`)
const index = await VersionUtil.getPromotionIndex()
const mcVer = argv.version as string
let forgeVer = VersionUtil.getPromotedVersionStrict(index, mcVer, 'recommended')
if (forgeVer != null) {
console.log(`Recommended version: Forge ${forgeVer} (${mcVer})`)
} else {
console.log(`No recommended build for ${mcVer}. Checking for latest version..`)
forgeVer = VersionUtil.getPromotedVersionStrict(index, mcVer, 'latest')
if (forgeVer != null) {
console.log(`Latest version: Forge ${forgeVer} (${mcVer})`)
} else {
console.log(`No build available for ${mcVer}.`)
}
}
}
}
const testCommand: yargs.CommandModule = {
command: 'test <mcVer> <forgeVer>',
describe: 'Validate a distribution.json against the spec.',
@@ -234,6 +278,8 @@ yargs
.command(initCommand)
.command(generateCommand)
.command(validateCommand)
.command(latestForgeCommand)
.command(recommendedForgeCommand)
.command(testCommand)
.demandCommand()
.help()

View File

@@ -0,0 +1,8 @@
export interface PromotionsSlim {
homepage: string
promos: {
[id: string]: string
}
}

View File

@@ -1,5 +1,13 @@
import Axios from 'axios'
import { PromotionsSlim } from '../model/forge/promotionsslim'
export class VersionUtil {
public static readonly PROMOTION_TYPE = [
'recommended',
'latest'
]
public static readonly MINECRAFT_VERSION_REGEX = /(\d+).(\d+).(\d+)/
public static isMinecraftVersion(version: string) {
@@ -28,4 +36,37 @@ export class VersionUtil {
return false
}
public static isPromotionVersion(version: string) {
return VersionUtil.PROMOTION_TYPE.indexOf(version.toLowerCase()) > -1
}
public static async getPromotionIndex() {
const response = await Axios({
method: 'get',
url: 'https://files.minecraftforge.net/maven/net/minecraftforge/forge/promotions_slim.json',
responseType: 'json'
})
return response.data as PromotionsSlim
}
public static getPromotedVersionStrict(index: PromotionsSlim, minecraftVersion: string, promotion: string) {
const workingPromotion = promotion.toLowerCase()
return index.promos[`${minecraftVersion}-${workingPromotion}`]
}
public static async getPromotedForgeVersion(minecraftVersion: string, promotion: string) {
const workingPromotion = promotion.toLowerCase()
const res = await VersionUtil.getPromotionIndex()
let version = res.promos[`${minecraftVersion}-${workingPromotion}`]
if (version == null) {
console.warn(`No ${workingPromotion} version found for Forge ${minecraftVersion}.`)
console.warn(`Attempting to pull latest version instead.`)
version = res.promos[`${minecraftVersion}-latest`]
if (version == null) {
throw new Error(`No latest version found for Forge ${minecraftVersion}.`)
}
}
return version
}
}