jvm-manager-cli 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "jvm-manager-cli",
3
+ "version": "1.0.0",
4
+ "description": "A simple CLI to manage Java installations on Linux",
5
+ "main": "bin/jvm.js",
6
+ "scripts": {
7
+ "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
8
+ "check": "node bin/jvm.js --help",
9
+ "link": "npm unlink 2>/dev/null || true && npm link",
10
+ "build": "mkdir -p dist && cp bin/jvm.js dist/ && cp package.json dist/ && cp README.md dist/ && cp LICENSE dist/"
11
+ },
12
+ "author": "",
13
+ "license": "MIT",
14
+ "bin": {
15
+ "jvm": "bin/jvm.js"
16
+ },
17
+ "keywords": ["java", "jdk", "jvm", "cli", "linux", "openjdk"],
18
+ "engines": {
19
+ "node": ">=14"
20
+ },
21
+ "dependencies": {},
22
+ "devDependencies": {
23
+ "jest": "^29.7.0"
24
+ },
25
+ "type": "module",
26
+ "jest": {
27
+ "testMatch": [
28
+ "**/test/**/*.spec.mjs",
29
+ "**/test/**/*.test.js",
30
+ "**/test/**/*.spec.js"
31
+ ],
32
+ "transform": {},
33
+ "testEnvironment": "node",
34
+ "verbose": true
35
+ }
36
+ }
@@ -0,0 +1,45 @@
1
+ import { execSync } from "child_process";
2
+ import { existsSync, readFileSync, rmSync, writeFileSync } from "fs";
3
+ import { join, resolve } from "path";
4
+ import { homedir } from "os";
5
+
6
+ const HOME = homedir();
7
+ const APP_NAME = "jvm-manager";
8
+ const APP_DIR = join(HOME, ".local", "share", APP_NAME);
9
+ const JDKS_DIR = join(APP_DIR, "jdks");
10
+ const PROJECT_FILE = ".jvmrc";
11
+
12
+ // Helper function to run jvm commands
13
+ function runJvmCmd(cmd, options = {}) {
14
+ return execSync(`node bin/jvm.js ${cmd}`, {
15
+ encoding: "utf8",
16
+ stdio: "pipe",
17
+ ...options
18
+ }).trim();
19
+ }
20
+
21
+ describe("jvm CLI basic functionality", () => {
22
+ it("should display help information", () => {
23
+ const helpOutput = runJvmCmd("help");
24
+ expect(helpOutput.toLowerCase()).toContain("jvm - linux jdk manager");
25
+ expect(helpOutput.toLowerCase()).toContain("usage:");
26
+ });
27
+
28
+ it("should check system compatibility", () => {
29
+ const doctorOutput = runJvmCmd("doctor");
30
+ expect(doctorOutput.toLowerCase()).toContain("node.js");
31
+ expect(doctorOutput.toLowerCase()).toContain("architecture");
32
+ expect(doctorOutput.toLowerCase()).toContain("os platform");
33
+ });
34
+
35
+ it("should handle list command when no JDK installed", () => {
36
+ expect(() => {
37
+ runJvmCmd("list");
38
+ }).not.toThrowError();
39
+ });
40
+
41
+ it("should create temporary directories for testing", () => {
42
+ // This test is to ensure that the test environment is set up correctly
43
+ expect(true).toBeTruthy();
44
+ });
45
+ });
package/test/debug.js ADDED
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env node
2
+ import { existsSync, readdirSync } from "node:fs";
3
+ import { join } from "node:path";
4
+
5
+ const APP_NAME = "jvm-manager";
6
+ const HOME = process.env.HOME;
7
+ const APP_DIR = join(HOME, ".local", "share", APP_NAME);
8
+ const JDKS_DIR = join(APP_DIR, "jdks");
9
+
10
+ console.log("=== System JVM directory ===");
11
+ if (existsSync("/usr/lib/jvm")) {
12
+ console.log("/usr/lib/jvm exists");
13
+ console.log("Directories in /usr/lib/jvm:");
14
+ readdirSync("/usr/lib/jvm", { withFileTypes: true }).forEach(entry => {
15
+ console.log(` ${entry.name} (${entry.isDirectory() ? "directory" : "file"})`);
16
+ });
17
+ } else {
18
+ console.log("/usr/lib/jvm does NOT exist");
19
+ }
20
+
21
+ console.log("\n=== Local jvm-manager directory ===");
22
+ if (existsSync(APP_DIR)) {
23
+ console.log(APP_DIR + " exists");
24
+ console.log("Contents:");
25
+ readdirSync(APP_DIR, { withFileTypes: true }).forEach(entry => {
26
+ console.log(` ${entry.name} (${entry.isDirectory() ? "directory" : "file"})`);
27
+ if (entry.isDirectory() && entry.name === "jdks") {
28
+ console.log(" jdks contents:");
29
+ readdirSync(JDKS_DIR, { withFileTypes: true }).forEach(jdkEntry => {
30
+ console.log(` ${jdkEntry.name}`);
31
+ });
32
+ }
33
+ });
34
+ } else {
35
+ console.log(APP_DIR + " does NOT exist");
36
+ }
@@ -0,0 +1,16 @@
1
+ function detectLatestBuild(version) {
2
+ const arch = detectArch();
3
+
4
+ let osArch = "x64";
5
+ if (arch === "arm64") {
6
+ osArch = "aarch64";
7
+ }
8
+
9
+ const url = `https://download.java.net/java/GA/jdk${version}/latest/openjdk-${version}_linux-${osArch}_bin.tar.gz`;
10
+ const filename = `openjdk-${version}_linux-${osArch}_bin.tar.gz`;
11
+
12
+ return {
13
+ link: url,
14
+ filename: filename
15
+ };
16
+ }
@@ -0,0 +1,153 @@
1
+ function install(version) {
2
+ ensureDirs();
3
+ if (!/^\d+$/.test(version)) {
4
+ fail("Version should be a major number, e.g. 8, 11, 17, 21");
5
+ }
6
+ const target = join(JDKS_DIR, version);
7
+ if (existsSync(target)) {
8
+ console.log(`JDK ${version} already installed: ${target}`);
9
+ return;
10
+ }
11
+
12
+ // Detect OS and use appropriate package manager
13
+ const osRelease = getOSRelease();
14
+ console.log(`Detected OS: ${osRelease.PRETTY_NAME}`);
15
+
16
+ if (osRelease.ID === "ubuntu" || osRelease.ID === "debian") {
17
+ // For Ubuntu/Debian, use apt package manager
18
+ installUbuntuDebian(version, target);
19
+ } else if (osRelease.ID === "fedora" || osRelease.ID === "centos" || osRelease.ID === "rhel") {
20
+ // For Fedora/CentOS/RHEL, use dnf/yum
21
+ installFedoraCentOSRHEL(version, target);
22
+ } else if (osRelease.ID === "arch") {
23
+ // For Arch Linux, use pacman
24
+ installArchLinux(version, target);
25
+ } else {
26
+ // For other OSes, fall back to downloading
27
+ installFromDownload(version, target);
28
+ }
29
+ }
30
+
31
+ function installUbuntuDebian(version, target) {
32
+ const packageName = `openjdk-${version}-jdk`;
33
+
34
+ console.log(`Installing OpenJDK ${version} using apt...`);
35
+ run(`sudo apt update`);
36
+ run(`sudo apt install -y ${packageName}`);
37
+
38
+ // Find the installed JDK path
39
+ let jdkPath;
40
+ if (existsSync("/usr/lib/jvm")) {
41
+ const entries = readdirSync("/usr/lib/jvm", { withFileTypes: true });
42
+ for (const entry of entries) {
43
+ if (entry.isDirectory() && entry.name.includes(`java-${version}`)) {
44
+ jdkPath = join("/usr/lib/jvm", entry.name);
45
+ break;
46
+ }
47
+ }
48
+ }
49
+
50
+ if (!jdkPath) {
51
+ fail(`Could not find installed OpenJDK ${version} in /usr/lib/jvm`);
52
+ }
53
+
54
+ // Create symlink to system JDK
55
+ symlinkSync(jdkPath, target, "dir");
56
+ console.log(`Installed OpenJDK ${version} at ${target}`);
57
+ }
58
+
59
+ function installFedoraCentOSRHEL(version, target) {
60
+ const packageName = `java-${version}-openjdk-devel`;
61
+
62
+ console.log(`Installing OpenJDK ${version} using dnf...`);
63
+ run(`sudo dnf install -y ${packageName}`);
64
+
65
+ // Find the installed JDK path
66
+ let jdkPath;
67
+ if (existsSync("/usr/lib/jvm")) {
68
+ const entries = readdirSync("/usr/lib/jvm", { withFileTypes: true });
69
+ for (const entry of entries) {
70
+ if (entry.isDirectory() && entry.name.includes(`java-${version}`)) {
71
+ jdkPath = join("/usr/lib/jvm", entry.name);
72
+ break;
73
+ }
74
+ }
75
+ }
76
+
77
+ if (!jdkPath) {
78
+ fail(`Could not find installed OpenJDK ${version} in /usr/lib/jvm`);
79
+ }
80
+
81
+ // Create symlink to system JDK
82
+ symlinkSync(jdkPath, target, "dir");
83
+ console.log(`Installed OpenJDK ${version} at ${target}`);
84
+ }
85
+
86
+ function installArchLinux(version, target) {
87
+ const packageName = `jdk${version}-openjdk`;
88
+
89
+ console.log(`Installing OpenJDK ${version} using pacman...`);
90
+ run(`sudo pacman -Syu --noconfirm ${packageName}`);
91
+
92
+ // Find the installed JDK path
93
+ let jdkPath;
94
+ if (existsSync("/usr/lib/jvm")) {
95
+ const entries = readdirSync("/usr/lib/jvm", { withFileTypes: true });
96
+ for (const entry of entries) {
97
+ if (entry.isDirectory() && entry.name.includes(`java-${version}`)) {
98
+ jdkPath = join("/usr/lib/jvm", entry.name);
99
+ break;
100
+ }
101
+ }
102
+ }
103
+
104
+ if (!jdkPath) {
105
+ fail(`Could not find installed OpenJDK ${version} in /usr/lib/jvm`);
106
+ }
107
+
108
+ // Create symlink to system JDK
109
+ symlinkSync(jdkPath, target, "dir");
110
+ console.log(`Installed OpenJDK ${version} at ${target}`);
111
+ }
112
+
113
+ function installFromDownload(version, target) {
114
+ const { link, filename } = detectLatestBuild(version);
115
+ const tmpDir = run("mktemp -d");
116
+ const tarPath = join(tmpDir, filename);
117
+
118
+ try {
119
+ console.log(`Downloading JDK ${version}...`);
120
+ run(`curl -fL "${link}" -o "${tarPath}"`, { stdio: "inherit" });
121
+ mkdirSync(target, { recursive: true });
122
+ run(`tar -xzf "${tarPath}" -C "${target}" --strip-components=1`, { stdio: "inherit" });
123
+ } catch (error) {
124
+ rmSync(target, { recursive: true, force: true });
125
+ throw error;
126
+ } finally {
127
+ rmSync(tmpDir, { recursive: true, force: true });
128
+ }
129
+ console.log(`Installed JDK ${version} at ${target}`);
130
+ }
131
+
132
+ function getOSRelease() {
133
+ const releaseFile = "/etc/os-release";
134
+ if (!existsSync(releaseFile)) {
135
+ return {
136
+ ID: "unknown",
137
+ PRETTY_NAME: "Unknown"
138
+ };
139
+ }
140
+
141
+ const content = readFileSync(releaseFile, "utf8");
142
+ const releaseInfo = {};
143
+
144
+ content.split("\n").forEach(line => {
145
+ const trimmed = line.trim();
146
+ if (trimmed && !trimmed.startsWith("#")) {
147
+ const [key, value] = trimmed.split("=");
148
+ releaseInfo[key] = value ? value.replace(/['"]/g, "") : "";
149
+ }
150
+ });
151
+
152
+ return releaseInfo;
153
+ }
@@ -0,0 +1,73 @@
1
+ function main() {
2
+ const args = process.argv.slice(2);
3
+ const cmd = args[0];
4
+ if (!cmd || cmd === "-h" || cmd === "--help" || cmd === "help") {
5
+ usage();
6
+ return;
7
+ }
8
+
9
+ try {
10
+ if (cmd === "install") {
11
+ const version = args[1];
12
+ if (!version) fail("Missing version. Example: jvm install 17");
13
+ install(version);
14
+ return;
15
+ }
16
+ if (cmd === "link") {
17
+ const systemPath = args[1];
18
+ const version = args[2];
19
+ if (!systemPath || !version) fail("Usage: jvm link <system-path> <version>");
20
+ linkSystemJdk(systemPath, version);
21
+ return;
22
+ }
23
+ if (cmd === "list") {
24
+ listInstalled();
25
+ return;
26
+ }
27
+ if (cmd === "use") {
28
+ const version = args[1];
29
+ if (!version) fail("Missing version. Example: jvm use 21 --global");
30
+ const flags = parseFlags(args.slice(2));
31
+ if (flags.global && flags.project) {
32
+ fail("Cannot use --global and --project together");
33
+ }
34
+ if (flags.project) {
35
+ setProject(version);
36
+ } else {
37
+ setGlobal(version);
38
+ }
39
+ return;
40
+ }
41
+ if (cmd === "env") {
42
+ const flags = parseFlags(args.slice(1));
43
+ if (flags.global && flags.project) {
44
+ fail("Cannot use --global and --project together");
45
+ }
46
+ if (flags.project) {
47
+ printEnv("project");
48
+ } else {
49
+ printEnv("global");
50
+ }
51
+ return;
52
+ }
53
+ if (cmd === "current") {
54
+ showCurrent();
55
+ return;
56
+ }
57
+ if (cmd === "doctor") {
58
+ doctor();
59
+ return;
60
+ }
61
+ if (cmd === "remove") {
62
+ const version = args[1];
63
+ if (!version) fail("Missing version. Example: jvm remove 17");
64
+ removeJdk(version);
65
+ return;
66
+ }
67
+ } catch (error) {
68
+ const message = error?.stderr || error?.message || String(error);
69
+ fail(message);
70
+ }
71
+
72
+ fail(`Unknown command: ${cmd}`);
73
+ }
package/test/temp.js ADDED
@@ -0,0 +1,44 @@
1
+ function detectSystemJdks() {
2
+ const versions = new Set();
3
+
4
+ try {
5
+ if (existsSync("/usr/lib/jvm")) {
6
+ const entries = readdirSync("/usr/lib/jvm", { withFileTypes: true });
7
+ for (const entry of entries) {
8
+ if (entry.isDirectory() && entry.name.includes("-amd64") || entry.name.includes("-aarch64")) {
9
+ const match17 = entry.name.match(/java-17/);
10
+ const match8 = entry.name.match(/java-8/);
11
+ const match21 = entry.name.match(/java-21/);
12
+ if (match17) versions.add("17");
13
+ if (match8) versions.add("8");
14
+ if (match21) versions.add("21");
15
+ }
16
+ }
17
+ }
18
+ } catch (err) {
19
+ // Ignore errors when /usr/lib/jvm doesn't exist
20
+ }
21
+
22
+ try {
23
+ const versionStr = run("java -version 2>&1 | head -1");
24
+ const match = versionStr.match(/version "(.*)"/);
25
+ if (match) {
26
+ const javaVersion = match[1];
27
+ if (javaVersion.startsWith("1.")) {
28
+ const oldVersion = javaVersion.match(/1\.(\d+)\.0/);
29
+ if (oldVersion) {
30
+ versions.add(oldVersion[1]);
31
+ }
32
+ } else {
33
+ const newVersion = javaVersion.match(/(\d+)/);
34
+ if (newVersion) {
35
+ versions.add(newVersion[1]);
36
+ }
37
+ }
38
+ }
39
+ } catch (err) {
40
+ // Ignore errors when java is not available
41
+ }
42
+
43
+ return Array.from(versions).sort((a, b) => Number(a) - Number(b));
44
+ }