new build script

This commit is contained in:
Slluxx 2022-03-23 15:45:39 +01:00
parent c9c1418787
commit cd0c689275
38 changed files with 645 additions and 651 deletions

View File

@ -4,7 +4,10 @@ on:
push: push:
branches: branches:
- master - master
- rewrite
defaults:
run:
working-directory: src
jobs: jobs:
build: build:
@ -15,13 +18,13 @@ jobs:
- id: set-version - id: set-version
run: | run: |
version=$(cat ./VERSION | python -c 'import sys, json; f=open("./src/settings.json");print(json.loads(f.read())["version"])') version=$(cat ./VERSION | python -c 'import sys, json; f=open("./settings.json");print(json.loads(f.read())["releaseVersion"])')
echo "::set-output name=version::$version" echo "::set-output name=version::$version"
- name: Set up Python 3.9 - name: Set up Python 3.9
uses: actions/setup-python@v1 uses: actions/setup-python@v1
with: with:
python-version: 3.9.10 python-version: '3.x'
- name: Install dependencies - name: Install dependencies
run: | run: |

View File

@ -1,11 +1,11 @@
<img src="assets/deepsea_wide_tr_an.gif" align="center" width="100%" /> <img src="assets/banner.png" align="center" width="100%" />
<p align="center"> <p align="center">
The new All-in-One CFW package for the Nintendo Switch.</br> The new All-in-One CFW package for the Nintendo Switch.</br>
<a href="https://discord.gg/VkaRjYN"> <a href="https://discord.gg/VkaRjYN">
<img alt="Discord" src="https://img.shields.io/discord/703301751171973190?label=Join%20DeepSea%20on%20Discord"> <img alt="Discord" src="https://img.shields.io/discord/703301751171973190?label=Join%20DeepSea%20on%20Discord&style=flat-square">
</a> </a>
<img alt="GitHub All Releases" src="https://img.shields.io/github/downloads/Team-Neptune/DeepSea/total?label=Total%20downloads"> <img alt="GitHub All Releases" src="https://img.shields.io/github/downloads/Team-Neptune/DeepSea/total?label=Total%20downloads&style=flat-square">
<img alt="GitHub Workflow Status" src="https://img.shields.io/github/workflow/status/Team-Neptune/DeepSea/BuildRelease?label=Build"> <img alt="GitHub Workflow Status" src="https://img.shields.io/github/workflow/status/Team-Neptune/DeepSea/BuildRelease?label=Build&style=flat-square">
</p> </p>
--- ---

BIN
assets/banner.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 336 KiB

View File

@ -1,86 +0,0 @@
import src.scripts.gh as GH, src.scripts.fs as FS
import argparse, json, os, importlib, shutil
from pathlib import Path
from distutils.dir_util import copy_tree
if __name__ == '__main__':
parser = argparse.ArgumentParser(description="TeamNeptune's DeepSea build script.")
requiredNamed = parser.add_argument_group('Options required to build a release candidate')
requiredNamed.add_argument('-v', '--version', help='DeepSea version tag', required=True)
requiredNamed.add_argument('-gt', '--githubToken', help='Github Token', required=True)
args = parser.parse_args()
try:
with open(Path.joinpath(Path.cwd(), "src", "settings.json")) as json_file:
settings = json.load(json_file)
except:
print("Could not load Package.")
exit()
shutil.rmtree("tmp", ignore_errors=True)
gh = GH.GH(args.githubToken)
fs = FS.FS()
for packageName in settings["packages"]:
packageObj = settings["packages"][packageName]
if packageObj["active"] == True:
for moduleName in packageObj["modules"]:
if fs.doesFilesExist(False, "src/modules/"+moduleName+".json"):
module = fs.getJson(False, "src/modules/"+moduleName+".json")
if not fs.doesFolderExist(True, moduleName):
print("Downloading: " + module["repo"])
dlPath = fs.createDirs(moduleName)
downloadedFiles = gh.downloadLatestRelease(module, dlPath)
for customStep in module["customSteps"]:
if customStep["action"] == "createDir":
print("- custom step: " + customStep["action"] + " -> " + customStep["source"])
fs.createDir(moduleName, customStep["source"])
if customStep["action"] == "extract":
print("- custom step: " + customStep["action"] + " -> " + customStep["source"])
fs.extract(moduleName, customStep["source"])
if customStep["action"] == "delete":
print("- custom step: " + customStep["action"] + " -> " + customStep["source"])
fs.delete(moduleName, customStep["source"])
if customStep["action"] == "copy":
if "fileRegex" in customStep:
print("- custom step: " + customStep["action"] + " -> " + customStep["fileRegex"])
fs.copy(moduleName, customStep["source"], customStep["destination"], customStep["fileRegex"])
else:
print("- custom step: " + customStep["action"] + " -> " + customStep["source"])
fs.copy(moduleName, customStep["source"], customStep["destination"])
if customStep["action"] == "move":
print("- custom step: " + customStep["action"] + " -> " + customStep["source"])
fs.move(moduleName, customStep["source"], customStep["destination"])
if customStep["action"] == "replaceText":
print("- custom step: " + customStep["action"] + " -> " + customStep["source"])
fs.replaceText(moduleName, customStep["source"], customStep["target"], customStep["replacement"])
if customStep["action"] == "createToolboxJson":
print("- custom step: " + customStep["action"] + " -> " + customStep["source"])
fs.createToolboxJson(moduleName, customStep["source"], customStep["requires_reboot"] )
else:
print("Already downloaded: " + module["repo"])
outPath = str(fs.createDirs("switch_out"))
shutil.copytree(str(Path(Path.joinpath(fs.workdir, moduleName))), str(Path(Path.joinpath(fs.workdir, "switch_out"))), dirs_exist_ok=True)
# fs.copy("", str(Path(Path.joinpath(fs.workdir, moduleName))), outPath)
else:
print("module file does not exist")
print("Zipping package: " + "deepsea-"+packageName+"_v"+settings["version"])
shutil.make_archive("deepsea-"+packageName+"_v"+settings["version"],'zip',outPath)
fs.delete("",outPath)
else:
print("package inactive")

