Removed command-based building. Now each package provides its name and its kind. Modules now also allow for optional parameters.

This commit is contained in:
Marco Calautti 2020-06-04 11:08:53 +02:00
parent 06fbd4c2a5
commit dfc69069ba
8 changed files with 391 additions and 219 deletions

View file

@ -26,7 +26,7 @@ import modules
from pathlib import Path
import shutil
import sys
import json
def parse_args():
parser = argparse.ArgumentParser()
@ -36,51 +36,20 @@ def parse_args():
type=str,
help='Overrides the DeepSea Version from the config file.',
metavar='DeepSeaVersion')
subparsers = parser.add_subparsers()
# Kosmos subcommands
parser_kosmos = subparsers.add_parser(
'deepsea', help='Create a release build of DeepSea.')
parser_kosmos.add_argument('output', help='Zip file to create.')
parser_kosmos.set_defaults(command=common.Command.Kosmos)
# SDSetup subcommands
parser_sdsetup = subparsers.add_parser(
'sdsetup', help='Create a DeepSea modules for SDSetup.')
parser_sdsetup.add_argument(
'output', help='Directory to output modules to.')
parser_sdsetup.add_argument(
'-a', '--auto',
action='store_true',
default=False,
help='Perform an auto build.')
parser_sdsetup.set_defaults(command=common.Command.SDSetup)
# Kosmos Minimal subcommands
parser_kosmos = subparsers.add_parser(
'deepsea-mini', help='Create a release build of DeepSea Minimal.')
parser_kosmos.add_argument('output', help='Zip file to create.')
parser_kosmos.set_defaults(command=common.Command.KosmosMinimal)
# Kosmos with patches subcommands
parser_kosmos_patches = subparsers.add_parser(
'deepsea-patches', help='Create a release build of DeepSea with patches.')
parser_kosmos_patches.add_argument('output', help='Zip file to create.')
parser_kosmos_patches.set_defaults(command=common.Command.KosmosPatches)
# Kosmos minimal with patches subcommands
parser_kosmos_minimal_patches = subparsers.add_parser(
'deepsea-mini-patches', help='Create a release build of DeepSea Minimal with patches.')
parser_kosmos_minimal_patches.add_argument('output', help='Zip file to create.')
parser_kosmos_minimal_patches.set_defaults(command=common.Command.KosmosMinimalPatches)
parser.add_argument(
"package_file",
default=None,
type=str,
help="Create a release build using the provided json file.")
parser.add_argument(
"output",
default=None,
type=str,
help='Zip file to create.')
# Parse arguments
args = parser.parse_args()
if not hasattr(args, 'command'):
parser.print_help()
sys.exit()
return args
@ -90,18 +59,9 @@ def get_deepsea_version(args):
return config.version
def init_version_messages(args, kosmos_version):
if args.command == common.Command.Kosmos:
return [f'DeepSea {kosmos_version} built with:']
elif args.command == common.Command.SDSetup and not args.auto:
return ['SDSetup Modules built with:']
elif args.command == common.Command.KosmosMinimal:
return [f'DeepSea Minimal {kosmos_version} built with:']
elif args.command == common.Command.KosmosPatches:
return [f'DeepSea with Patches {kosmos_version} built with:']
elif args.command == common.Command.KosmosMinimalPatches:
return [f'DeepSea Minimal with Patches {kosmos_version} built with:']
return []
def init_version_messages(package_content, kosmos_version):
pkg_name = package_content['package_name']
return [f'{pkg_name} {kosmos_version} built with:']
if __name__ == '__main__':
@ -115,17 +75,20 @@ if __name__ == '__main__':
if hasattr(args, 'auto'):
auto_build = args.auto
version_messages = init_version_messages(args, deepsea_version)
with open(args.package_file,'r') as pkgfile:
package_content = json.load(pkgfile)
version_messages = init_version_messages(package_content, deepsea_version)
build_messages = modules.build(
temp_directory, deepsea_version, args.command, auto_build)
temp_directory, deepsea_version, package_content, auto_build)
common.delete(args.output)
if build_messages is not None:
version_messages += build_messages
if args.command == common.Command.SDSetup:
if package_content['is_sdsetup']:
common.move(temp_directory, args.output)
else:
shutil.make_archive(

View file

@ -25,13 +25,6 @@ import re
import shutil
import uuid
class Command(enum.Enum):
Kosmos = 0
SDSetup = 1
KosmosMinimal = 2
KosmosPatches = 3
KosmosMinimalPatches = 4
class GitService(enum.Enum):
GitHub = 0
GitLab = 1

View file

@ -1,6 +1,22 @@
[
"Atmosphère",
"Hekate",
"PKG2-Patches",
"ES-Patches"
]
{
"package_name": "DeepSea Minimal with Patches",
"is_sdsetup": false,
"modules": [
{
"module_name": "Atmosphère",
"parameters": null
},
{
"module_name": "Hekate",
"parameters": null
},
{
"module_name": "PKG2-Patches",
"parameters": null
},
{
"module_name": "ES-Patches",
"parameters": null
}
]
}

View file

@ -1,4 +1,14 @@
[
"Atmosphère",
"Hekate"
]
{
"package_name": "DeepSea Minimal",
"is_sdsetup": false,
"modules": [
{
"module_name": "Atmosphère",
"parameters": null
},
{
"module_name": "Hekate",
"parameters": null
}
]
}

View file

@ -1,26 +1,102 @@
[
"Atmosphère",
"Hekate",
"Hekate Icons",
"Homebrew App Store",
"EdiZon",
"Emuiibo",
"Goldleaf",
"Awoo Installer",
"DeepSea Toolbox",
"DeepSea Updater",
"DeepSea Cleaner",
"JKSV",
"NXMTP",
"ldn_mitm",
"Lockpick_RCM",
"nx-ovlloader",
"ovlSysModules",
"Status Monitor Overlay",
"sys-clk",
"sys-con",
"sys-ftpd-light",
"Tesla-Menu",
"PKG2-Patches",
"ES-Patches"
]
{
"package_name": "DeepSea with Patches",
"is_sdsetup": false,
"modules": [
{
"module_name": "Atmosphère",
"parameters": null
},
{
"module_name": "Hekate",
"parameters": null
},
{
"module_name": "Hekate Icons",
"parameters": null
},
{
"module_name": "Homebrew App Store",
"parameters": null
},
{
"module_name": "EdiZon",
"parameters": null
},
{
"module_name": "Emuiibo",
"parameters": null
},
{
"module_name": "Goldleaf",
"parameters": null
},
{
"module_name": "Awoo Installer",
"parameters": null
},
{
"module_name": "DeepSea Toolbox",
"parameters": null
},
{
"module_name": "DeepSea Updater",
"parameters": null
},
{
"module_name": "DeepSea Cleaner",
"parameters": null
},
{
"module_name": "JKSV",
"parameters": null
},
{
"module_name": "NXMTP",
"parameters": null
},
{
"module_name": "ldn_mitm",
"parameters": null
},
{
"module_name": "Lockpick_RCM",
"parameters": null
},
{
"module_name": "nx-ovlloader",
"parameters": null
},
{
"module_name": "ovlSysModules",
"parameters": null
},
{
"module_name": "Status Monitor Overlay",
"parameters": null
},
{
"module_name": "sys-clk",
"parameters": null
},
{
"module_name": "sys-con",
"parameters": null
},
{
"module_name": "sys-ftpd-light",
"parameters": null
},
{
"module_name": "Tesla-Menu",
"parameters": null
},
{
"module_name": "PKG2-Patches",
"parameters": null
},
{
"module_name": "ES-Patches",
"parameters": null
}
]
}

View file

@ -1,24 +1,94 @@
[
"Atmosphère",
"Hekate",
"Hekate Icons",
"Homebrew App Store",
"EdiZon",
"Emuiibo",
"Goldleaf",
"Awoo Installer",
"DeepSea Toolbox",
"DeepSea Updater",
"DeepSea Cleaner",
"JKSV",
"NXMTP",
"ldn_mitm",
"Lockpick_RCM",
"nx-ovlloader",
"ovlSysModules",
"Status Monitor Overlay",
"sys-clk",
"sys-con",
"sys-ftpd-light",
"Tesla-Menu"
]
{
"package_name": "DeepSea",
"is_sdsetup": false,
"modules": [
{
"module_name": "Atmosphère",
"parameters": null
},
{
"module_name": "Hekate",
"parameters": null
},
{
"module_name": "Hekate Icons",
"parameters": null
},
{
"module_name": "Homebrew App Store",
"parameters": null
},
{
"module_name": "EdiZon",
"parameters": null
},
{
"module_name": "Emuiibo",
"parameters": null
},
{
"module_name": "Goldleaf",
"parameters": null
},
{
"module_name": "Awoo Installer",
"parameters": null
},
{
"module_name": "DeepSea Toolbox",
"parameters": null
},
{
"module_name": "DeepSea Updater",
"parameters": null
},
{
"module_name": "DeepSea Cleaner",
"parameters": null
},
{
"module_name": "JKSV",
"parameters": null
},
{
"module_name": "NXMTP",
"parameters": null
},
{
"module_name": "ldn_mitm",
"parameters": null
},
{
"module_name": "Lockpick_RCM",
"parameters": null
},
{
"module_name": "nx-ovlloader",
"parameters": null
},
{
"module_name": "ovlSysModules",
"parameters": null
},
{
"module_name": "Status Monitor Overlay",
"parameters": null
},
{
"module_name": "sys-clk",
"parameters": null
},
{
"module_name": "sys-con",
"parameters": null
},
{
"module_name": "sys-ftpd-light",
"parameters": null
},
{
"module_name": "Tesla-Menu",
"parameters": null
}
]
}

View file

@ -183,7 +183,7 @@ def get_version(module, release, index):
return groups[0]
def download_atmosphere(module, temp_directory, deepsea_version, deepsea_build):
def download_atmosphere(module, temp_directory, deepsea_version, parameters, deepsea_build):
release = get_latest_release(module)
bundle_path = download_asset(module, release, 0)
if bundle_path is None:
@ -214,7 +214,7 @@ def download_atmosphere(module, temp_directory, deepsea_version, deepsea_build):
return get_version(module, release, 0)
def download_hekate(module, temp_directory, deepsea_version, deepsea_build):
def download_hekate(module, temp_directory, deepsea_version, parameters, deepsea_build):
release = get_latest_release(module)
bundle_path = download_asset(module, release, 0)
if bundle_path is None:
@ -254,7 +254,7 @@ def download_hekate(module, temp_directory, deepsea_version, deepsea_build):
return get_version(module, release, 0)
def download_hekate_icons(module, temp_directory, deepsea_version, deepsea_build):
def download_hekate_icons(module, temp_directory, deepsea_version, parameters, deepsea_build):
release = get_latest_release(module)
bundle_path = download_asset(module, release, 0)
if bundle_path is None:
@ -279,7 +279,7 @@ def download_hekate_icons(module, temp_directory, deepsea_version, deepsea_build
return get_version(module, release, 0)
def download_appstore(module, temp_directory, deepsea_version, deepsea_build):
def download_appstore(module, temp_directory, deepsea_version, parameters, deepsea_build):
release = get_latest_release(module)
bundle_path = download_asset(module, release, 0)
if bundle_path is None:
@ -296,7 +296,7 @@ def download_appstore(module, temp_directory, deepsea_version, deepsea_build):
return get_version(module, release, 0)
def download_edizon(module, temp_directory, deepsea_version, deepsea_build):
def download_edizon(module, temp_directory, deepsea_version, parameters, deepsea_build):
release = get_latest_release(module)
app_path = download_asset(module, release, 0)
if app_path is None:
@ -316,7 +316,7 @@ def download_edizon(module, temp_directory, deepsea_version, deepsea_build):
return get_version(module, release, 0)
def download_emuiibo(module, temp_directory, deepsea_version, deepsea_build):
def download_emuiibo(module, temp_directory, deepsea_version, parameters, deepsea_build):
release = get_latest_release(module)
bundle_path = download_asset(module, release, 0)
if bundle_path is None:
@ -342,7 +342,7 @@ def download_emuiibo(module, temp_directory, deepsea_version, deepsea_build):
return get_version(module, release, 0)
def download_goldleaf(module, temp_directory, deepsea_version, deepsea_build):
def download_goldleaf(module, temp_directory, deepsea_version, parameters, deepsea_build):
release = get_latest_release(module)
app_path = download_asset(module, release, 0)
if app_path is None:
@ -355,7 +355,7 @@ def download_goldleaf(module, temp_directory, deepsea_version, deepsea_build):
return get_version(module, release, 0)
def download_deepsea_cleaner(module, temp_directory, deepsea_version, deepsea_build):
def download_deepsea_cleaner(module, temp_directory, deepsea_version, parameters, deepsea_build):
release = get_latest_release(module)
bundle_path = download_asset(module, release, 0)
if bundle_path is None:
@ -367,7 +367,7 @@ def download_deepsea_cleaner(module, temp_directory, deepsea_version, deepsea_bu
return get_version(module, release, 0)
def download_deepsea_toolbox(module, temp_directory, deepsea_version, deepsea_build):
def download_deepsea_toolbox(module, temp_directory, deepsea_version, parameters, deepsea_build):
release = get_latest_release(module)
app_path = download_asset(module, release, 0)
if app_path is None:
@ -384,7 +384,7 @@ def download_deepsea_toolbox(module, temp_directory, deepsea_version, deepsea_bu
return get_version(module, release, 0)
def download_kosmos_updater(module, temp_directory, deepsea_version, deepsea_build):
def download_kosmos_updater(module, temp_directory, deepsea_version, parameters, deepsea_build):
release = get_latest_release(module)
app_path = download_asset(module, release, 0)
if app_path is None:
@ -401,7 +401,7 @@ def download_kosmos_updater(module, temp_directory, deepsea_version, deepsea_bui
return get_version(module, release, 0)
def download_ldn_mitm(module, temp_directory, deepsea_version, deepsea_build):
def download_ldn_mitm(module, temp_directory, deepsea_version, parameters, deepsea_build):
release = get_latest_release(module)
bundle_path = download_asset(module, release, 0)
if bundle_path is None:
@ -420,7 +420,7 @@ def download_ldn_mitm(module, temp_directory, deepsea_version, deepsea_build):
return get_version(module, release, 0)
def download_lockpick(module, temp_directory, deepsea_version, deepsea_build):
def download_lockpick(module, temp_directory, deepsea_version, parameters, deepsea_build):
release = get_latest_release(module)
app_path = download_asset(module, release, 0)
if app_path is None:
@ -433,7 +433,7 @@ def download_lockpick(module, temp_directory, deepsea_version, deepsea_build):
return get_version(module, release, 0)
def download_lockpick_rcm(module, temp_directory, deepsea_version, deepsea_build):
def download_lockpick_rcm(module, temp_directory, deepsea_version, parameters, deepsea_build):
release = get_latest_release(module)
payload_path = download_asset(module, release, 0)
if payload_path is None:
@ -449,7 +449,7 @@ def download_lockpick_rcm(module, temp_directory, deepsea_version, deepsea_build
return get_version(module, release, 0)
def download_nxdumptool(module, temp_directory, deepsea_version, deepsea_build):
def download_nxdumptool(module, temp_directory, deepsea_version, parameters, deepsea_build):
release = get_latest_release(module)
app_path = download_asset(module, release, 0)
if app_path is None:
@ -462,7 +462,7 @@ def download_nxdumptool(module, temp_directory, deepsea_version, deepsea_build):
return get_version(module, release, 0)
def download_nx_ovlloader(module, temp_directory, deepsea_version, deepsea_build):
def download_nx_ovlloader(module, temp_directory, deepsea_version, parameters, deepsea_build):
release = get_latest_release(module)
bundle_path = download_asset(module, release, 0)
if bundle_path is None:
@ -476,7 +476,7 @@ def download_nx_ovlloader(module, temp_directory, deepsea_version, deepsea_build
return get_version(module, release, 0)
def download_ovl_sysmodules(module, temp_directory, deepsea_version, deepsea_build):
def download_ovl_sysmodules(module, temp_directory, deepsea_version, parameters, deepsea_build):
release = get_latest_release(module)
app_path = download_asset(module, release, 0)
if app_path is None:
@ -489,7 +489,7 @@ def download_ovl_sysmodules(module, temp_directory, deepsea_version, deepsea_bui
return get_version(module, release, 0)
def download_status_monitor_overlay(module, temp_directory, deepsea_version, deepsea_build):
def download_status_monitor_overlay(module, temp_directory, deepsea_version, parameters, deepsea_build):
release = get_latest_release(module)
app_path = download_asset(module, release, 0)
if app_path is None:
@ -502,7 +502,7 @@ def download_status_monitor_overlay(module, temp_directory, deepsea_version, dee
return get_version(module, release, 0)
def download_sys_clk(module, temp_directory, deepsea_version, deepsea_build):
def download_sys_clk(module, temp_directory, deepsea_version, parameters, deepsea_build):
release = get_latest_release(module)
bundle_path = download_asset(module, release, 0)
if bundle_path is None:
@ -522,7 +522,7 @@ def download_sys_clk(module, temp_directory, deepsea_version, deepsea_build):
return get_version(module, release, 0)
def download_sys_con(module, temp_directory, deepsea_version, deepsea_build):
def download_sys_con(module, temp_directory, deepsea_version, parameters, deepsea_build):
release = get_latest_release(module)
bundle_path = download_asset(module, release, 0)
if bundle_path is None:
@ -539,7 +539,7 @@ def download_sys_con(module, temp_directory, deepsea_version, deepsea_build):
return get_version(module, release, 0)
def download_sys_ftpd_light(module, temp_directory, deepsea_version, deepsea_build):
def download_sys_ftpd_light(module, temp_directory, deepsea_version, parameters, deepsea_build):
release = get_latest_release(module)
bundle_path = download_asset(module, release, 0)
if bundle_path is None:
@ -556,7 +556,7 @@ def download_sys_ftpd_light(module, temp_directory, deepsea_version, deepsea_bui
return get_version(module, release, 0)
def download_tesla_menu(module, temp_directory, deepsea_version, deepsea_build):
def download_tesla_menu(module, temp_directory, deepsea_version, parameters, deepsea_build):
release = get_latest_release(module)
bundle_path = download_asset(module, release, 0)
if bundle_path is None:
@ -570,7 +570,7 @@ def download_tesla_menu(module, temp_directory, deepsea_version, deepsea_build):
return get_version(module, release, 0)
def download_awoo(module, temp_directory, deepsea_version, deepsea_build):
def download_awoo(module, temp_directory, deepsea_version, parameters, deepsea_build):
release = get_latest_release(module)
app_path = download_asset(module, release, 0)
if app_path is None:
@ -582,7 +582,7 @@ def download_awoo(module, temp_directory, deepsea_version, deepsea_build):
return get_version(module, release, 0)
def download_jksv(module, temp_directory, deepsea_version, deepsea_build):
def download_jksv(module, temp_directory, deepsea_version, parameters, deepsea_build):
release = get_latest_release(module)
app_path = download_asset(module, release, 0)
if app_path is None:
@ -595,7 +595,7 @@ def download_jksv(module, temp_directory, deepsea_version, deepsea_build):
return get_version(module, release, 0)
def download_nxmtp(module, temp_directory, deepsea_version, deepsea_build):
def download_nxmtp(module, temp_directory, deepsea_version, parameters, deepsea_build):
release = get_latest_release(module)
app_path = download_asset(module, release, 0)
if app_path is None:
@ -608,7 +608,7 @@ def download_nxmtp(module, temp_directory, deepsea_version, deepsea_build):
return get_version(module, release, 0)
def download_pkg2_patches(module, temp_directory, deepsea_version, deepsea_build):
def download_pkg2_patches(module, temp_directory, deepsea_version, parameters, deepsea_build):
release = get_latest_release(module)
fusee_patches_path = download_asset(module, release, 0)
if fusee_patches_path is None:
@ -635,7 +635,7 @@ def download_pkg2_patches(module, temp_directory, deepsea_version, deepsea_build
return get_version(module, release, 0)
def download_es_patches(module, temp_directory, deepsea_version, deepsea_build):
def download_es_patches(module, temp_directory, deepsea_version, parameters, deepsea_build):
release = get_latest_release(module)
es_patches_path = download_asset(module, release, 0)
if es_patches_path is None:
@ -649,19 +649,9 @@ def download_es_patches(module, temp_directory, deepsea_version, deepsea_build):
return get_version(module, release, 0)
def build(temp_directory, deepsea_version, command, auto_build):
def build(temp_directory, deepsea_version, package_content, auto_build):
results = []
modules_filename = 'deepsea.json'
if command == common.Command.KosmosMinimal:
modules_filename = 'deepsea-minimal.json'
elif command == common.Command.SDSetup:
modules_filename = 'sdsetup.json'
elif command == common.Command.KosmosPatches:
modules_filename = "deepsea-patches.json"
elif command == common.Command.KosmosMinimalPatches:
modules_filename = "deepsea-minimal-patches.json"
# Open up modules-definitions.json first and load all modules
mods_map = {}
with open("Modules/modules-definitions.json") as mod_json_file:
@ -674,50 +664,51 @@ def build(temp_directory, deepsea_version, command, auto_build):
mods_map[name] = module_def
# Open up modules.json
with open(modules_filename) as json_file:
# Parse JSON
data = json.load(json_file)
data = package_content['modules']
# Loop through modules
for mod_entry in data:
mod_id = mod_entry['module_name']
if mod_id not in mods_map:
raise Exception('Module with name '+mod_id+' does not exist')
# Loop through modules
for mod_id in data:
if mod_id not in mods_map:
raise Exception('Module with name '+mod_id+' does not exist')
module = mods_map[mod_id]
# Running a SDSetup Build
if command == common.Command.SDSetup:
# Only show prompts when it's not an auto build.
if not auto_build:
print(f'Downloading {module["name"]}...')
module = mods_map[mod_id]
parameters = mod_entry.get('parameters')
# Make sure module directory is created.
module_directory = temp_directory.joinpath(
module['sdsetup_module_name'])
common.mkdir(module_directory)
# Download the module.
download = globals()[module['download_function_name']]
version = download(module, module_directory,
deepsea_version, False)
if version is None:
return None
# Auto builds have a different prompt at the end for parsing.
if auto_build:
results.append(
f'{module["sdsetup_module_name"]}:{version}')
else:
results.append(f' {module["name"]} - {version}')
# Running a Kosmos Build
else:
# Download the module.
# Running a SDSetup Build
if package_content['is_sdsetup']:
# Only show prompts when it's not an auto build.
if not auto_build:
print(f'Downloading {module["name"]}...')
download = globals()[module['download_function_name']]
version = download(module, temp_directory,
deepsea_version, True)
if version is None:
return None
# Make sure module directory is created.
module_directory = temp_directory.joinpath(
module['sdsetup_module_name'])
common.mkdir(module_directory)
# Download the module.
download = globals()[module['download_function_name']]
version = download(module, module_directory,
deepsea_version, parameters, False)
if version is None:
return None
# Auto builds have a different prompt at the end for parsing.
if auto_build:
results.append(
f'{module["sdsetup_module_name"]}:{version}')
else:
results.append(f' {module["name"]} - {version}')
# Running a Kosmos Build
else:
# Download the module.
print(f'Downloading {module["name"]}...')
download = globals()[module['download_function_name']]
version = download(module, temp_directory,
deepsea_version, parameters, True)
if version is None:
return None
results.append(f' {module["name"]} - {version}')
return results

View file

@ -1,18 +1,71 @@
{
"package_name": "SDSetup",
"is_sdsetup": true,
"modules":
[
"Atmosphère",
"Hekate",
"Hekate Icons",
"Emuiibo",
"Kosmos Cleaner",
"Kosmos Toolbox",
"Kosmos Updater",
"ldn_mitm",
"Lockpick_RCM",
"nx-ovlloader",
"ovlSysModules",
"Status Monitor Overlay",
"sys-clk",
"sys-con",
"sys-ftpd-light",
"Tesla-Menu"
{
"module_name": "Atmosphère",
"parameters": null
},
{
"module_name": "Hekate",
"parameters": null
},
{
"module_name": "Hekate Icons",
"parameters": null
},
{
"module_name": "Emuiibo",
"parameters": null
},
{
"module_name": "Kosmos Cleaner",
"parameters": null
},
{
"module_name": "Kosmos Toolbox",
"parameters": null
},
{
"module_name": "Kosmos Updater",
"parameters": null
},
{
"module_name": "ldn_mitm",
"parameters": null
},
{
"module_name": "Lockpick_RCM",
"parameters": null
},
{
"module_name": "nx-ovlloader",
"parameters": null
},
{
"module_name": "ovlSysModules",
"parameters": null
},
{
"module_name": "Status Monitor Overlay",
"parameters": null
},
{
"module_name": "sys-clk",
"parameters": null
},
{
"module_name": "sys-con",
"parameters": null
},
{
"module_name": "sys-ftpd-light",
"parameters": null
},
{
"module_name": "Tesla-Menu",
"parameters": null
}
]
}