|
import sys |
|
import glob |
|
import json |
|
from os import path |
|
import os |
|
import shutil |
|
import subprocess |
|
|
|
SDK_PATH = "C:\\path\\to\\sdk" |
|
VENDOR_INFO_FILE = "vendor.json" |
|
VERSIONS_INFO_FILE = "versions.json" |
|
|
|
|
|
class VendorInfo: |
|
def __init__(self, name, versions, parent, path): |
|
self.name = name |
|
self.versions = versions |
|
self.parent = parent |
|
self.path = path |
|
|
|
|
|
class VersionInfo: |
|
def __init__(self, java_major, java_minor, vendor_original, path, vendor): |
|
self.java_major = java_major |
|
self.java_minor = java_minor |
|
self.vendor_original = vendor_original |
|
self.path = path |
|
self.vendor = vendor |
|
|
|
|
|
def load_versions_info(vendor_path, vendor_name): |
|
versions = [] |
|
for version_path in glob.glob(path.join(SDK_PATH, vendor_path, "**", VERSIONS_INFO_FILE)): |
|
if not path.exists(version_path): |
|
print("No version info file found for vendor: " + vendor_name) |
|
continue |
|
|
|
with open(version_path, "r", encoding="utf-8") as f: |
|
vendor_info = json.load(f) |
|
versions.append(VersionInfo( |
|
vendor_info["java_major"], |
|
vendor_info["java_minor"], |
|
vendor_info["vendor_original"], |
|
path.dirname(version_path), |
|
vendor_name |
|
)) |
|
|
|
return versions |
|
|
|
|
|
def load_vendor_info(vendor_root): |
|
vendor_info_file = path.join(SDK_PATH, vendor_root + "/" + VENDOR_INFO_FILE) |
|
if not path.exists(vendor_info_file): |
|
return None |
|
|
|
with open(vendor_info_file) as f: |
|
data = json.load(f) |
|
versions = load_versions_info(vendor_root, data["name"]) |
|
|
|
return VendorInfo( |
|
data["name"], |
|
versions, |
|
data["parent"], |
|
vendor_root |
|
) |
|
|
|
|
|
def save_vendor_info(vendor): |
|
vendor_path = path.join(SDK_PATH, vendor.name.lower()) |
|
os.makedirs(vendor_path, exist_ok=True) |
|
with open(path.join(vendor_path, VENDOR_INFO_FILE), "w") as f: |
|
json.dump({ |
|
"name": vendor.name, |
|
"parent": vendor.parent |
|
}, f) |
|
|
|
|
|
def save_version_info(version_info): |
|
version_path = path.join(version_info.path, VERSIONS_INFO_FILE) |
|
print("Saving version info to: " + version_path) |
|
with open(version_path, "w") as f: |
|
json.dump({ |
|
"java_major": version_info.java_major, |
|
"java_minor": version_info.java_minor, |
|
"vendor_original": version_info.vendor_original, |
|
"vendor": version_info.vendor |
|
}, f) |
|
|
|
|
|
def vendor_list(): |
|
directories = glob.glob(SDK_PATH + "/*") |
|
vendors = [] |
|
for directory in directories: |
|
vendor = load_vendor_info(directory) |
|
if vendor is not None: |
|
vendors.append(vendor) |
|
return vendors |
|
|
|
|
|
def create_vendor(vendors): |
|
print("Welcome to the vendor creation wizard!") |
|
print("Please enter the following information:") |
|
vendor_name = input("Vendor name: ") |
|
if vendor_name.lower() is "current": |
|
print("Vendor name cannot be 'current'") |
|
return |
|
|
|
if [v for v in vendors if v.name == vendor_name]: |
|
print("Vendor already exists: " + vendor_name) |
|
return |
|
|
|
vendor_parent = input("Vendor parent: ") |
|
if vendor_parent == "": |
|
vendor_parent = None |
|
elif not [v for v in vendors if v.name == vendor_parent]: |
|
print("Vendor not found: " + vendor_parent) |
|
return |
|
|
|
print("Creating vendor: ") |
|
print("Name: " + vendor_name) |
|
if vendor_parent is None: |
|
print("Parent: None") |
|
else: |
|
print("Parent: " + vendor_parent) |
|
|
|
confirm = input("Confirm? [y/N] ") |
|
if not confirm.startswith("y"): |
|
print("Aborting...") |
|
return |
|
|
|
vendor = VendorInfo(vendor_name, [], vendor_parent, path.join(SDK_PATH, vendor_name)) |
|
save_vendor_info(vendor) |
|
|
|
|
|
def decompress_to_temp(file_name): |
|
temp_dir = path.join(SDK_PATH, "jdk-temp", file_name[:-4]) |
|
os.makedirs(temp_dir, exist_ok=True) |
|
shutil.unpack_archive(file_name, temp_dir) |
|
return temp_dir |
|
|
|
|
|
def is_jdk_dir(dir): |
|
return path.exists(path.join(dir, "bin", "javac.exe")) and path.exists(path.join(dir, "bin", "java.exe")) \ |
|
and path.exists(path.join(dir, "lib")) and path.exists(path.join(dir, "include")) |
|
|
|
|
|
def patch_java(jdk_dir): |
|
# for /r %x in ( *.pack ) do .\bin\unpack200 -r "%x" "%~dx %~px%~nx.jar" |
|
subprocess.run(["cmd", "/c", "for /r %x in ( *.pack ) do .\\bin\\unpack200 -r ", "%x", "%~dx%~px%~nx.jar"], |
|
cwd=jdk_dir, |
|
stdout=subprocess.PIPE) |
|
|
|
# above to python |
|
|
|
|
|
def detect_java_version(jdk_dir): |
|
java_file = path.join(jdk_dir, "bin", "java.exe") |
|
process = subprocess.Popen([java_file, "-version"], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
|
output, error = process.communicate() |
|
if process.returncode != 0: |
|
print("Failed to detect vendor version!") |
|
print(output) |
|
return None |
|
|
|
version_string = None |
|
vendor_version = None |
|
for line in error.decode("utf-8").splitlines(): |
|
if line.startswith("java version "): |
|
version_string = line[14:] |
|
version_string = version_string.split('"')[0] |
|
elif line.startswith("openjdk version "): |
|
version_string = line[17:] |
|
version_string = version_string.split('"')[0] |
|
if line.startswith("Java(TM) SE Runtime Environment") or line.startswith("OpenJDK Runtime Environment"): |
|
vendor_version = line |
|
|
|
process.kill() |
|
|
|
return { |
|
"version_string": version_string, |
|
"vendor_version": vendor_version |
|
} |
|
|
|
|
|
def parse_java_version(version_string): |
|
parts = version_string.split(".") |
|
if len(parts) < 2: |
|
return None |
|
|
|
java_major = int(parts[0]) |
|
if java_major == 1: |
|
java_major = int(parts[1]) |
|
|
|
java_minor = parts[2].split("_") |
|
|
|
if len(java_minor) < 2: |
|
java_minor = parts[2] |
|
else: |
|
java_minor = java_minor[1] |
|
|
|
return { |
|
"java_major": java_major, |
|
"java_minor": java_minor |
|
} |
|
|
|
|
|
def create_version(vendors): |
|
print("Welcome to the version creation wizard!") |
|
print("Please enter the following information:") |
|
vendor_name = input("Vendor name: ") |
|
vendor = [v for v in vendors if v.name.lower() == vendor_name.lower()] |
|
if not vendor: |
|
print("Vendor not found: " + vendor_name) |
|
return |
|
vendor = vendor[0] |
|
|
|
print("Please enter the path to the JDK zip file:") |
|
zip_path = input("Path: ") |
|
if not path.exists(zip_path): |
|
print("File not found: " + zip_path) |
|
return |
|
|
|
print("Decompressing...") |
|
temp_dir = decompress_to_temp(zip_path) |
|
print("Searching for JDK directory...") |
|
jdk_dir = None |
|
for dir in glob.glob(path.join(temp_dir, "*")): |
|
if is_jdk_dir(dir): |
|
jdk_dir = dir |
|
break |
|
if is_jdk_dir(temp_dir): |
|
jdk_dir = temp_dir |
|
if jdk_dir is None: |
|
print("No JDK found!") |
|
shutil.rmtree(temp_dir) |
|
return |
|
print("Found JDK directory: " + jdk_dir) |
|
print("Patching JDK...") |
|
patch_java(jdk_dir) |
|
|
|
print("Detecting version...") |
|
version_info = detect_java_version(jdk_dir) |
|
if version_info is None: |
|
print("Failed to detect version!") |
|
shutil.rmtree(temp_dir) |
|
return |
|
version = parse_java_version(version_info["version_string"]) |
|
if version is None: |
|
print("Failed to parse version!") |
|
shutil.rmtree(temp_dir) |
|
return |
|
print("Creating version: ") |
|
print("Vendor: " + vendor_name) |
|
print("Version: " + version_info["version_string"]) |
|
print("Vendor version: " + version_info["vendor_version"]) |
|
print("Java major: " + str(version["java_major"])) |
|
print("Java minor: " + str(version["java_minor"])) |
|
|
|
java_dir = path.join(vendor.path, str(version["java_major"]) + "." + str(version["java_minor"])) |
|
print("Java directory: " + java_dir) |
|
|
|
confirm = input("Confirm? [y/N] ") |
|
if not confirm.startswith("y"): |
|
print("Aborting...") |
|
shutil.rmtree(temp_dir) |
|
return |
|
|
|
print("Copying files...") |
|
shutil.copytree(jdk_dir, java_dir) |
|
|
|
shutil.rmtree(temp_dir) |
|
print("Done!") |
|
save_version_info(VersionInfo( |
|
version["java_major"], |
|
version["java_minor"], |
|
version_info["vendor_version"], |
|
java_dir, |
|
vendor.name |
|
)) |
|
|
|
|
|
def change_version(vendor_name, version_str): |
|
vendors = vendor_list() |
|
vendor = [v for v in vendors if v.name.lower() == vendor_name.lower()] |
|
if len(vendor) == 0: |
|
print("Vendor not found: " + vendor_name) |
|
return |
|
vendor = vendor[0] |
|
|
|
versions = vendor.versions |
|
version = [v for v in versions if str(v.java_major) + "." + v.java_minor == version_str or str(v.java_major) == version_str] |
|
if len(version) == 0: |
|
print("Version not found: " + version_str) |
|
return |
|
version = version[0] |
|
|
|
print("Changing version to: ") |
|
print("Vendor: " + vendor.name) |
|
print("Version: " + version.vendor_original) |
|
print("Java: " + str(version.java_major) + "." + str(version.java_minor)) |
|
|
|
confirm = input("Confirm? [y/N] ") |
|
if not confirm.startswith("y"): |
|
print("Aborting...") |
|
return |
|
|
|
print("Changing version...") |
|
|
|
current = path.join(SDK_PATH, "current") |
|
|
|
if path.exists(current): |
|
shutil.rmtree(current) |
|
|
|
shutil.copytree(version.path, current, copy_function=os.link) |
|
|
|
print("Done!") |
|
|
|
|
|
def main(): |
|
args = sys.argv[1:] |
|
|
|
if len(args) == 0: |
|
print("Usage: sdk <command> <platform> [path]") |
|
return |
|
|
|
command = args[0] |
|
vendors = vendor_list() |
|
|
|
if command == "list": |
|
if len(args) == 1: |
|
print("Available vendors:") |
|
for vendor in vendors: |
|
parent = vendor.parent |
|
if parent is None: |
|
print("- " + vendor.name) |
|
else: |
|
print("- " + vendor.name + " (Parent: " + parent + ")") |
|
elif len(args) == 2: |
|
print_version(args, vendors) |
|
elif command == "create": |
|
if len(args) == 1: |
|
print("Usage: sdk create <vendor|version>") |
|
elif len(args) >= 2: |
|
if args[1] == "vendor": |
|
create_vendor(vendors) |
|
elif args[1] == "version": |
|
create_version(vendors) |
|
else: |
|
print("Unknown command: " + " ".join(args[1:]) + ".") |
|
elif command in ["use", "change", "switch", "set", "select", "sel", "ch", "sw"]: |
|
if len(args) < 3: |
|
print("Usage: sdk change <vendor> <version>") |
|
if len(args) == 2: |
|
print_version(args, vendors) |
|
elif len(args) == 3: |
|
change_version(args[1], args[2]) |
|
else: |
|
print("Unknown command: " + " ".join(args[1:]) + ".") |
|
else: |
|
print("Unknown command: " + " ".join(args) + ".") |
|
print("Available commands: list, create, change, use, switch, set, select, sel, ch, sw") |
|
|
|
|
|
def print_version(args, vendors): |
|
vendor = args[1] |
|
vendor = [v for v in vendors if v.name.lower() == vendor.lower()] |
|
if len(vendor) != 0: |
|
vendor = vendor[0] |
|
print("Available versions for vendor: " + vendor.name) |
|
for version in vendor.versions: |
|
print("- " + str(version.java_major) + "." + version.java_minor + " (" + version.vendor_original + ")") |
|
else: |
|
print("Vendor not found: " + args[1]) |
|
|
|
|
|
if __name__ == "__main__": |
|
main() |