View File

@ -1,3 +1 @@
PyGithub PyGithub
python-gitlab
xmltodict

95
src/fs.py Normal file
View File

@ -0,0 +1,95 @@
import shutil, os, logging, re, zipfile, glob
from pathlib import Path
class FS():
def __init__(self):
shutil.rmtree("./base", ignore_errors=True)
shutil.rmtree("./menv", ignore_errors=True)
shutil.rmtree("./sd", ignore_errors=True)
for elements in glob.glob(f"./*.zip"):
os.remove(elements)
def createSDEnv(self):
shutil.rmtree("./sd", ignore_errors=True)
Path("./sd").mkdir(parents=True, exist_ok=True)
def createModuleEnv(self, module):
shutil.rmtree("./menv", ignore_errors=True)
Path("./menv").mkdir(parents=True, exist_ok=True)
shutil.copytree(f"./base/{module['repo']}", f"./menv/", dirs_exist_ok=True)
def finishModule(self):
self.__copyToSD()
shutil.rmtree("./menv", ignore_errors=True)
def executeStep(self, module, step):
if step["name"] == "extract":
self.__extract(step["arguments"][0])
if step["name"] == "create_dir":
self.__createDir(step["arguments"][0])
if step["name"] == "create_file":
self.__createFile(step["arguments"][0], step["arguments"][1])
if step["name"] == "replace_content":
self.__replaceFileContent(step["arguments"][0], step["arguments"][1], step["arguments"][2])
if step["name"] == "delete":
self.__delete(step["arguments"][0])
if step["name"] == "copy":
self.__copy(step["arguments"][0], step["arguments"][1])
if step["name"] == "move":
self.__copy(step["arguments"][0], step["arguments"][1])
self.__delete(step["arguments"][0])
def __extract(self, source):
path = f"./menv/"
for filename in os.listdir(path):
if re.search(source, filename):
assetPath = f"./menv/{filename}"
with zipfile.ZipFile(assetPath, 'r') as zip_ref:
zip_ref.extractall(path)
self.__delete(filename)
def __delete(self, source):
if not os.path.isdir(f"./menv/{source}"):
if os.path.exists(f"./menv/{source}"):
os.remove(f"./menv/{source}")
else:
shutil.rmtree(f"./menv/{source}", ignore_errors=True)
def __copy(self, source, dest):
for elements in glob.glob(f"./menv/{source}"):
if not os.path.isdir(elements):
if os.path.exists(elements):
shutil.copy(f"{elements}", f"./menv/{dest}")
break
else:
shutil.copytree(f"{elements}", f"./menv/{dest}", dirs_exist_ok=True)
break
def __createDir(self, source):
Path(f"./menv/{source}").mkdir(parents=True, exist_ok=True)
def __createFile(self, source, content):
with open(f"./menv/{source}", "w") as f:
f.write(content)
def __replaceFileContent(self, source, search, replace):
fin = open(f"./menv/{source}", "rt")
data = fin.read()
data = data.replace(search, replace)
fin.close()
fin = open(f"./menv/{source}", "wt")
fin.write(data)
fin.close()
def __copyToSD(self):
shutil.copytree("./menv", "./sd/", dirs_exist_ok=True)

33
src/gh.py Normal file
View File

