diff --git a/README.md b/README.md index 8ad074af..b8f4b36a 100644 --- a/README.md +++ b/README.md @@ -38,20 +38,124 @@ Commands: crafting tweaks given a share code or pack file ``` +For [patch](#patch) command [see below](#patch-schemas) for a description of [PatchSet](#patchset) and [PatchDefinition](#patchdefinition) JSON schemas. + +For [install-curseforge](#install-curseforge) and [install-modrinth-modpack](#install-modrinth-modpack) commands, refer to [the exclude/include file schema](#excludeinclude-file-schema). + + + +### asciify + +``` +Usage: mc-image-helper asciify +Converts UTF-8 on stdin to ASCII by escaping Unicode characters +``` + +### assert + +``` +Usage: mc-image-helper assert [COMMAND] +Provides assertion operators for verifying container setup +Commands: + fileExists + fileNotExists + jsonPathEquals + propertyEquals +``` + +### compare-versions + +``` +Usage: mc-image-helper compare-versions + +Used for shell scripting, exits with success(0) when comparison is satisfied or +1 when not + + + +``` + +### curseforge-files + +``` +Usage: mc-image-helper curseforge-files [-h] [--disable-api-caching] + [--api-base-url=] + [--api-key=] + [--default-category=] + [--game-version=] + [--mod-loader=] [-o=DIR] + [[--api-cache-ttl=OPERATION=DURATION]... + [--api-cache-default-ttl=DURATION]] + [[--connection-pool-max-idle-timeout=DUR + ATION] + [--tls-handshake-timeout=DURATION] + [--connection-pool-pending-acquire-timeo + ut=DURATION] + [--http-response-timeout=DURATION]] [REF + [,REF...]...] +Download and manage individual mod/plugin files from CurseForge + [REF[,REF...]...] Can be |':', |'@', |, project page URL, file page URL, + '@' + If not specified, any previous mod/plugin files are + removed + --api-base-url= + Allows for overriding the CurseForge Eternal API used + Can also be passed via CF_API_BASE_URL + --api-cache-default-ttl=DURATION + Set default/fallback TTL in ISO-8601 duration format. + Default: P2D + --api-cache-ttl=OPERATION=DURATION + Set individual operation TTLs + --api-key= An API key allocated from the Eternal developer + console at https://console.curseforge.com/ + Can also be passed via CF_API_KEY + --connection-pool-max-idle-timeout=DURATION + + --connection-pool-pending-acquire-timeout=DURATION + + --default-category= + When providing slugs, a category is required to + qualify those + --disable-api-caching + + --game-version= + The Minecraft version + Can also be passed via VERSION + -h, --help + --http-response-timeout=DURATION + The response timeout to apply to HTTP operations. + Parsed from ISO-8601 format. Default: PT30S + --mod-loader= + One of Any, Forge, Cauldron, LiteLoader, Fabric, + Quilt, NeoForge + -o, --output-directory=DIR + + --tls-handshake-timeout=DURATION + Default: PT30S +``` + ### find ``` -Usage: mc-image-helper find [-hq] [--delete] [--fail-no-matches] - [--only-shallowest] [--output-count-only] - [--stop-on-first] [--format=] - [--max-depth=N] [-t=] [--exclude-name=glob[, - glob...]]... [--name=glob[,glob...]]... startDir... +Usage: mc-image-helper find [-hq] [--delete] [--delete-empty-directories] + [--fail-no-matches] [--only-shallowest] + [--output-count-only] [--stop-on-first] + [--format=] [--max-depth=N] [--min-depth=N] + [--exclude-name=glob[\s*,\s*glob...]]... + [--name=glob[\s*,\s*glob...]]... [-t=[\s*, + \s*...]]... startDir... Specialized replacement for GNU's find startDir... One or more starting directories --delete Deletes the matched entries. When searching for directories, each directory and its contents will be recursively deleted. - --exclude-name=glob[,glob...] + --delete-empty-directories + Deletes a traversed directory if it becomes empty + after matching files/directories within it were + deleted + --exclude-name=glob[\s*,\s*glob...] One or more glob patterns to exclude by looking at name part of the path. If a pattern matches a directory's name, then its entire subtree is @@ -63,35 +167,51 @@ Specialized replacement for GNU's find %h leading directory of the entry %P path of the entry relative to the starting point -h, --help - --max-depth=N Unlimited depth if zero or negative - --name=glob[,glob...] One or more glob patterns to match name part of the + --max-depth=N Unlimited depth if negative + --min-depth=N Minimum match depth where 0 is a starting point + --name=glob[\s*,\s*glob...] + One or more glob patterns to match name part of the path --only-shallowest --output-count-only -q, --quiet --stop-on-first - -t, --type= Valid values: file, directory + -t, --type=[\s*,\s*...] + Valid values: file, directory ``` ### get ``` -Usage: mc-image-helper get [-hsz] [--exists] [--log-progress-each] +Usage: mc-image-helper get [-hz] [--exists] [--log-progress-each] [--output-filename] [--skip-existing] - [--accept=] [--json-path=] + [--apikey=] [--json-path=] + [--json-value-when-missing=] [-o=FILE|DIR] [--prune-depth=] - [--uris-file=] [--prune-others=GLOB[, - GLOB...]]... [URI[,URI...]...] + [--retry-count=] + [--retry-delay=] + [--uris-file=] + [--accept=[\s*, + \s*...]]... [--prune-others=GLOB + [\s*,\s*GLOB...]]... [URI[\s*,\s*URI...]...] Download a file - [URI[,URI...]...] The URI of the resource to retrieve. When the + [URI[\s*,\s*URI...]...] + The URI of the resource to retrieve. When the output is a directory, more than one URI can be requested. - --accept= + --accept=[\s*,\s*...] + Specifies the accepted content type(s) to use with + the request + --apikey= Specifies the accept header to use with the request --exists Test if the given URIs are retrievable -h, --help Show this usage and exit --json-path= Extract and output a JsonPath from the response + --json-value-when-missing= + Defines the value that is output when the requested + JSON path does not exist. An empty value results + in a non-zero exit code. --log-progress-each Output a log as each URI is being retrieved -o, --output=FILE|DIR Specifies the name of a file or directory to write the downloaded content. If a directory is @@ -103,125 +223,162 @@ Download a file --prune-depth= When using prune-others, this specifies how deep to search for files to prune - --prune-others=GLOB[,GLOB...] + --prune-others=GLOB[\s*,\s*GLOB...] When set and using an output directory, files that match the given glob patterns will be pruned if not part of the download set. For example *.jar - -s, --silent Don't output logs even if there's an error + --retry-count= + + --retry-delay= + in seconds --skip-existing Do not retrieve if the output file already exists --uris-file= A file that contains a URL per line -z, --skip-up-to-date Skips re-downloading a file that is up to date ``` +### github + +``` +Usage: mc-image-helper github [COMMAND] +Commands: + download-latest-asset From the latest release, downloads the first matching + asset, and outputs the downloaded filename +``` + +### hash + +``` +Usage: mc-image-helper hash +Outputs an MD5 hash of the standard input +``` + ### install-curseforge ``` -Usage: mc-image-helper install-curseforge [-h] [--force-synchronize] - [--file-id=] [--filename-matcher=STR] [--modpack-page-url=URL] - [--output-directory=DIR] [--parallel-downloads=] - [--results-file=FILE] [--slug=] [--exclude-include-file=FILE | - [[--exclude-mods=PROJECT_ID|SLUG[,| PROJECT_ID|SLUG...]]... - [--force-include-mods=PROJECT_ID|SLUG[,| PROJECT_ID|SLUG...]]...]] - [COMMAND] - --exclude-include-file=FILE - A JSON file that contains global and per modpack - exclude/include declarations. See README for - schema. - --exclude-mods=PROJECT_ID|SLUG[,| PROJECT_ID|SLUG...] - For mods that need to be excluded from server - deployments, such as those that don't label as - client +Usage: mc-image-helper install-curseforge [-h] [--disable-api-caching] + [--force-reinstall-modloader] [--force-synchronize] + [--overrides-skip-existing] [--api-base-url=] + [--api-key=] [--downloads-repo=DIR] [--file-id=] + [--filename-matcher=STR] [--missing-mods-filename=] + [--modpack-manifest=PATH] [--modpack-page-url=URL] [--modpack-zip=PATH] + [-o=DIR] [--results-file=FILE] [--set-level-from=] + [--slug=] [--ignore-missing-files=[, + |...]]... + [--overrides-exclusions=[NL or , + ...]]... [[--exclude-include-file=FILE|URI] + [[--exclude-mods=PROJECT_ID|SLUG[,|PROJECT_ID|SLUG...]]... + [--force-include-mods=PROJECT_ID|SLUG[,|PROJECT_ID|SLUG...]]...]] + [[--connection-pool-max-idle-timeout=DURATION] + [--tls-handshake-timeout=DURATION] + [--connection-pool-pending-acquire-timeout=DURATION] + [--http-response-timeout=DURATION]] + [[--api-cache-ttl=OPERATION=DURATION]... + [--api-cache-default-ttl=DURATION]] [COMMAND] +Downloads, installs, and upgrades CurseForge modpacks + --api-base-url= + Allows for overriding the CurseForge Eternal API + used + --api-cache-default-ttl=DURATION + Set default/fallback TTL in ISO-8601 duration + format. + Default: P2D + --api-cache-ttl=OPERATION=DURATION + Set individual operation TTLs + --api-key= An API key allocated from the Eternal developer + console at https://console.curseforge.com/ + Can also be passed via CF_API_KEY + --connection-pool-max-idle-timeout=DURATION + + --connection-pool-pending-acquire-timeout=DURATION + + --disable-api-caching + --downloads-repo=DIR A local directory that will supply pre-downloaded + mod and modpack files that are marked disallowed + for automated download. The subdirectories mods, + modpacks, and worlds will also be consulted + accordingly. + --exclude-include-file=FILE|URI + A JSON file that contains global and per modpack + exclude/include declarations. See README for + schema. + --exclude-mods=PROJECT_ID|SLUG[,|PROJECT_ID|SLUG...] + For mods that need to be excluded from server + deployments, such as those that don't label as + client --file-id= - --filename-matcher=STR - Substring to select specific modpack filename - --force-include-mods=PROJECT_ID|SLUG[,| PROJECT_ID|SLUG...] - Some mods incorrectly declare client-only support, - but still need to be included in a server deploy + --filename-matcher=STR Substring to select specific modpack filename + --force-include-mods=PROJECT_ID|SLUG[,|PROJECT_ID|SLUG...] + Some mods incorrectly declare client-only support, + but still need to be included in a server deploy. + This can also be used to selectively override + exclusions. + --force-reinstall-modloader + --force-synchronize -h, --help - --modpack-page-url=URL - URL of a modpack page such as https://www. - curseforge. - com/minecraft/modpacks/all-the-mods-8or a file - page https://www.curseforge. - com/minecraft/modpacks/all-the-mods-8/files/424839 - 0 - --output-directory=DIR - - --parallel-downloads= - Default: 4 - --results-file=FILE A key=value file suitable for scripted environment - variables. Currently includes - SERVER: the entry point jar or script - --slug= The short-URL identifier + --http-response-timeout=DURATION + The response timeout to apply to HTTP operations. + Parsed from ISO-8601 format. Default: PT30S + --ignore-missing-files=[,|...] + These files will be ignored when evaluating if the + modpack is up to date + --missing-mods-filename= + + --modpack-manifest=PATH + Similar to --modpack-zip but provide the manifest. + json from the modpack. + Can be a local file path or a URL to a manifest. + --modpack-page-url=URL URL of a modpack page such as + https://www.curseforge. + com/minecraft/modpacks/all-the-mods-8or a file's + page + https://www.curseforge. + com/minecraft/modpacks/all-the-mods-8/files/42483 + 90 + --modpack-zip=PATH Path to a pre-downloaded modpack client zip file + that can be used when modpack author disallows + automation. + Can also be passed via CF_MODPACK_ZIP + -o, --output-directory=DIR + --overrides-exclusions=[NL or , + ...] + Excludes files from the overrides that match these + ant-style patterns + * : matches any non-slash characters + ** : matches any characters + ? : matches one character + --overrides-skip-existing + When enabled, existing files will not be replaced + by overrides content from the modpack + --results-file=FILE A key=value file suitable for scripted environment + variables. Currently includes + SERVER: the entry point jar or script + --set-level-from= + When WORLD_FILE, a world file included the modpack + will be unzipped into a folder under 'saves' and + referenced as 'LEVEL' in the results file. + When OVERRIDES and the overrides contains a world + save directory (contains level.dat), then that + directory will be referenced as 'LEVEL' in the + results file. + In either case, existing world data will be + preserved and skipped if it already exists. + Valid values: WORLD_FILE, OVERRIDES + --slug= The short-URL identifier + --tls-handshake-timeout=DURATION + Default: PT30S Commands: schemas Output relevant JSON schemas ``` -#### Exclude/Include File Schema - -```json -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "title": "Mods Exclude/Include File Content", - "type": "object", - "additionalProperties": false, - "properties": { - "globalExcludes": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Mods by slug|id to exclude for all modpacks" - }, - "globalForceIncludes": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Mods by slug|id to force include for all modpacks" - }, - "modpacks": { - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/ExcludeIncludes" - }, - "description": "Specific exclude/includes by modpack slug" - } - }, - "definitions": { - "ExcludeIncludes": { - "type": "object", - "additionalProperties": false, - "properties": { - "excludes": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Mods by slug|id to exclude for this modpack" - }, - "forceIncludes": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Mods by slug|id to force include for this modpack" - } - } - } - } -} -``` - ### install-fabric-loader ``` Usage: mc-image-helper install-fabric-loader [-h] [--output-directory=DIR] - [--results-file=FILE] (--from-local-file=FILE | --from-url=URL | - [--minecraft-version=VERSION [--installer-version=VERSION] - [--loader-version=VERSION]]) + [--results-file=FILE] [--from-local-file=FILE | --from-url=URL | + [[--minecraft-version=VERSION] [--installer-version=VERSION] + [--loader-version=VERSION]]] Provides a few ways to obtain a Fabric loader with simple cleanup of previous loader instances --from-local-file=FILE @@ -244,71 +401,281 @@ loader instances ### install-forge ``` -Usage: mc-image-helper install-forge [-hV] [--forge-version=] - --minecraft-version= +Usage: mc-image-helper install-forge [-h] [--force-reinstall] + [--minecraft-version=VERSION] [--output-directory=DIR] - [--results-file=] - --forge-version= - A specific Forge version or to auto-resolve the version - provide 'latest' or 'recommended'. Default value is - recommended - -h, --help Show this help message and exit. - --minecraft-version= + [--results-file=FILE] + [--forge-installer= | + [--forge-version=]] + [[--connection-pool-max-idle-timeout=DURATI + ON] [--tls-handshake-timeout=DURATION] + [--connection-pool-pending-acquire-timeout= + DURATION] + [--http-response-timeout=DURATION]] +Downloads and installs a requested version of Forge + --connection-pool-max-idle-timeout=DURATION + --connection-pool-pending-acquire-timeout=DURATION + + --force-reinstall + --forge-installer= + Use a local forge installer + --forge-version= + A specific Forge version or to auto-resolve the + version provide 'latest' or 'recommended'. + Default value is recommended + -h, --help + --http-response-timeout=DURATION + The response timeout to apply to HTTP operations. + Parsed from ISO-8601 format. Default: PT30S + --minecraft-version=VERSION + 'latest', which is the default, or a specific + version --output-directory=DIR - --results-file= - A key=value file suitable for scripted environment variables. - Currently includes - SERVER: the entry point jar or script + --results-file=FILE A key=value file suitable for scripted environment + variables. Currently includes + SERVER: the entry point jar or script + --tls-handshake-timeout=DURATION + Default: PT30S ``` ### install-modrinth-modpack ``` -Usage: mc-image-helper install-modrinth-modpack [-hV] - [--force-modloader-reinstall] [--force-synchronize] - [--api-base-url=] [--default-version-type=TYPE] +Usage: mc-image-helper install-modrinth-modpack [--force-modloader-reinstall] + [--force-synchronize] [--api-base-url=] + [--default-exclude-includes=FILE|URI] [--default-version-type=TYPE] [--game-version=] [--loader=] [--output-directory=DIR] --project= - [--results-file=FILE] [--version-id=] - [[--tls-handshake-timeout=DURATION] [--http-response-timeout=DURATION] - [--connection-pool-max-idle-timeout=DURATION]] + [--results-file=FILE] [--version=] + [--exclude-files=[,|...]]... + [--force-include-files=[, + |...]]... + [--ignore-missing-files=[, + |...]]... + [--overrides-exclusions=[NL or , + ...]]... + [[--connection-pool-max-idle-timeout=DURATION] + [--tls-handshake-timeout=DURATION] + [--connection-pool-pending-acquire-timeout=DURATION] + [--http-response-timeout=DURATION]] Supports installation of Modrinth modpacks along with the associated mod loader --api-base-url= - Default: https://api.modrinth.com/v2 + Default: https://api.modrinth.com --connection-pool-max-idle-timeout=DURATION + --connection-pool-pending-acquire-timeout=DURATION + + --default-exclude-includes=FILE|URI + A JSON file that contains global and per modpack + exclude/include declarations. See README for + schema. --default-version-type=TYPE Valid values: release, beta, alpha Default: release + --exclude-files=[,|...] + Files to exclude, such as improperly declared + client mods. It will match any part of the file's + name/path. + --force-include-files=[,|...] + Files to force include that were marked as + non-server mods. It will match any part of the + file's name/path. --force-modloader-reinstall --force-synchronize --game-version= - Applicable Minecraft version where default is any - version - -h, --help Show this help message and exit. + Applicable Minecraft version + Default: (any) --http-response-timeout=DURATION The response timeout to apply to HTTP operations. Parsed from ISO-8601 format. Default: PT30S - --loader= Valid values: fabric, forge where default is any - loader + --ignore-missing-files=[,|...] + These files will be ignored when evaluating if the + modpack is up to date + --loader= Valid values: fabric, forge, quilt, neoforge + Default: (any) --output-directory=DIR + --overrides-exclusions=[NL or , + ...] + Excludes files from the overrides that match these + ant-style patterns + * : matches any non-slash characters + ** : matches any characters + ? : matches one character --project= One of - Project ID or slug - Project page URL - Project file URL + - Custom URL of a hosted modpack file + - Local path to a modpack file + --results-file=FILE A key=value file suitable for scripted environment + variables. Currently includes + SERVER: the entry point jar or script + --tls-handshake-timeout=DURATION + Default: PT30S + --version, --version-id= + Version ID, name, or number from the file's metadata + Default chooses newest file based on game version, + loader, and/or default version type +``` + +### install-neoforge + +``` +Usage: mc-image-helper install-neoforge [-h] [--force-reinstall] + [--minecraft-version=VERSION] + [--neoforge-version=] + [--output-directory=DIR] + [--results-file=FILE] + [[--connection-pool-max-idle-timeout=DUR + ATION] + [--tls-handshake-timeout=DURATION] + [--connection-pool-pending-acquire-timeo + ut=DURATION] + [--http-response-timeout=DURATION]] +Downloads and installs a requested version of NeoForge + --connection-pool-max-idle-timeout=DURATION + + --connection-pool-pending-acquire-timeout=DURATION + + --force-reinstall + -h, --help + --http-response-timeout=DURATION + The response timeout to apply to HTTP operations. + Parsed from ISO-8601 format. Default: PT30S + --minecraft-version=VERSION + 'latest', which is the default, or a specific + version to narrow NeoForge version selection + --neoforge-version= + A specific NeoForge version, 'latest', or 'beta'. + Default value is latest + --output-directory=DIR + --results-file=FILE A key=value file suitable for scripted environment variables. Currently includes SERVER: the entry point jar or script --tls-handshake-timeout=DURATION Default: PT30S - -V, --version Print version information and exit. - --version-id= - Version ID (not name) from the file's metadata +``` + +### install-paper + +``` +Usage: mc-image-helper install-paper [--check-updates] [--base-url=] + [-o=] + [--results-file=FILE] [--url= + | [[--project=] [--build=] + [--channel=] + [--version=]]] + [--connection-pool-max-idle-timeout=DURATIO + N | [--tls-handshake-timeout=DURATION] | + --connection-pool-pending-acquire-timeout=D + URATION | + [--http-response-timeout=DURATION]] +Installs selected PaperMC + --base-url= + --build= + --channel= + --check-updates Check for updates and exit with status code 0 when + available + --connection-pool-max-idle-timeout=DURATION + + --connection-pool-pending-acquire-timeout=DURATION + + --http-response-timeout=DURATION + The response timeout to apply to HTTP operations. + Parsed from ISO-8601 format. Default: PT30S + -o, --output-directory= + + --project= + --results-file=FILE A key=value file suitable for scripted environment + variables. Currently includes + SERVER: the entry point jar or script + --tls-handshake-timeout=DURATION + Default: PT30S + --url= Use a custom URL location + --version= May be 'latest' or specific version +``` + +### install-purpur + +``` +Usage: mc-image-helper install-purpur [--base-url=] + [-o=] + [--results-file=FILE] + [--url= | + [[--version=] + [--build=]]] + [--connection-pool-max-idle-timeout=DURATI + ON | [--tls-handshake-timeout=DURATION] | + --connection-pool-pending-acquire-timeout= + DURATION | + [--http-response-timeout=DURATION]] +Downloads latest or selected version of Purpur + --base-url= + --build= + --connection-pool-max-idle-timeout=DURATION + + --connection-pool-pending-acquire-timeout=DURATION + + --http-response-timeout=DURATION + The response timeout to apply to HTTP operations. + Parsed from ISO-8601 format. Default: PT30S + -o, --output-directory= + + --results-file=FILE A key=value file suitable for scripted environment + variables. Currently includes + SERVER: the entry point jar or script + --tls-handshake-timeout=DURATION + Default: PT30S + --url= Use a custom URL location + --version= May be 'latest' or specific version +``` + +### install-quilt + +``` +Usage: mc-image-helper install-quilt [-h] [--force-reinstall] + [--loader-version=VERSION] + [--minecraft-version=VERSION] + [--output-directory=DIR] + [--repo-url=] + [--results-file=FILE] [--installer-url=URL + | --installer-version=VERSION] + [[--connection-pool-max-idle-timeout=DURATI + ON] [--tls-handshake-timeout=DURATION] + [--connection-pool-pending-acquire-timeout= + DURATION] + [--http-response-timeout=DURATION]] +Installs Quilt mod loader + --connection-pool-max-idle-timeout=DURATION + + --connection-pool-pending-acquire-timeout=DURATION + + --force-reinstall + -h, --help + --http-response-timeout=DURATION + The response timeout to apply to HTTP operations. + Parsed from ISO-8601 format. Default: PT30S + --installer-url=URL + --installer-version=VERSION + Default uses latest + --loader-version=VERSION + Default uses latest + --minecraft-version=VERSION + 'latest', 'snapshot', or specific version + --output-directory=DIR + --repo-url= Default: https://maven.quiltmc. + org/repository/release + --results-file=FILE A key=value file suitable for scripted environment + variables. Currently includes + SERVER: the entry point jar or script + --tls-handshake-timeout=DURATION + Default: PT30S ``` ### interpolate @@ -338,6 +705,62 @@ Interpolates existing files in one or more directories Default: CFG_ ``` +### java-release + +``` +Usage: mc-image-helper java-release +Outputs the Java release number, such as 8, 11, 17 +``` + +### manage-users + +``` +Usage: mc-image-helper manage-users [-fh] [--existing=] + [--mojang-api-base-url=] + [--output-directory=] + [--playerdb-api-base-url=] -t= + [--user-api-provider=] + [--version=] + [[--connection-pool-max-idle-timeout=DURATIO + N] [--tls-handshake-timeout=DURATION] + [--connection-pool-pending-acquire-timeout=D + URATION] + [--http-response-timeout=DURATION]] [INPUT[, + INPUT...]...] + [INPUT[,INPUT...]...] One or more Mojang usernames, UUID, or ID (UUID + without dashes); however, when offline, only + UUID/IDs can be provided. + When input is a file, only one local file path or + URL can be provided + --connection-pool-max-idle-timeout=DURATION + + --connection-pool-pending-acquire-timeout=DURATION + + --existing= + Select the behavior when the resulting file already + exists + Allowed: SYNCHRONIZE, MERGE, SKIP + -f, --input-is-file + -h, --help + --http-response-timeout=DURATION + The response timeout to apply to HTTP operations. + Parsed from ISO-8601 format. Default: PT30S + --mojang-api-base-url= + + --output-directory= + + --playerdb-api-base-url= + + -t, --type= Allowed: JAVA_WHITELIST, JAVA_OPS + --tls-handshake-timeout=DURATION + Default: PT30S + --user-api-provider= + Allowed: mojang, playerdb + --version= Minecraft game version. If not provided, assumes + JSON format +``` + ### maven-download ``` @@ -347,13 +770,25 @@ Usage: mc-image-helper maven-download [-h] [--print-filename] [--skip-existing] [--output-directory=] [--packaging=] [-r=] [-v=] + [[--connection-pool-max-idle-timeout=DURAT + ION] [--tls-handshake-timeout=DURATION] + [--connection-pool-pending-acquire-timeout + =DURATION] + [--http-response-timeout=DURATION]] Downloads a maven artifact from a Maven repository -a, -m, --module, --artifact= --classifier= + --connection-pool-max-idle-timeout=DURATION + + --connection-pool-pending-acquire-timeout=DURATION + -g, --group= -h, --help + --http-response-timeout=DURATION + The response timeout to apply to HTTP operations. + Parsed from ISO-8601 format. Default: PT30S --output-directory= --packaging= @@ -363,7 +798,10 @@ Downloads a maven artifact from a Maven repository --skip-existing --skip-up-to-date - -v, --version= + --tls-handshake-timeout=DURATION + Default: PT30S + -v, --version= A specific version, 'release', or 'latest' + Default: release ``` ### mcopy @@ -371,38 +809,98 @@ Downloads a maven artifact from a Maven repository ``` Usage: mc-image-helper mcopy [-hz] [--file-is-listing] [--skip-existing] [--glob=GLOB] [--scope=] --to= - SRC[,SRC...]... + SRC[,|SRC...]... Multi-source file copy operation with with managed cleanup. Supports auto-detected sourcing from file list, directories, and URLs - SRC[,SRC...]... Any mix of source file, directory, or URL that can be - optionally comma-separated. - --file-is-listing Source files or URLs are processed as a line - delimited list of sources. - For remote listing files, the contents must all be - file URLs. - --glob=GLOB When a source is a directory, this filename glob will - be applied to select files. + SRC[,|SRC...]... Any mix of source file, directory, or URLs. + Can be optionally comma or newline separated. + --file-is-listing Source files or URLs are processed as a line + delimited list of sources. + For remote listing files, the contents must all be + file URLs. + --glob=GLOB When a source is a directory, this filename glob + will be applied to select files. -h, --help --scope, --manifest-id= - If managed cleanup is required, this is the - identifier used for qualifying manifest filename in - destination + If managed cleanup is required, this is the + identifier used for qualifying manifest filename + in destination --skip-existing --to, --output-directory= -z, --skip-up-to-date ``` +### modrinth + +``` +Usage: mc-image-helper modrinth [--skip-existing] [--skip-up-to-date] + [--allowed-version-type=] + [--api-base-url=] + [--download-dependencies=] + --game-version= --loader= + [--output-directory=DIR] + [--world-directory=] + [--projects=id|slug[,|id|slug...]]... + [[--connection-pool-max-idle-timeout=DURATION] + [--tls-handshake-timeout=DURATION] + [--connection-pool-pending-acquire-timeout=DURAT + ION] [--http-response-timeout=DURATION]] +Automates downloading of modrinth resources + --allowed-version-type= + Valid values: release, beta, alpha + --api-base-url= + Default: https://api.modrinth.com + --connection-pool-max-idle-timeout=DURATION + + --connection-pool-pending-acquire-timeout=DURATION + + --download-dependencies= + Default is NONE + Valid values: NONE, REQUIRED, OPTIONAL + --game-version= + Applicable Minecraft version + --http-response-timeout=DURATION + The response timeout to apply to HTTP operations. + Parsed from ISO-8601 format. Default: PT30S + --loader= Valid values: fabric, quilt, forge, neoforge, bukkit, + spigot, paper, pufferfish, purpur, bungeecord, + velocity, datapack + --output-directory=DIR + + --projects=id|slug[,|id|slug...] + Project ID or Slug + --skip-existing + --skip-up-to-date + --tls-handshake-timeout=DURATION + Default: PT30S + --world-directory= + Used for datapacks, a path relative to the output + directory or an absolute path + Default: world +``` + +### network-interfaces + +``` +Usage: mc-image-helper network-interfaces [--include-loopback] + [--check=] +Provides simple operations to list network interface names and check existence + --check= + + --include-loopback +``` + ### patch +``` +Usage: mc-image-helper patch [-h] [--patch-env-prefix=] FILE_OR_DIR +Patches one or more existing files using JSON path based operations Supports the file formats: - JSON - JSON5 - Yaml - TOML, but processed output is not pretty - -``` -Usage: mc-image-helper patch [-h] [--patch-env-prefix=] FILE_OR_DIR FILE_OR_DIR Path to a PatchSet json file or directory containing PatchDefinition json files -h, --help Show this usage and exit @@ -412,44 +910,61 @@ Usage: mc-image-helper patch [-h] [--patch-env-prefix=] FILE_OR_DIR Default: CFG_ ``` -[See below](#patch-schemas) for a description of [PatchSet](#patchset) and [PatchDefinition](#patchdefinition) JSON schemas. - -### install-quilt +### resolve-minecraft-version ``` -Usage: mc-image-helper install-quilt [-h] [--force-reinstall] - [--loader-version=VERSION] - [--minecraft-version=VERSION] - [--output-directory=DIR] - [--repo-url=] - [--results-file=FILE] [--installer-url=URL - | --installer-version=VERSION] - [[--tls-handshake-timeout=DURATION] - [--connection-pool-max-idle-timeout=DURATIO - N] [--http-response-timeout=DURATION]] -Installs Quilt mod loader +Usage: mc-image-helper resolve-minecraft-version + [[--connection-pool-max-idle-timeout=DURATION] + [--tls-handshake-timeout=DURATION] + [--connection-pool-pending-acquire-timeout=DURATION] + [--http-response-timeout=DURATION]] +Resolves and validate latest, snapshot, and specific versions + --connection-pool-max-idle-timeout=DURATION - --force-reinstall - -h, --help + --connection-pool-pending-acquire-timeout=DURATION + --http-response-timeout=DURATION - The response timeout to apply to HTTP operations. - Parsed from ISO-8601 format. Default: PT30S - --installer-url=URL - --installer-version=VERSION - Default uses latest - --loader-version=VERSION - Default uses latest - --minecraft-version=VERSION - 'latest', 'snapshot', or specific version - --output-directory=DIR - --repo-url= Default: https://maven.quiltmc. - org/repository/release - --results-file=FILE A key=value file suitable for scripted environment - variables. Currently includes - SERVER: the entry point jar or script + The response timeout to apply to HTTP operations. Parsed + from ISO-8601 format. Default: PT30S --tls-handshake-timeout=DURATION - Default: PT30S + Default: PT30S +``` + +### set-properties + +``` +Usage: mc-image-helper set-properties [--escape-unicode] + [--definitions=] + [-p=]... +Maps environment variables to a properties file + + --definitions= + JSON file of property names to PropertyDefinition + mappings + --escape-unicode + -p, --custom-property, --custom-properties= + Key=value pairs of custom properties to set +``` + +### show-all-subcommand-usage + +``` +Usage: mc-image-helper show-all-subcommand-usage +Renders all of the subcommand usage as markdown sections for README +``` + +### sync + +``` +Usage: mc-image-helper sync [-h] [--skip-newer-in-destination] +Synchronizes the contents of one directory to another. + source directory + destination directory + -h, --help Show this usage and exit + --skip-newer-in-destination + Skip any files that exist in the destination and have a newer + modification time than the source. ``` ### sync-and-interpolate @@ -480,6 +995,60 @@ interpolation. modification time than the source. ``` +### test-logging-levels + +``` +Usage: mc-image-helper test-logging-levels +``` + +### vanillatweaks + +``` +Usage: mc-image-helper vanillatweaks [--force-synchronize] + [--base-url=] + [--output-directory=DIR] + [--world-subdir=] + [--pack-files=FILE[,|FILE...]]... + [--share-codes=CODE[,|CODE...]]... + [[--connection-pool-max-idle-timeout=DURATI + ON] [--tls-handshake-timeout=DURATION] + [--connection-pool-pending-acquire-timeout= + DURATION] + [--http-response-timeout=DURATION]] +Downloads Vanilla Tweaks resource packs, data packs, or crafting tweaks given a +share code or pack file + --base-url= + --connection-pool-max-idle-timeout=DURATION + + --connection-pool-pending-acquire-timeout=DURATION + + --force-synchronize + --http-response-timeout=DURATION + The response timeout to apply to HTTP operations. + Parsed from ISO-8601 format. Default: PT30S + --output-directory=DIR + --pack-files=FILE[,|FILE...] + + --share-codes=CODE[,|CODE...] + + --tls-handshake-timeout=DURATION + Default: PT30S + --world-subdir= + +``` + +### yaml-path + +``` +Usage: mc-image-helper yaml-path [--file=] +Extracts a path from a YAML file using json-path syntax + A YAML/JSON path in to query. Leading root anchor, $, + will be added if not present + --file= A YAML file to query +``` + + + ## Patch Schemas @@ -609,4 +1178,61 @@ One of the following identifiers or can be prefixed with `list of ` to indicate - int : integer/whole value - float : numerical value with an optional decimal part - bool : boolean value of `true` or `false` -- auto : where the text value is attempted to be converted into one of the above \ No newline at end of file +- auto : where the text value is attempted to be converted into one of the above + +## Exclude/Include File Schema + +```json +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Mods Exclude/Include File Content", + "type": "object", + "additionalProperties": false, + "properties": { + "globalExcludes": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Mods by slug|id to exclude for all modpacks" + }, + "globalForceIncludes": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Mods by slug|id to force include for all modpacks" + }, + "modpacks": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/ExcludeIncludes" + }, + "description": "Specific exclude/includes by modpack slug" + } + }, + "definitions": { + "ExcludeIncludes": { + "type": "object", + "additionalProperties": false, + "properties": { + "excludes": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Mods by slug|id to exclude for this modpack" + }, + "forceIncludes": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Mods by slug|id to force include for this modpack" + } + } + } + } +} +``` + diff --git a/build.gradle b/build.gradle index 41099863..8de995a8 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,3 @@ -/* - * This file was generated by the Gradle 'init' task. - */ - plugins { id 'java' id 'application' @@ -10,7 +6,9 @@ plugins { // https://github.com/qoomon/gradle-git-versioning-plugin id 'me.qoomon.git-versioning' version '6.4.4' // https://github.com/itzg/github-releaser-gradle-plugin - id 'io.github.itzg.github-releaser' version '0.2.0' + id 'io.github.itzg.github-releaser' version '0.2.1' + // https://github.com/ben-manes/gradle-versions-plugin + id 'com.github.ben-manes.versions' version '0.51.0' } group = 'io.github.itzg' diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index c1962a79..a4b76b95 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 4eaec467..cea7a793 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index aeb74cbb..f5feea6d 100755 --- a/gradlew +++ b/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -83,7 +85,9 @@ done # This is normally unused # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -130,10 +134,13 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. @@ -141,7 +148,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac @@ -149,7 +156,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -198,11 +205,11 @@ fi # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ diff --git a/gradlew.bat b/gradlew.bat index 93e3f59f..9d21a218 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -43,11 +45,11 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -57,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail diff --git a/src/main/java/me/itzg/helpers/McImageHelper.java b/src/main/java/me/itzg/helpers/McImageHelper.java index d9f2dc05..f43b9761 100644 --- a/src/main/java/me/itzg/helpers/McImageHelper.java +++ b/src/main/java/me/itzg/helpers/McImageHelper.java @@ -6,11 +6,14 @@ import java.io.InputStream; import java.net.URL; import java.util.Enumeration; +import java.util.Map; +import java.util.concurrent.Callable; import java.util.jar.Attributes; import java.util.jar.Attributes.Name; import java.util.jar.Manifest; import lombok.Getter; import lombok.extern.slf4j.Slf4j; +import me.itzg.helpers.McImageHelper.ShowAllSubcommandUsage; import me.itzg.helpers.assertcmd.AssertCommand; import me.itzg.helpers.curseforge.CurseForgeFilesCommand; import me.itzg.helpers.curseforge.InstallCurseForgeCommand; @@ -48,9 +51,12 @@ import picocli.CommandLine; import picocli.CommandLine.ArgGroup; import picocli.CommandLine.Command; +import picocli.CommandLine.ExitCode; import picocli.CommandLine.ITypeConverter; import picocli.CommandLine.IVersionProvider; +import picocli.CommandLine.Model.CommandSpec; import picocli.CommandLine.Option; +import picocli.CommandLine.Spec; @Command(name = "mc-image-helper", versionProvider = McImageHelper.AppVersionProvider.class, @@ -81,6 +87,7 @@ PatchCommand.class, ResolveMinecraftVersionCommand.class, SetPropertiesCommand.class, + ShowAllSubcommandUsage.class, Sync.class, SyncAndInterpolate.class, TestLoggingCommand.class, @@ -204,4 +211,30 @@ public Level convert(String value) { return Level.toLevel(value); } } + + @Command(name = "show-all-subcommand-usage", description = "Renders all of the subcommand usage as markdown sections for README") + public static class ShowAllSubcommandUsage implements Callable { + + @Spec + CommandSpec spec; + + @Override + public Integer call() throws Exception { + + System.out.printf("%n_The following is generated using `%s`_%n%n", spec.qualifiedName()); + + spec.parent().subcommands().entrySet().stream() + .sorted(Map.Entry.comparingByKey()) + .forEach(entry -> { + System.out.printf("### %s%n", entry.getKey()); + System.out.println(); + System.out.println("```"); + entry.getValue().usage(System.out); + System.out.println("```"); + System.out.println(); + }); + + return ExitCode.OK; + } + } } diff --git a/src/main/java/me/itzg/helpers/patch/PatchCommand.java b/src/main/java/me/itzg/helpers/patch/PatchCommand.java index d67b870d..bbb270ad 100644 --- a/src/main/java/me/itzg/helpers/patch/PatchCommand.java +++ b/src/main/java/me/itzg/helpers/patch/PatchCommand.java @@ -1,22 +1,26 @@ package me.itzg.helpers.patch; import com.fasterxml.jackson.databind.ObjectMapper; -import lombok.extern.slf4j.Slf4j; -import me.itzg.helpers.env.Interpolator; -import me.itzg.helpers.env.StandardEnvironmentVariablesProvider; -import me.itzg.helpers.patch.model.PatchDefinition; -import me.itzg.helpers.patch.model.PatchSet; -import picocli.CommandLine; - import java.io.IOException; import java.nio.file.DirectoryStream; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; import java.util.concurrent.Callable; +import lombok.extern.slf4j.Slf4j; +import me.itzg.helpers.env.Interpolator; +import me.itzg.helpers.env.StandardEnvironmentVariablesProvider; +import me.itzg.helpers.patch.model.PatchDefinition; +import me.itzg.helpers.patch.model.PatchSet; +import picocli.CommandLine; @CommandLine.Command(name = "patch", - description = "Patches one or more existing files using JSON path based operations" + description = "Patches one or more existing files using JSON path based operations%n" + + "Supports the file formats:%n" + + "- JSON%n" + + "- JSON5%n" + + "- Yaml%n" + + "- TOML, but processed output is not pretty" ) @Slf4j public class PatchCommand implements Callable {