4
0
Fork 0
mirror of https://github.com/Anvilcraft/modpacktools synced 2024-06-10 22:49:26 +02:00

use argparse4j for args

This commit is contained in:
LordMZTE 2020-08-01 19:22:21 +02:00
parent 8863e703bc
commit dfe682f41e
10 changed files with 103 additions and 37 deletions

View file

@ -34,6 +34,7 @@ dependencies {
compile 'com.j2html:j2html:1.4.0'
compile 'org.reflections:reflections:0.9.12'
compile 'commons-io:commons-io:2.7'
compile 'net.sourceforge.argparse4j:argparse4j:0.8.1'
}
compileKotlin {

View file

@ -8,6 +8,7 @@ import ley.anvil.modpacktools.command.ICommand
import ley.anvil.modpacktools.util.ModpackJsonHandler
import ley.anvil.modpacktools.util.config.Config
import ley.anvil.modpacktools.util.config.MissingConfigValueException
import net.sourceforge.argparse4j.inf.ArgumentParserException
import okhttp3.Dispatcher
import okhttp3.OkHttpClient
import java.io.File
@ -73,6 +74,8 @@ fun runCommand(args: Array<out String>) {
e.message?.let {println(it)}
println('\n')
e.printStackTrace()
} catch(e: ArgumentParserException) {
println("Invalid args: ${e.message}")
}
}
}

View file