@ -0,0 +1,33 @@
import pathlib
from github import Github
import urllib.request
import re
import logging
class GH():
def __init__(self, ghToken):
self.token = ghToken
self.github = Github(self.token)
def downloadReleaseAssets(self, module):
try:
ghRepo = self.github.get_repo(module["repo"])
except:
logging.exception(f"Unable to get: {module['repo']}")
return
releases = ghRepo.get_releases()
if releases.totalCount == 0:
logging.warning(f"No available release for: {module['repo']}")
return
ghLatestRelease = releases[0]
for pattern in module["regex"]:
for asset in ghLatestRelease.get_assets():
if re.search(pattern, asset.name):
logging.info(f"[{module['repo']}] Downloading: {asset.name}")
fpath = f"./base/{module['repo']}/"
pathlib.Path(fpath).mkdir(parents=True, exist_ok=True)
urllib.request.urlretrieve(asset.browser_download_url, f"{fpath}{asset.name}")
return True

View File

@ -1,14 +0,0 @@
{
"repo":"ndeadly/MissionControl",
"assetRegex":[".*MissionControl.*\\.zip"],
"customSteps":[
{
"action": "extract",
"source": ".*MissionControl.*\\.zip"
},
{
"action": "delete",
"source": "atmosphere/contents/010000000000bd00/flags/boot2.flag"
}
]
}

View File

@ -1,15 +0,0 @@
{
"repo":"masagrator/Status-Monitor-Overlay",
"assetRegex":[".*Status-Monitor-Overlay.*\\.ovl"],
"customSteps":[
{
"action": "createDir",
"source": "switch/.overlays"
},
{
"action": "move",
"source": "Status-Monitor-Overlay.ovl",
"destination": "switch/.overlays/Status-Monitor-Overlay.ovl"
}
]
}

View File

@ -1,15 +0,0 @@
{
"repo":"suchmememanyskill/TegraExplorer",
"assetRegex":[".*\\.bin"],
"customSteps":[
{
"action": "createDir",
"source": "bootloader/payloads"
},
{
"action": "move",
"source": "TegraExplorer.bin",
"destination": "bootloader/payloads/TegraExplorer.bin"
}
]
}

View File

@ -1,10 +0,0 @@
{
"repo":"WerWolv/Tesla-Menu",
"assetRegex":[".*ovlmenu.*\\.zip"],
"customSteps":[
{
"action": "extract",
"source": ".*ovlmenu.*\\.zip"
}
]
}

View File

@ -1,10 +0,0 @@
{
"repo":"HamletDuFromage/aio-switch-updater",
"assetRegex":[".*aio-switch-updater.*\\.zip"],
"customSteps":[
{
"action": "extract",
"source": ".*aio-switch-updater.*\\.zip"
}
]
}

View File

@ -1,29 +0,0 @@
{
"repo":"Atmosphere-NX/Atmosphere",
"assetRegex":[".*atmosphere.*\\.zip"],
"customSteps":[
{
"action": "extract",
"source": ".*atmosphere.*\\.zip"
},
{
"action": "delete",
"source": "switch/reboot_to_payload.nro"
},
{
"action": "createDir",
"source": "atmosphere/contents"
},
{
"action": "copy",
"source": "atmosphere/config_templates/system_settings.ini",
"destination": "atmosphere/config/system_settings.ini"
},
{
"action": "replaceText",
"source": "atmosphere/config/system_settings.ini",
"target": "; dmnt_cheats_enabled_by_default = u8!0x1",
"replacement":"dmnt_cheats_enabled_by_default = u8!0x0"
}
]
}

View File

@ -1,10 +0,0 @@
{
"repo":"Team-Neptune/DeepSea-Assets",
"assetRegex":[".*DeepSea-Assets.*\\.zip"],
"customSteps":[
{
"action": "extract",
"source": ".*DeepSea-Assets.*\\.zip"
}
]
}

View File

@ -1,15 +0,0 @@
{
"repo":"Team-Neptune/CommonProblemResolver",
"assetRegex":[".*\\.bin"],
"customSteps":[
{
"action": "createDir",
"source": "bootloader/payloads"
},
{
"action": "move",
"source": "CommonProblemResolver.bin",
"destination": "bootloader/payloads/CommonProblemResolver.bin"
}
]
}

View File

@ -1,10 +0,0 @@
{
"repo":"Team-Neptune/DeepSea-Cleaner",
"assetRegex":[".*DeepSea-Cleaner.*\\.zip"],
"customSteps":[
{
"action": "extract",
"source": ".*DeepSea-Cleaner.*\\.zip"
}
]
}

View File

@ -1,15 +0,0 @@
{
"repo":"Team-Neptune/DeepSea-Toolbox",
"assetRegex":[".*\\.nro"],
"customSteps":[
{
"action": "createDir",
"source": "switch/DeepSea-Toolbox"
},
{
"action": "move",
"source": "DeepSeaToolbox.nro",
"destination": "switch/DeepSea-Toolbox/DeepSeaToolbox.nro"
}
]
}

View File

@ -1,24 +0,0 @@
{
"repo":"WerWolv/EdiZon",
"assetRegex":[".*EdiZon.*\\.nro", ".*ovlEdiZon.*\\.ovl"],
"customSteps":[
{
"action": "createDir",
"source": "switch/.overlays"
},
{
"action": "createDir",
"source": "switch/edizon"
},
{
"action": "move",
"source": "EdiZon.nro",
"destination": "switch/edizon/EdiZon.nro"
},
{
"action": "move",
"source": "ovlEdiZon.ovl",
"destination": "switch/.overlays/ovlEdiZon.ovl"
}
]
}

