jdkman 0.1.2__tar.gz

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.
jdkman-0.1.2/PKG-INFO ADDED
@@ -0,0 +1,208 @@
1
+ Metadata-Version: 2.3
2
+ Name: jdkman
3
+ Version: 0.1.2
4
+ Summary: A command-line tool for installing and managing OpenJDK distributions.
5
+ Author: junghun.song
6
+ Author-email: junghun.song <xunyss@gmail.com>
7
+ Requires-Dist: requests>=2.32.5
8
+ Requires-Dist: typer-slim>=0.24.0
9
+ Requires-Python: >=3.12
10
+ Description-Content-Type: text/markdown
11
+
12
+ # jdkman
13
+
14
+ A command-line tool for installing and managing OpenJDK distributions.
15
+
16
+ ---
17
+
18
+ ## Why jdkman?
19
+
20
+ How often do you actually need to pick between `21.0.3` and `21.0.5`?
21
+ Probably never. "The latest Zulu 21" is almost always good enough.
22
+
23
+ jdkman manages JDKs at exactly that level — no more, no less.
24
+
25
+ - `jdk install zulu-21` — just pick a vendor and a major version
26
+ - `jdk upgrade zulu-21` — updates to the latest patch automatically
27
+ - One installation per vendor + major version, always
28
+
29
+ No scrolling through minor version lists. No patch versions piling up.
30
+
31
+ On macOS, JDKs are installed under `~/Library/Java/JavaVirtualMachines/` — the standard
32
+ path where Gradle, IntelliJ, and most other tools automatically look for JDKs.
33
+ No extra configuration needed.
34
+
35
+ ---
36
+
37
+ ## Requirements
38
+
39
+ - Python 3.12+
40
+
41
+ ## Installation
42
+
43
+ ```bash
44
+ pip install jdkman
45
+ ```
46
+
47
+ ## Quick Start
48
+
49
+ ```bash
50
+ # Browse available JDK distributions
51
+ jdk remote
52
+
53
+ # Install a distribution
54
+ jdk install zulu-21
55
+
56
+ # List installed distributions
57
+ jdk list
58
+
59
+ # Check for outdated installations
60
+ jdk outdated
61
+ ```
62
+
63
+ ---
64
+
65
+ ## Commands
66
+
67
+ ### `jdk remote [DISTRO]`
68
+
69
+ Browse JDK distributions available for download.
70
+
71
+ By default, shows only stable JDK builds. Use flags to include additional build types.
72
+
73
+ ```bash
74
+ jdk remote # List all stable JDK builds
75
+ jdk remote zulu # Filter by vendor prefix
76
+ jdk remote --version 21 # Filter by major version
77
+ jdk remote --all # Include JRE and feature builds
78
+ jdk remote --with-jre # Include JRE builds
79
+ jdk remote --with-feat # Include feature builds (e.g. JavaFX, CRaC)
80
+ jdk remote --all zulu # Combined: all build types, zulu only
81
+ ```
82
+
83
+ **Options:**
84
+
85
+ | Option | Short | Description |
86
+ |--------|-------|-------------|
87
+ | `--version` | `-v` | Filter by major version number |
88
+ | `--all` | `-a` | Include all build types |
89
+ | `--with-jre` | `-R` | Include JRE builds |
90
+ | `--with-feat` | `-F` | Include feature builds |
91
+
92
+ ---
93
+
94
+ ### `jdk install <DISTRO>`
95
+
96
+ Download and install a JDK distribution.
97
+
98
+ ```bash
99
+ jdk install zulu-21
100
+ jdk install temurin-17
101
+ jdk install zulu-jre-21 # JRE variant
102
+ jdk install zulu-javafx-21 # With JavaFX
103
+ jdk install zulu-crac-21 # With CRaC
104
+ jdk install zulu-javafx-jre-21 # JRE + JavaFX
105
+ ```
106
+
107
+ The `DISTRO` name follows this pattern:
108
+ ```
109
+ {vendor}[-{feature}][-jre]-{major_version}
110
+ ```
111
+
112
+ Use `jdk remote` to find the exact distribution name.
113
+
114
+ ---
115
+
116
+ ### `jdk list`
117
+
118
+ Show all installed JDK distributions managed by jdkman.
119
+
120
+ ```bash
121
+ jdk list
122
+ jdk ls # alias
123
+ ```
124
+
125
+ ---
126
+
127
+ ### `jdk uninstall <DISTRO>`
128
+
129
+ Remove an installed JDK distribution.
130
+
131
+ ```bash
132
+ jdk uninstall zulu-21
133
+ jdk remove zulu-21 # alias
134
+ jdk rm zulu-21 # alias
135
+ ```
136
+
137
+ ---
138
+
139
+ ### `jdk upgrade <DISTRO>`
140
+
141
+ Upgrade an installed distribution to the latest patch version.
142
+
143
+ ```bash
144
+ jdk upgrade zulu-21
145
+ jdk update zulu-21 # alias
146
+ ```
147
+
148
+ ---
149
+
150
+ ### `jdk outdated`
151
+
152
+ List installed distributions that have newer versions available.
153
+
154
+ ```bash
155
+ jdk outdated
156
+ ```
157
+
158
+ ---
159
+
160
+ ### `jdk vendors`
161
+
162
+ List all available JDK vendors.
163
+
164
+ ```bash
165
+ jdk vendors
166
+ jdk vendor # alias
167
+ ```
168
+
169
+ ---
170
+
171
+ ### `jdk cleanup`
172
+
173
+ Remove cached data (downloaded archives and catalog cache).
174
+
175
+ ```bash
176
+ jdk cleanup
177
+ jdk clean # alias
178
+ jdk clear # alias
179
+ ```
180
+
181
+ ---
182
+
183
+ ### `jdk home` *(macOS only)*
184
+
185
+ Show Java home paths for JVMs registered with the system.
186
+
187
+ ```bash
188
+ jdk home # List registered Java installations
189
+ jdk home --json # Show detailed info in JSON format
190
+ ```
191
+
192
+ ---
193
+
194
+ ### `jdk version`
195
+
196
+ Show the jdkman version.
197
+
198
+ ```bash
199
+ jdk version
200
+ jdk --version
201
+ jdk -v
202
+ ```
203
+
204
+ ---
205
+
206
+ ## License
207
+
208
+ MIT
jdkman-0.1.2/README.md ADDED
@@ -0,0 +1,197 @@
1
+ # jdkman
2
+
3
+ A command-line tool for installing and managing OpenJDK distributions.
4
+
5
+ ---
6
+
7
+ ## Why jdkman?
8
+
9
+ How often do you actually need to pick between `21.0.3` and `21.0.5`?
10
+ Probably never. "The latest Zulu 21" is almost always good enough.
11
+
12
+ jdkman manages JDKs at exactly that level — no more, no less.
13
+
14
+ - `jdk install zulu-21` — just pick a vendor and a major version
15
+ - `jdk upgrade zulu-21` — updates to the latest patch automatically
16
+ - One installation per vendor + major version, always
17
+
18
+ No scrolling through minor version lists. No patch versions piling up.
19
+
20
+ On macOS, JDKs are installed under `~/Library/Java/JavaVirtualMachines/` — the standard
21
+ path where Gradle, IntelliJ, and most other tools automatically look for JDKs.
22
+ No extra configuration needed.
23
+
24
+ ---
25
+
26
+ ## Requirements
27
+
28
+ - Python 3.12+
29
+
30
+ ## Installation
31
+
32
+ ```bash
33
+ pip install jdkman
34
+ ```
35
+
36
+ ## Quick Start
37
+
38
+ ```bash
39
+ # Browse available JDK distributions
40
+ jdk remote
41
+
42
+ # Install a distribution
43
+ jdk install zulu-21
44
+
45
+ # List installed distributions
46
+ jdk list
47
+
48
+ # Check for outdated installations
49
+ jdk outdated
50
+ ```
51
+
52
+ ---
53
+
54
+ ## Commands
55
+
56
+ ### `jdk remote [DISTRO]`
57
+
58
+ Browse JDK distributions available for download.
59
+
60
+ By default, shows only stable JDK builds. Use flags to include additional build types.
61
+
62
+ ```bash
63
+ jdk remote # List all stable JDK builds
64
+ jdk remote zulu # Filter by vendor prefix
65
+ jdk remote --version 21 # Filter by major version
66
+ jdk remote --all # Include JRE and feature builds
67
+ jdk remote --with-jre # Include JRE builds
68
+ jdk remote --with-feat # Include feature builds (e.g. JavaFX, CRaC)
69
+ jdk remote --all zulu # Combined: all build types, zulu only
70
+ ```
71
+
72
+ **Options:**
73
+
74
+ | Option | Short | Description |
75
+ |--------|-------|-------------|
76
+ | `--version` | `-v` | Filter by major version number |
77
+ | `--all` | `-a` | Include all build types |
78
+ | `--with-jre` | `-R` | Include JRE builds |
79
+ | `--with-feat` | `-F` | Include feature builds |
80
+
81
+ ---
82
+
83
+ ### `jdk install <DISTRO>`
84
+
85
+ Download and install a JDK distribution.
86
+
87
+ ```bash
88
+ jdk install zulu-21
89
+ jdk install temurin-17
90
+ jdk install zulu-jre-21 # JRE variant
91
+ jdk install zulu-javafx-21 # With JavaFX
92
+ jdk install zulu-crac-21 # With CRaC
93
+ jdk install zulu-javafx-jre-21 # JRE + JavaFX
94
+ ```
95
+
96
+ The `DISTRO` name follows this pattern:
97
+ ```
98
+ {vendor}[-{feature}][-jre]-{major_version}
99
+ ```
100
+
101
+ Use `jdk remote` to find the exact distribution name.
102
+
103
+ ---
104
+
105
+ ### `jdk list`
106
+
107
+ Show all installed JDK distributions managed by jdkman.
108
+
109
+ ```bash
110
+ jdk list
111
+ jdk ls # alias
112
+ ```
113
+
114
+ ---
115
+
116
+ ### `jdk uninstall <DISTRO>`
117
+
118
+ Remove an installed JDK distribution.
119
+
120
+ ```bash
121
+ jdk uninstall zulu-21
122
+ jdk remove zulu-21 # alias
123
+ jdk rm zulu-21 # alias
124
+ ```
125
+
126
+ ---
127
+
128
+ ### `jdk upgrade <DISTRO>`
129
+
130
+ Upgrade an installed distribution to the latest patch version.
131
+
132
+ ```bash
133
+ jdk upgrade zulu-21
134
+ jdk update zulu-21 # alias
135
+ ```
136
+
137
+ ---
138
+
139
+ ### `jdk outdated`
140
+
141
+ List installed distributions that have newer versions available.
142
+
143
+ ```bash
144
+ jdk outdated
145
+ ```
146
+
147
+ ---
148
+
149
+ ### `jdk vendors`
150
+
151
+ List all available JDK vendors.
152
+
153
+ ```bash
154
+ jdk vendors
155
+ jdk vendor # alias
156
+ ```
157
+
158
+ ---
159
+
160
+ ### `jdk cleanup`
161
+
162
+ Remove cached data (downloaded archives and catalog cache).
163
+
164
+ ```bash
165
+ jdk cleanup
166
+ jdk clean # alias
167
+ jdk clear # alias
168
+ ```
169
+
170
+ ---
171
+
172
+ ### `jdk home` *(macOS only)*
173
+
174
+ Show Java home paths for JVMs registered with the system.
175
+
176
+ ```bash
177
+ jdk home # List registered Java installations
178
+ jdk home --json # Show detailed info in JSON format
179
+ ```
180
+
181
+ ---
182
+
183
+ ### `jdk version`
184
+
185
+ Show the jdkman version.
186
+
187
+ ```bash
188
+ jdk version
189
+ jdk --version
190
+ jdk -v
191
+ ```
192
+
193
+ ---
194
+
195
+ ## License
196
+
197
+ MIT
@@ -0,0 +1,31 @@
1
+ [project]
2
+ name = "jdkman"
3
+ version = "0.1.2"
4
+ description = "A command-line tool for installing and managing OpenJDK distributions."
5
+ authors = [{name = "junghun.song", email = "xunyss@gmail.com"}]
6
+ readme = "README.md"
7
+ requires-python = ">=3.12"
8
+ dependencies = [
9
+ "requests>=2.32.5",
10
+ "typer-slim>=0.24.0",
11
+ ]
12
+
13
+ [project.scripts]
14
+ jdk = "jdkman.cli:app"
15
+
16
+ [tool.setuptools.packages.find]
17
+ where = ["src"]
18
+
19
+ [tool.pytest.ini_options]
20
+ testpaths = ["tests"]
21
+ pythonpath = ["src"]
22
+
23
+ [build-system]
24
+ requires = ["uv_build >= 0.8.14, <0.11.0"]
25
+ build-backend = "uv_build"
26
+
27
+ [dependency-groups]
28
+ dev = [
29
+ "pytest>=9.0.2",
30
+ ]
31
+
File without changes
@@ -0,0 +1,203 @@
1
+ import json
2
+ import time
3
+
4
+ import requests
5
+
6
+ from .config import CATALOG_CACHE_FILE, CATALOG_CACHE_TTL, JVM_API_URL
7
+ from .console import out
8
+ from .utils import version_key
9
+
10
+
11
+ def fetch_artifacts() -> list[dict]:
12
+ """
13
+ {
14
+ "checksum": "sha256:0000000000000000000000000000000000000000000000000000000000000000",
15
+ "created_at": "2025-03-28T22:02:46.826962",
16
+ "features": [],
17
+ "file_type": "zip",
18
+ "image_type": "jre",
19
+ "java_version": "17.0.2",
20
+ "jvm_impl": "hotspot",
21
+ "url": "https://cdn.azul.com/zulu/bin/zulu17.32.13-ca-jre17.0.2-macosx_aarch64.zip",
22
+ "vendor": "zulu",
23
+ "version": "17.32.13.0"
24
+ }
25
+ """
26
+ if CATALOG_CACHE_FILE.exists() and (time.time() - CATALOG_CACHE_FILE.stat().st_mtime) < CATALOG_CACHE_TTL:
27
+ artifacts = json.loads(CATALOG_CACHE_FILE.read_text())
28
+ else:
29
+ out("==> Fetching JVM Database...")
30
+ response = requests.get(JVM_API_URL, timeout=30)
31
+ response.raise_for_status()
32
+ artifacts: list[dict] = response.json()
33
+
34
+ CATALOG_CACHE_FILE.parent.mkdir(parents=True, exist_ok=True)
35
+ CATALOG_CACHE_FILE.write_text(json.dumps(artifacts))
36
+
37
+ return artifacts
38
+
39
+
40
+ def fetch_releases():
41
+ """
42
+ {
43
+ "vendor": "zulu",
44
+ "image_type": "jre",
45
+ "features": [],
46
+ "jvm_impl": "hotspot",
47
+ "java_version": "17.0.2",
48
+ "version": "17.32.13.0",
49
+ "dists": [
50
+ {
51
+ "file_type": "zip",
52
+ "url": "https://cdn.azul.com/zulu/bin/zulu17.32.13-ca-jre17.0.2-macosx_aarch64.zip",
53
+ "checksum": "sha256:0000000000000000000000000000000000000000000000000000000000000000",
54
+ "created_at": "2025-03-28T22:02:46.826962"
55
+ },
56
+ ...
57
+ ]
58
+ }
59
+ """
60
+ _group_keys = ("vendor", "image_type", "features", "jvm_impl", "java_version", "version")
61
+ _dist_keys = ("file_type", "url", "checksum", "created_at")
62
+ releases: dict[tuple, dict] = {}
63
+ for artifact in fetch_artifacts():
64
+ key = (artifact["vendor"], artifact["image_type"], tuple(sorted(artifact["features"])), artifact["jvm_impl"], artifact["java_version"], artifact["version"])
65
+ if key not in releases:
66
+ releases[key] = {
67
+ k: artifact[k]
68
+ for k in _group_keys
69
+ } | {
70
+ "dists": []
71
+ }
72
+
73
+ releases[key]["dists"].append({
74
+ k: artifact[k] for k in _dist_keys
75
+ })
76
+
77
+ return list(releases.values())
78
+
79
+
80
+ def make_slug(release_info: dict) -> str:
81
+ """
82
+ features cases: [
83
+ "[]",
84
+ ["javafx"]", # zulu
85
+ ["crac"], # zulu
86
+ ["jcef"]", # jetbrains
87
+ ["lite"], # liberica
88
+ ["javafx", "libericafx", "minimal-vm"], # liberica
89
+ ["notarized"] # kona
90
+ ]
91
+ jvm_impl cases: [
92
+ "hotspot",
93
+ "graalvm",
94
+ "openj9" # semeru (semeru 의 모든 dist 는 "openj9" 임)
95
+ ]
96
+ """
97
+ feature = release_info["features"][0] if release_info["features"] and release_info["features"] != ["notarized"] else ""
98
+ jvm_impl = release_info["jvm_impl"] if release_info["jvm_impl"] not in ["hotspot", "graalvm"] else ""
99
+
100
+ parts = [release_info["vendor"]]
101
+ if release_info["image_type"] == "jre":
102
+ parts.append(release_info["image_type"])
103
+ if feature:
104
+ parts.append(feature)
105
+ if jvm_impl:
106
+ parts.append(jvm_impl)
107
+ parts.append(str(release_info["major_version"]))
108
+
109
+ return "-".join(parts)
110
+
111
+
112
+ def fetch_slugs():
113
+ """
114
+ {
115
+ "zulu-jre-17": {
116
+ "vendor": "zulu",
117
+ "image_type": "jre",
118
+ "features": [],
119
+ "jvm_impl": "hotspot",
120
+ "major_version": 17,
121
+ "latest": "17.64.17.0",
122
+ "versions": [
123
+ {
124
+ "java_version": "17.0.2",
125
+ "version": "17.64.15.0",
126
+ "dists": [
127
+ {
128
+ "file_type": "tar.gz",
129
+ "url": "https://cdn.azul.com/zulu/bin/zulu17.64.15-ca-jre17.0.18-macosx_aarch64.tar.gz",
130
+ "checksum": "sha256:0000000000000000000000000000000000000000000000000000000000000000",
131
+ "created_at": "2026-01-21T22:04:16.168823"
132
+ },
133
+ ...
134
+ ]
135
+ },
136
+ ...
137
+ ]
138
+ },
139
+ ...
140
+ }
141
+ """
142
+ slugs: dict[str, dict] = {}
143
+ for release in fetch_releases():
144
+ release_info = {
145
+ "vendor": release["vendor"],
146
+ "image_type": release["image_type"],
147
+ "features": release["features"],
148
+ "jvm_impl": release["jvm_impl"],
149
+ "major_version": version_key(release["java_version"])[0][0],
150
+ }
151
+ slug = make_slug(release_info)
152
+ if slug not in slugs:
153
+ slugs[slug] = release_info | {
154
+ "latest": release["version"],
155
+ "versions": [],
156
+ }
157
+ else:
158
+ if version_key(release["version"]) > version_key(slugs[slug]["latest"]):
159
+ slugs[slug]["latest"] = release["version"]
160
+
161
+ slugs[slug]["versions"].append({
162
+ "java_version": release["java_version"],
163
+ "version": release["version"],
164
+ "dists": release["dists"]
165
+ })
166
+
167
+ return slugs
168
+
169
+
170
+ def sort_slugs(slugs: dict) -> dict:
171
+ # 3. dists 정렬: created_at
172
+ def sort_dists(versions):
173
+ return [
174
+ {
175
+ **version,
176
+ "dists": sorted(version["dists"], key=lambda x: x["created_at"])
177
+ }
178
+ for version in versions
179
+ ]
180
+
181
+ # 2. versions 정렬: version
182
+ def sort_versions(versions):
183
+ sorted_versions = sorted(versions, key=lambda x: version_key(x["version"]))
184
+ return sort_dists(sorted_versions)
185
+
186
+ # 1. slug 객체 정렬: vendor, image_type, features[0], major_version
187
+ def slug_sort_key(slug_item):
188
+ slug, slug_info = slug_item
189
+ return (
190
+ slug_info["vendor"],
191
+ slug_info["image_type"],
192
+ slug_info["features"][0] if slug_info["features"] else "",
193
+ slug_info["major_version"],
194
+ )
195
+
196
+ return {
197
+ slug: {
198
+ **slug_info,
199
+ "versions": sort_versions(slug_info["versions"])
200
+ }
201
+ for slug, slug_info in sorted(slugs.items(), key=slug_sort_key)
202
+ }
203
+