@ -2,6 +2,7 @@ package ley.anvil.modpacktools.command
import ley.anvil.modpacktools.CONFIG
import ley.anvil.modpacktools.MPJH
import net.sourceforge.argparse4j.inf.ArgumentParserException
import org.reflections.Reflections
import org.reflections.scanners.SubTypesScanner
import kotlin.reflect.KClass
@ -25,9 +26,10 @@ class CommandLoader(private val pkg: String) {
* @param args the args to pass to the command
* @throws ConfigMissingException if the command requires a config and it is not found
* @throws ModpackJsonMissingException if the command requires a modpackjson file and it is not found
* @throws ArgumentParserException if the arguments are not valid
*/
@JvmStatic
@Throws(ConfigMissingException::class, ModpackJsonMissingException::class)
@Throws(ConfigMissingException::class, ModpackJsonMissingException::class, ArgumentParserException::class)
fun ICommand.runStatic(args: Array<out String>): CommandReturn {
if(this.needsConfig && !CONFIG.exists)
throw ConfigMissingException()
@ -35,7 +37,7 @@ class CommandLoader(private val pkg: String) {
if(this.needsModpackjson && MPJH.asWrapper == null)
throw ModpackJsonMissingException()
return this.execute(args)
return this.execute(this.parser.parseArgs(args.slice(1 until args.size).toTypedArray()))
}
}
@ -87,7 +89,8 @@ class CommandLoader(private val pkg: String) {
* @param args the arguments passed into the command
* @return the return of the command
* @throws NoSuchElementException if there's no command with the given name
* @throws ArgumentParserException if the arguments are not valid
*/
@Throws(NoSuchElementException::class)
@Throws(NoSuchElementException::class, ConfigMissingException::class, ModpackJsonMissingException::class, ArgumentParserException::class)
fun runCommand(name: String, args: Array<out String>) = commands.computeIfAbsent(name) {throw NoSuchElementException("Command $name Not Found")}.runStatic(args)
}

View file

@ -1,5 +1,8 @@
package ley.anvil.modpacktools.command
import net.sourceforge.argparse4j.inf.ArgumentParser
import net.sourceforge.argparse4j.inf.Namespace
/**
* This must be implemented by all commands
*/
@ -10,7 +13,9 @@ interface ICommand {
* @param args Arguments for the Command
* @return If the Command was executed successful
*/
fun execute(args: Array<out String>): CommandReturn
fun execute(args: Namespace): CommandReturn
val parser: ArgumentParser
/**
* this is the name of the command

View file

@ -11,6 +11,9 @@ import ley.anvil.modpacktools.util.FileDownloader
import ley.anvil.modpacktools.util.manifest.convertAStoManifest
import ley.anvil.modpacktools.util.mergeTo
import ley.anvil.modpacktools.util.toZip
import net.sourceforge.argparse4j.ArgumentParsers
import net.sourceforge.argparse4j.inf.ArgumentParser
import net.sourceforge.argparse4j.inf.Namespace
import org.apache.commons.io.FileUtils
import org.apache.commons.io.FilenameUtils
import java.io.File
@ -23,11 +26,15 @@ import java.util.zip.ZipOutputStream
object BuildTwitch : ICommand {
override val name: String = "buildtwitch"
override val helpMessage: String = "builds a twitch export"
override val parser: ArgumentParser = ArgumentParsers.newFor("BuildTwitch")
.build()
.description(helpMessage)
private val tempDir by lazy {File(CONFIG.config.pathOrException<String>("Locations/tempDir"))}
private val tmp: File by lazy {File(tempDir, "twitch")}
private val downloadDir by lazy {File(tempDir, "download")}
override fun execute(args: Array<out String>): CommandReturn {
override fun execute(args: Namespace): CommandReturn {
val wr = MPJH.asWrapper!!
val ml = convertAStoManifest(wr)
val archiveName = "${wr.json.id}-${wr.defaultVersion.versionName}-twitch"

View file

@ -11,6 +11,12 @@ import ley.anvil.modpacktools.command.CommandReturn.Companion.fail
import ley.anvil.modpacktools.command.CommandReturn.Companion.success
import ley.anvil.modpacktools.command.ICommand
import ley.anvil.modpacktools.command.LoadCommand
import net.sourceforge.argparse4j.ArgumentParsers
import net.sourceforge.argparse4j.impl.Arguments.storeTrue
import net.sourceforge.argparse4j.impl.type.EnumStringArgumentType
import net.sourceforge.argparse4j.impl.type.FileArgumentType
import net.sourceforge.argparse4j.inf.ArgumentParser
import net.sourceforge.argparse4j.inf.Namespace
import org.apache.commons.csv.CSVFormat
import org.apache.commons.csv.CSVPrinter
import org.apache.commons.io.IOUtils
@ -21,19 +27,34 @@ import java.nio.charset.StandardCharsets
@LoadCommand
object CreateModlist : ICommand {
override val name: String = "createmodlist"
override val helpMessage: String = "This creates a modlist either as html or csv file. if the \'all\' option is supplied, not only mods will be included Syntax: <html/csv> <outFile> [all]"
override val helpMessage: String = "This creates a modlist either as html or csv file."
override val parser: ArgumentParser = run {
val parser = ArgumentParsers.newFor("CreateModlist").build()
.description(helpMessage)
override fun execute(args: Array<out String>): CommandReturn {
if(!args.checkArgs())
return fail("invalid args")
parser.addArgument("-a", "--all")
.action(storeTrue())
.help("If this is set, all relations and not only be mods will be in the list")
val outFile = File(args[2])
parser.addArgument("type")
.type(EnumStringArgumentType(Formats::class.java))
.help("What format the mod list should be made in")
parser.addArgument("file")
.type(FileArgumentType())
.help("What file the mod list should be written to")
parser
}
override fun execute(args: Namespace): CommandReturn {
val outFile = args.get<File>("file")
if(outFile.exists())
return fail("File already exists!")
val all = args.getOrNull(3) == "all"
return if(args[1] == "html")
val all = args.get<Boolean>("all") ?: false
return if(args.get<Formats>("type") == Formats.HTML)
doHtml(outFile, all)
else
doCsv(outFile, all)
@ -127,11 +148,5 @@ object CreateModlist : ICommand {
return mods.sortedBy {m -> m.name?.toLowerCase()}
}
private fun Array<out String>.checkArgs(): Boolean =
//must be right length
this.size >= 3 &&
//second option must be html or csv
this[1] in arrayOf("html", "csv") &&
//3rd option must either be "all" or nothing
this.getOrElse(3) {"all"} == "all"
enum class Formats {HTML, CSV}
}

View file

@ -3,13 +3,17 @@ package ley.anvil.modpacktools.commands
import ley.anvil.addonscript.wrapper.FileOrLink
import ley.anvil.modpacktools.MPJH
import ley.anvil.modpacktools.command.CommandReturn
import ley.anvil.modpacktools.command.CommandReturn.Companion.fail
import ley.anvil.modpacktools.command.CommandReturn.Companion.success
import ley.anvil.modpacktools.command.ICommand
import ley.anvil.modpacktools.command.LoadCommand
import ley.anvil.modpacktools.util.FileDownloader
import ley.anvil.modpacktools.util.FileDownloader.ExistingFileBehaviour.OVERWRITE
import ley.anvil.modpacktools.util.FileDownloader.ExistingFileBehaviour.SKIP
import net.sourceforge.argparse4j.ArgumentParsers
import net.sourceforge.argparse4j.impl.Arguments.storeTrue
import net.sourceforge.argparse4j.impl.type.FileArgumentType
import net.sourceforge.argparse4j.inf.ArgumentParser
import net.sourceforge.argparse4j.inf.Namespace
import java.io.File
import java.net.URL
import java.nio.file.Paths
@ -18,13 +22,23 @@ import java.util.stream.Collectors.toMap
@LoadCommand
object DownloadMods : ICommand {
override val name: String = "downloadmods"
override val helpMessage: String = "Downloads all mods. force always downloads files even if they are already present Syntax: <OutDir> [force]"
override val helpMessage: String = "Downloads all mods."
override val parser: ArgumentParser = run {
val parser = ArgumentParsers.newFor("DownloadMods")
.build()
.description(helpMessage)
override fun execute(args: Array<out String>): CommandReturn {
if(!args.checkArgs())
return fail("Invalid Args")
parser.addArgument("dir")
.type(FileArgumentType().verifyCanCreate())
.help("the directory to download the mods to")
parser.addArgument("-f", "--force")
.action(storeTrue())
.help("if true, mods that are already in the download folder will be downloaded again")
parser
}
override fun execute(args: Namespace): CommandReturn {
val json = MPJH.asWrapper
val fileList = mutableListOf<FileOrLink>()
for (rel in json!!.defaultVersion!!.getRelations(arrayOf("client"), arrayOf("mod"))!!)
@ -37,7 +51,7 @@ object DownloadMods : ICommand {
.filter {it.installer == "internal.dir:mods"}
.collect(toMap<FileOrLink, URL, File>(
{URL(it.link)},
{File(args[1], Paths.get(URL(it.link).path).fileName.toString())},
{File(args.get<File>("dir"), Paths.get(URL(it.link).path).fileName.toString())},
{_: File, f: File -> f}
)),
{r: FileDownloader.DownloadFileTask.Return ->
@ -48,10 +62,8 @@ object DownloadMods : ICommand {
println(r.exception.message)
}
},
if("force" in args) OVERWRITE else SKIP
if(args["force"]) OVERWRITE else SKIP
)
return success()
}
private fun Array<out String>.checkArgs(): Boolean = this.size >= 2 && this.elementAtOrNull(2)?.equals("force") ?: true
}

View file

@ -9,6 +9,10 @@ import ley.anvil.modpacktools.command.CommandReturn.Companion.fail
import ley.anvil.modpacktools.command.CommandReturn.Companion.success
import ley.anvil.modpacktools.command.ICommand
import ley.anvil.modpacktools.command.LoadCommand
import net.sourceforge.argparse4j.ArgumentParsers
import net.sourceforge.argparse4j.impl.type.FileArgumentType
import net.sourceforge.argparse4j.inf.ArgumentParser
import net.sourceforge.argparse4j.inf.Namespace
import java.io.File
import java.io.FileReader
import java.io.FileWriter
@ -17,15 +21,20 @@ import java.io.FileWriter
object Import : ICommand {
override val name: String = "import"
override val helpMessage: String = "Converts a given manifest file to a modpackjson file"
override val parser: ArgumentParser = ArgumentParsers.newFor("Import")
.build()
.apply {
addArgument("manifest")
.help("the manifest file to import")
.type(FileArgumentType().verifyIsFile())
}
override val needsModpackjson: Boolean = false
override val needsConfig: Boolean = false
override fun execute(args: Array<out String>): CommandReturn {
if(!args.checkArgs())
return fail("Invalid Args")
override fun execute(args: Namespace): CommandReturn {
val outFile = MPJH.modpackJsonFile
val manifest = File(args[1])
val manifest = args.get<File>("manifest")
if(!manifest.exists() || outFile.exists())
return fail("$manifest not found or $outFile already exists.")
@ -37,6 +46,4 @@ object Import : ICommand {
mpjWriter.close()
return success("Converted sucessfully")
}
private fun Array<out String>.checkArgs(): Boolean = this.size == 2
}

View file

@ -6,6 +6,9 @@ import ley.anvil.modpacktools.command.CommandReturn
import ley.anvil.modpacktools.command.CommandReturn.Companion.success
import ley.anvil.modpacktools.command.ICommand
import ley.anvil.modpacktools.command.LoadCommand
import net.sourceforge.argparse4j.ArgumentParsers
import net.sourceforge.argparse4j.inf.ArgumentParser
import net.sourceforge.argparse4j.inf.Namespace
import java.io.File
import java.io.FileWriter
@ -13,10 +16,14 @@ import java.io.FileWriter
object Init : ICommand {
override val name: String = "init"
override val helpMessage: String = "initializes the MPT dev environment (currently only creates config file)"
override val parser: ArgumentParser = ArgumentParsers.newFor("Init")
.build()
.description(helpMessage)
override val needsConfig: Boolean = false
override val needsModpackjson: Boolean = false
override fun execute(args: Array<out String>): CommandReturn {
override fun execute(args: Namespace): CommandReturn {
if(!CONFIG.exists)
CONFIG.copyConfig()

View file

@ -5,16 +5,22 @@ import ley.anvil.modpacktools.command.CommandReturn.Companion.success
import ley.anvil.modpacktools.command.ICommand
import ley.anvil.modpacktools.command.LoadCommand
import ley.anvil.modpacktools.runCommand
import net.sourceforge.argparse4j.ArgumentParsers
import net.sourceforge.argparse4j.inf.ArgumentParser
import net.sourceforge.argparse4j.inf.Namespace
@LoadCommand
object Shell : ICommand {
override val name: String = "shell"
override val helpMessage: String = "opens a shell where mpt commands can be entered in a loop."
override val parser: ArgumentParser = ArgumentParsers.newFor("Shell")
.build()
.description(helpMessage)
override val needsConfig: Boolean = false
override val needsModpackjson: Boolean = false
override fun execute(args: Array<out String>): CommandReturn {
override fun execute(args: Namespace): CommandReturn {
println("enter \'exit\' to exit the shell\n")
while(true) {