View File

@ -1,28 +0,0 @@
{
"repo":"XorTroll/emuiibo",
"assetRegex":[".*emuiibo.*\\.zip"],
"customSteps":[
{
"action": "extract",
"source": ".*emuiibo.*\\.zip"
},
{
"action": "move",
"source": "SdOut/atmosphere",
"destination": "atmosphere"
},
{
"action": "move",
"source": "SdOut/switch",
"destination": "switch"
},
{
"action": "delete",
"source": "SdOut"
},
{
"action": "delete",
"source": "atmosphere/contents/0100000000000352/flags/boot2.flag"
}
]
}

View File

@ -1,10 +0,0 @@
{
"repo":"fortheusers/hb-appstore",
"assetRegex":[".*switch-extracttosd.*\\.zip"],
"customSteps":[
{
"action": "extract",
"source": ".*switch-extracttosd.*\\.zip"
}
]
}

View File

@ -1,26 +0,0 @@
{
"repo":"CTCaer/hekate",
"assetRegex":[".*hekate.*\\.zip"],
"customSteps":[
{
"action": "extract",
"source": ".*hekate.*\\.zip"
},
{
"action": "copy",
"source": "bootloader",
"fileRegex": ".*hekate.*\\.bin",
"destination": "bootloader/update.bin"
},
{
"action": "createDir",
"source": "atmosphere"
},
{
"action": "copy",
"source": "bootloader",
"fileRegex": ".*hekate.*\\.bin",
"destination": "atmosphere/reboot_payload.bin"
}
]
}

View File

@ -1,15 +0,0 @@
{
"repo":"J-D-K/JKSV",
"assetRegex":[".*\\.nro"],
"customSteps":[
{
"action": "createDir",
"source": "switch/jksv"
},
{
"action": "move",
"source": "JKSV.nro",
"destination": "switch/jksv/JKSV.nro"
}
]
}

View File

@ -1,19 +0,0 @@
{
"repo":"spacemeowx2/ldn_mitm",
"assetRegex":[".*ldn_mitm.*\\.zip"],
"customSteps":[
{
"action": "extract",
"source": ".*ldn_mitm.*\\.zip"
},
{
"action": "delete",
"source": "atmosphere/contents/4200000000000010/flags/boot2.flag"
},
{
"action": "createToolboxJson",
"source": "atmosphere/contents/4200000000000010/",
"requires_reboot": true
}
]
}

View File

@ -1,10 +0,0 @@
{
"repo":"WerWolv/nx-ovlloader",
"assetRegex":[".*nx-ovlloader.*\\.zip"],
"customSteps":[
{
"action": "extract",
"source": ".*nx-ovlloader.*\\.zip"
}
]
}

View File

@ -1,15 +0,0 @@
{
"repo":"joel16/NX-Shell",
"assetRegex":[".*NX-Shell.*\\.nro"],
"customSteps":[
{
"action": "createDir",
"source": "switch/NX-Shell"
},
{
"action": "move",
"source": "NX-Shell.nro",
"destination": "switch/NX-Shell/NX-Shell.nro"
}
]
}

View File

@ -1,15 +0,0 @@
{
"repo":"liuervehc/nxmtp",
"assetRegex":[".*\\.nro"],
"customSteps":[
{
"action": "createDir",
"source": "switch/nxmtp"
},
{
"action": "move",
"source": "nxmtp.nro",
"destination": "switch/nxmtp/nxmtp.nro"
}
]
}

View File

@ -1,15 +0,0 @@
{
"repo":"WerWolv/ovl-sysmodules",
"assetRegex":[".*ovlSysmodules.*\\.ovl"],
"customSteps":[
{
"action": "createDir",
"source": "switch/.overlays"
},
{
"action": "move",
"source": "ovlSysmodules.ovl",
"destination": "switch/.overlays/ovlSysmodules.ovl"
}
]
}

View File

@ -1,32 +0,0 @@
{
"repo":"retronx-team/sys-clk",
"assetRegex":[".*sys-clk.*\\.zip"],
"customSteps":[
{
"action": "extract",
"source": ".*sys-clk.*\\.zip"
},
{
"action": "createDir",
"source": "switch/sys-clk-manager"
},
{
"action": "move",
"source": "switch//sys-clk-manager.nro",
"destination": "switch/sys-clk-manager/sys-clk-manager.nro"
},
{
"action": "delete",
"source": "README.md"
},
{
"action": "delete",
"source": "atmosphere/contents/00FF0000636C6BFF/flags/boot2.flag"
},
{
"action": "createToolboxJson",
"source": "atmosphere/contents/00FF0000636C6BFF/",
"requires_reboot": true
}
]
}

View File

@ -1,14 +0,0 @@
{
"repo":"cathery/sys-con",
"assetRegex":[".*sys-con.*\\.zip"],
"customSteps":[
{
"action": "extract",
"source": ".*sys-con.*\\.zip"
},
{
"action": "delete",
"source": "atmosphere/contents/690000000000000D/flags/boot2.flag"
}
]
}

View File

@ -1,14 +0,0 @@
{
"repo":"cathery/sys-ftpd-light",
"assetRegex":[".*sys-ftpd-light.*\\.zip"],
"customSteps":[
{
"action": "extract",
"source": ".*sys-ftpd-light.*\\.zip"
},
{
"action": "delete",
"source": "atmosphere/contents/420000000000000E/flags/boot2.flag"
}
]
}

View File

@ -1,10 +0,0 @@
{
"repo":"mrdude2478/TinWoo",
"assetRegex":[".*TinWoo-Installer.*\\.zip"],
"customSteps":[
{
"action": "extract",
"source": ".*TinWoo-Installer.*\\.zip"
}
]
}

View File

@ -1,103 +0,0 @@
from distutils.dir_util import copy_tree
from pathlib import Path
import shutil
import uuid
import json
import os
import re
import zipfile
from os.path import normpath, basename
class FS():
def __init__(self):
self.workdir = Path.cwd().joinpath('tmp', str(uuid.uuid4()))
Path(Path.joinpath(self.workdir)).mkdir(parents=True, exist_ok=True)
def createDirs(self, path, override=True):
newdir = Path(Path.joinpath(self.workdir, path))
if override:
newdir.mkdir(parents=True, exist_ok=True)
return newdir
def doesFolderExist(self, workspace, path):
if not workspace: workspace = Path.cwd()
else: workspace = self.workdir
return Path(Path.joinpath(workspace, path)).is_dir()
def doesFilesExist(self, workspace, path):
if not workspace: workspace = Path.cwd()
else: workspace = self.workdir
return Path(Path.joinpath(workspace, path)).exists()
def getJson(self, workspace, path):
if not workspace: workspace = Path.cwd()
else: workspace = self.workdir
return json.loads(open(Path.joinpath(workspace,path)).read())
################### THIS IS WHAT SHOULD BE USED FOR MODULES ###################
def delete(self, modulename, source):
path = Path(Path.joinpath(self.workdir, modulename, source))
if not path.is_dir():
if os.path.exists(path):
os.remove(path)
else:
shutil.rmtree(path, ignore_errors=True)
def copy(self, modulename, source, dest, regex=False):
if regex == False:
spath = Path(Path.joinpath(self.workdir, modulename, source))
dpath = Path(Path.joinpath(self.workdir, modulename, dest))
if spath.is_dir():
print(dpath.is_dir())
copy_tree(str(spath), str(dpath))
else:
shutil.copyfile(str(spath), str(dpath))
else:
path = Path(Path.joinpath(self.workdir, modulename))
for filename in os.listdir(path):
if re.search(regex, filename):
assetPath = Path(Path.joinpath(path, filename))
dpath = Path(Path.joinpath(self.workdir, modulename, dest))
shutil.copyfile(str(assetPath), str(dpath))
def move(self, modulename, source, dest):
self.copy(modulename, source, dest)
self.delete(modulename, source)
def createDir(self, modulename, source):
Path(Path.joinpath(self.workdir, modulename, source)).mkdir(parents=True, exist_ok=True)
def extract(self, modulename, source):
path = Path(Path.joinpath(self.workdir, modulename))
for filename in os.listdir(path):
if re.search(source, filename):
assetPath = Path(Path.joinpath(path, filename))
with zipfile.ZipFile(assetPath, 'r') as zip_ref:
zip_ref.extractall(path)
self.delete(modulename, assetPath)
break
def replaceText(self, modulename, source, target, replacement):
path = Path(Path.joinpath(self.workdir, modulename, source))
fin = open(path, "rt")
data = fin.read()
data = data.replace(target, replacement)
fin.close()
fin = open(path, "wt")
fin.write(data)
fin.close()
def createToolboxJson(self, modulename, source, requires_reboot):
path = Path(Path.joinpath(self.workdir, modulename, source, "toolbox.json"))
tid = basename(normpath(source))
data = {
"name" : modulename,
"tid" : tid,
"requires_reboot": requires_reboot
}
with open(path, 'w') as f:
json.dump(data, f, indent=4)

View File

@ -1,41 +0,0 @@
from pathlib import Path
from github import Github
import urllib.request
import re
class GH():
def __init__(self, ghToken):
self.token = ghToken
self.github = Github(self.token)
def downloadLatestRelease(self, moduleJson, downloadPath):
try:
ghRepo = self.github.get_repo(moduleJson["repo"])
except:
print("Unable to get: ", moduleJson["repo"])
return
releases = ghRepo.get_releases()
if releases.totalCount == 0:
print("No available releases for: ", moduleJson["repo"])
return
ghLatestRelease = releases[0]
downloadedFiles = []
for pattern in moduleJson["assetRegex"]:
matched_asset = None
for asset in ghLatestRelease.get_assets():
if re.search(pattern, asset.name):
matched_asset = asset
break
if matched_asset is None:
print("Did not find asset for pattern: ", pattern)
return
downloadFilePath = Path.joinpath(downloadPath, matched_asset.name)
urllib.request.urlretrieve(matched_asset.browser_download_url, downloadFilePath)
downloadedFiles.append(downloadFilePath)
return downloadedFiles

View File

@ -1,30 +1,461 @@
{ {
"version": "3.5.0", "releaseVersion": "1.0.0",
"packages":{ "packages": [
"minimal":{ {
"active": true, "name": "minimal",
"modules": ["atmosphere", "hekate", "deepseaAssets", "hb-appstore"]
},
"normal":{
"active": true, "active": true,
"modules": [ "modules": [
"atmosphere", "hekate", "deepseaAssets", "hb-appstore", "atmosphere",
"deepseaToolbox", "deepseaCleaner", "hekate",
"aioUpdater", "edizon", "emuiibo", "jksv", "nxmtp", "tinwoo", "deepseaassets",
"sys-ftpd-light", "nx-ovlloader", "ovl-sysmodules", "Tesla-Menu", "hbappstore"
"deepseaCPR"
] ]
}, },
"advanced":{ {
"active": true, "name": "normal",
"active": false,
"modules": [ "modules": [
"atmosphere", "hekate", "deepseaAssets", "hb-appstore", "atmosphere",
"deepseaToolbox", "deepseaCleaner", "hekate",
"aioUpdater", "edizon", "emuiibo", "jksv", "nxmtp", "tinwoo", "deepseaassets",
"sys-clk", "sys-con","sys-ftpd-light", "hbappstore",
"ldn_mitm", "nx-ovlloader", "ovl-sysmodules", "Tesla-Menu", "Status-Monitor-Overlay", "deepseatoolbox",
"deepseaCPR", "TegraExplorer", "NX-Shell", "MissionControl" "deepseacleaner",
"aioupdater",
"edizon",
"emuiibo",
"jksv",
"nxmtp",
"tinwoo",
"sysftpdlight",
"nxovlloader",
"ovlsysmodules",
"teslamenu",
"deepseacpr"
]
},
{
"name": "advanced",
"active": false,
"modules": [
"atmosphere",
"hekate",
"deepseaassets",
"hbappstore",
"deepseatoolbox",
"deepseacleaner",
"aioupdater",
"edizon",
"emuiibo",
"jksv",
"nxmtp",
"tinwoo",
"sysclk",
"syscon",
"sysftpdlight",
"ldn_mitm",
"nxovlloader",
"ovlsysmodules",
"teslamenu",
"statusmonitoroverlay",
"deepseacpr",
"tegraexplorer",
"nxshell",
"missioncontrol"
]
}
],
"moduleList": {
"atmosphere": {
"repo": "Atmosphere-NX/Atmosphere",
"regex": [
".*atmosphere.*\\.zip"
],
"steps": [
{
"name": "extract",
"arguments": [
".*atmosphere.*\\.zip"
]
},
{
"name": "delete",
"arguments": [
"switch/reboot_to_payload.nro"
]
},
{
"name": "create_dir",
"arguments": [
"atmosphere/contents"
]
},
{
"name": "copy",
"arguments": [
"atmosphere/config_templates/system_settings.ini",
"atmosphere/config/system_settings.ini"
]
},
{
"name": "replace_content",
"arguments": [
"atmosphere/config/system_settings.ini",
"; dmnt_cheats_enabled_by_default = u8!0x1",
"dmnt_cheats_enabled_by_default = u8!0x0"
]
}
]
},
"hekate": {
"repo": "CTCaer/hekate",
"regex": [
".*hekate.*\\.zip"
],
"steps": [
{
"name": "extract",
"arguments": [".*hekate.*\\.zip"]
},
{
"name": "copy",
"arguments": ["bootloader/hekate_*", "bootloader/update.bin"]
},
{
"name": "createDir",
"arguments": ["atmosphere"]
},
{
"name": "copy",
"arguments": ["bootloader/hekate_*", "atmosphere/reboot_payload.bin"]
}
]
},
"deepseaassets": {
"repo": "Team-Neptune/DeepSea-Assets",
"regex": [
".*DeepSea-Assets.*\\.zip"
],
"steps": [
{
"name": "extract",
"arguments": [
".*DeepSea-Assets.*\\.zip"
]
}
]
},
"hbappstore": {
"repo": "fortheusers/hb-appstore",
"regex": [".*switch-extracttosd.*\\.zip"],
"steps": [
{
"name": "extract",
"arguments": [
".*switch-extracttosd.*\\.zip"
]
}
]
},
"deepseatoolbox": {
"repo": "Team-Neptune/DeepSea-Toolbox",
"regex": [".*\\.nro"],
"steps": [
{
"name": "create_dir",
"arguments": ["switch/DeepSea-Toolbox"]
},
{
"name": "move",
"arguments": ["DeepSeaToolbox.nro", "switch/DeepSea-Toolbox/DeepSeaToolbox.nro"]
}
]
},
"deepseacleaner": {
"repo": "Team-Neptune/DeepSea-Cleaner",
"regex": [".*DeepSea-Cleaner.*\\.zip"],
"steps": [
{
"name": "extract",
"arguments": [".*DeepSea-Cleaner.*\\.zip"]
}
]
},
"aioupdater": {
"repo": "HamletDuFromage/aio-switch-updater",
"regex": [".*aio-switch-updater.*\\.zip"],
"steps": [
{
"name": "extract",
"arguments": [".*aio-switch-updater.*\\.zip"]
}
]
},
"edizon": {
"repo": "WerWolv/EdiZon",
"regex": [".*EdiZon.*\\.nro", ".*ovlEdiZon.*\\.ovl"],
"steps": [
{
"name": "create_dir",
"arguments": ["switch/.overlays"]
},
{
"name": "create_dir",
"arguments": ["switch/edizon"]
},
{
"name": "move",
"arguments": ["EdiZon.nro", "switch/edizon/EdiZon.nro"]
},
{
"name": "create_dir",
"arguments": ["switch/.overlays", "switch/.overlays/ovlEdiZon.ovl"]
}
]
},
"emuiibo": {
"repo": "XorTroll/emuiibo",
"regex": [".*emuiibo.*\\.zip"],
"steps": [
{
"name": "extract",
"arguments": [".*emuiibo.*\\.zip"]
},
{
"name": "move",
"arguments": ["SdOut/atmosphere", "atmosphere"]
},
{
"name": "move",
"arguments": ["SdOut/switch", "switch"]
},
{
"name": "delete",
"arguments": ["SdOut"]
},
{
"name": "delete",
"arguments": ["atmosphere/contents/0100000000000352/flags/boot2.flag"]
}
]
},
"jksv": {
"repo": "J-D-K/JKSV",
"regex": [".*\\.nro"],
"steps": [
{
"name": "create_dir",
"arguments": ["switch/jksv"]
},
{
"name": "move",
"arguments": ["JKSV.nro", "switch/jksv"]
}
]
},
"nxmtp": {
"repo": "liuervehc/nxmtp",
"regex": [".*\\.nro"],
"steps": [
{
"name": "create_dir",
"arguments": ["switch/nxmtp"]
},
{
"name": "move",
"arguments": ["nxmtp.nro", "switch/nxmtp"]
}
]
},
"tinwoo": {
"repo": "mrdude2478/TinWoo",
"regex": [".*TinWoo-Installer.*\\.zip"],
"steps": [
{
"name": "extract",
"arguments": [".*TinWoo-Installer.*\\.zip"]
}
]
},
"sysclk": {
"repo": "retronx-team/sys-clk",
"regex": [".*sys-clk.*\\.zip"],
"steps": [
{
"name": "extract",
"arguments": [".*sys-clk.*\\.zip"]
},
{
"name": "create_dir",
"arguments": ["switch/sys-clk-manager"]
},
{
"name": "move",
"arguments": ["switch/sys-clk-manager.nro", "switch/sys-clk-manager/sys-clk-manager.nro"]
},
{
"name": "delete",
"arguments": ["README.md"]
},
{
"name": "delete",
"arguments": ["atmosphere/contents/00FF0000636C6BFF/flags/boot2.flag"]
},
{
"name": "create_file",
"arguments": ["atmosphere/contents/00FF0000636C6BFF/toolbox.json", "{\"name\": \"sys-clk\",\"tid\": \"00FF0000636C6BFF\",\"requires_reboot\": true}"]
}
]
},
"syscon": {
"repo": "cathery/sys-con",
"regex": [".*sys-con.*\\.zip"],
"steps": [
{
"name": "extract",
"arguments": [".*sys-con.*\\.zip"]
},
{
"name": "delete",
"arguments": ["atmosphere/contents/690000000000000D/flags/boot2.flag"]
}
]
},
"sysftpdlight": {
"repo": "cathery/sys-ftpd-light",
"regex": [".*sys-ftpd-light.*\\.zip"],
"steps": [
{
"name": "extract",
"arguments": [".*sys-ftpd-light.*\\.zip"]
},
{
"name": "delete",
"arguments": ["atmosphere/contents/420000000000000E/flags/boot2.flag"]
}
]
},
"ldn_mitm": {
"repo": "spacemeowx2/ldn_mitm",
"regex": [".*ldn_mitm.*\\.zip"],
"steps": [
{
"name": "extract",
"arguments": [".*ldn_mitm.*\\.zip"]
},
{
"name": "delete",
"arguments": ["atmosphere/contents/4200000000000010/flags/boot2.flag"]
},
{
"name": "create_file",
"arguments": ["atmosphere/contents/4200000000000010/toolbox.json", "{\"name\": \"ldn_mitm\",\"tid\": \"4200000000000010\",\"requires_reboot\": true}"]
}
]
},
"nxovlloader": {
"repo": "WerWolv/nx-ovlloader",
"regex": [".*nx-ovlloader.*\\.zip"],
"steps": [
{
"name": "extract",
"arguments": [".*nx-ovlloader.*\\.zip"]
}
]
},
"ovlsysmodules": {
"repo": "WerWolv/ovl-sysmodules",
"regex": [".*ovlSysmodules.*\\.ovl"],
"steps": [
{
"name": "create_dir",
"arguments": ["switch/.overlays"]
},
{
"name": "move",
"arguments": ["ovlSysmodules.ovl", "switch/.overlays/ovlSysmodules.ovl"]
}
]
},
"teslamenu": {
"repo": "WerWolv/Tesla-Menu",
"regex": [".*ovlmenu.*\\.zip"],
"steps": [
{
"name": "extract",
"arguments": [".*ovlmenu.*\\.zip"]
}
]
},
"statusmonitoroverlay": {
"repo": "masagrator/Status-Monitor-Overlay",
"regex": [".*Status-Monitor-Overlay.*\\.ovl"],
"steps": [
{
"name": "create_dir",
"arguments": ["switch/.overlays"]
},
{
"name": "move",
"arguments": ["Status-Monitor-Overlay.ovl", "switch/.overlays/Status-Monitor-Overlay.ovl"]
}
]
},
"deepseacpr": {
"repo": "Team-Neptune/CommonProblemResolver",
"regex": [".*\\.bin"],
"steps": [
{
"name": "create_dir",
"arguments": ["bootloader/payloads"]
},
{
"name": "move",
"arguments": ["CommonProblemResolver.bin", "bootloader/payloads/CommonProblemResolver.bin"]
}
]
},
"tegraexplorer": {
"repo": "suchmememanyskill/TegraExplorer",
"regex": [".*\\.bin"],
"steps": [
{
"name": "create_dir",
"arguments": ["bootloader/payloads"]
},
{
"name": "move",
"arguments": ["TegraExplorer.bin", "bootloader/payloads/TegraExplorer.bin"]
}
]
},
"nxshell": {
"repo": "joel16/NX-Shell",
"regex": [".*NX-Shell.*\\.nro"],
"steps": [
{
"name": "create_dir",
"arguments": ["switch/NX-Shell"]
},
{
"name": "move",
"arguments": ["NX-Shell.nro", "switch/NX-Shell/NX-Shell.nro"]
}
]
},
"missioncontrol": {
"repo": "ndeadly/MissionControl",
"regex": [".*MissionControl.*\\.zip"],
"steps": [
{
"name": "extract",
"arguments": [".*MissionControl.*\\.zip"]
},
{
"name": "delete",
"arguments": ["atmosphere/contents/010000000000bd00/flags/boot2.flag"]
}
] ]
} }
} }
} }

54
src/start.py Normal file
View File

@ -0,0 +1,54 @@
import logging, json, argparse, shutil
from gh import GH
from fs import FS
logging.basicConfig(format='[%(asctime)s] %(message)s', datefmt='%H:%M:%S')
logging.getLogger().setLevel(logging.INFO)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description="TeamNeptune's DeepSea build script.")
requiredNamed = parser.add_argument_group('Options required to build a release candidate')
requiredNamed.add_argument('-v', '--version', help='DeepSea version tag', required=True)
requiredNamed.add_argument('-gt', '--githubToken', help='Github Token', required=True)
args = parser.parse_args()
sdcard = FS()
github = GH(args.githubToken)
with open('./settings.json', 'r') as f:
settings = json.load(f)
neededModules = []
for package in settings["packages"]:
if package["active"]:
for module in package["modules"]:
if module not in neededModules:
neededModules.append(module)
for i in neededModules:
module = settings["moduleList"][i]
github.downloadReleaseAssets(module)
for package in settings["packages"]:
if package["active"]:
logging.info(f"[{package['name']}] Creating package")
sdcard.createSDEnv()
for i in package["modules"]:
module = settings["moduleList"][i]
logging.info(f"[{package['name']}][{module['repo']}] Creating module env")
sdcard.createModuleEnv(module)
for step in module["steps"]:
logging.info(f"[{package['name']}][{module['repo']}] Executing step: {step['name']}")
sdcard.executeStep(module, step)
logging.info(f"[{package['name']}][{module['repo']}] Moving MENV to SD")
sdcard.finishModule()
logging.info(f"[{package['name']}] All modules processed.")
logging.info(f"[{package['name']}] Creating ZIP")
shutil.make_archive(f"deepsea-{package['name']}_v{settings['releaseVersion']}", 'zip', "./sd")