daktari 0.0.236__py3-none-any.whl → 0.0.254__py3-none-any.whl

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.

Potentially problematic release.


This version of daktari might be problematic. Click here for more details.

daktari/checks/git.py DELETED
@@ -1,198 +0,0 @@
1
- import logging
2
- from typing import Optional
3
-
4
- from daktari.check import Check, CheckResult
5
- from daktari.command_utils import can_run_command, get_stdout
6
- from daktari.file_utils import file_contains_text, is_ascii
7
- from daktari.os import OS
8
- from daktari.version_utils import get_simple_cli_version
9
-
10
-
11
- class GitInstalled(Check):
12
- name = "git.installed"
13
-
14
- suggestions = {
15
- OS.OS_X: "<cmd>brew install git</cmd>",
16
- OS.UBUNTU: "<cmd>sudo apt install git</cmd>",
17
- OS.GENERIC: "Install Git: https://git-scm.com/downloads",
18
- }
19
-
20
- def check(self) -> CheckResult:
21
- if can_run_command("git version"):
22
- return self.passed("Git is installed")
23
- else:
24
- return self.failed("Could not find git on the path")
25
-
26
-
27
- class GitLfsInstalled(Check):
28
- name = "git.lfs.installed"
29
- depends_on = [GitInstalled]
30
-
31
- suggestions = {
32
- OS.OS_X: "<cmd>brew install git-lfs</cmd>",
33
- OS.UBUNTU: "<cmd>sudo apt install git-lfs</cmd>",
34
- OS.GENERIC: "Install Git LFS: https://github.com/git-lfs/git-lfs/wiki/Installation",
35
- }
36
-
37
- def check(self) -> CheckResult:
38
- return self.verify(can_run_command("git lfs version"), "Git LFS is <not/> installed")
39
-
40
-
41
- class GitLfsSetUpForUser(Check):
42
- name = "git.lfs.setUpForUser"
43
- depends_on = [GitLfsInstalled]
44
-
45
- suggestions = {
46
- OS.GENERIC: """
47
- Set up Git LFS for your user account:
48
- <cmd>git lfs install</cmd>
49
- """
50
- }
51
-
52
- def check(self) -> CheckResult:
53
- output = get_stdout("git lfs env")
54
- passed = bool(output and "git-lfs filter-process" in output)
55
- return self.verify(passed, "Git LFS is <not/> set up for the current user")
56
-
57
-
58
- class GitLfsFilesDownloaded(Check):
59
- name = "git.lfs.filesDownloaded"
60
- depends_on = [GitLfsSetUpForUser]
61
-
62
- suggestions = {
63
- OS.GENERIC: """
64
- Download all Git LFS files and update working copy with the downloaded content:
65
- <cmd>git lfs pull</cmd>
66
- """
67
- }
68
-
69
- def check(self) -> CheckResult:
70
- output = get_stdout("git lfs ls-files") or ""
71
- files_not_downloaded = [line.split()[2] for line in output.splitlines() if line.split()[1] == "-"]
72
- for file in files_not_downloaded:
73
- logging.info(f"Git LFS file not downloaded: {file}")
74
- passed = len(files_not_downloaded) == 0
75
- return self.verify(passed, "Git LFS files have <not/> been downloaded")
76
-
77
-
78
- class GitCryptInstalled(Check):
79
- name = "git.crypt.installed"
80
- depends_on = [GitInstalled]
81
-
82
- suggestions = {
83
- OS.OS_X: "<cmd>brew install git-crypt</cmd>",
84
- OS.UBUNTU: "<cmd>sudo apt install git-crypt</cmd>",
85
- OS.GENERIC: "Install git-crypt: https://www.agwa.name/projects/git-crypt/",
86
- }
87
-
88
- def check(self) -> CheckResult:
89
- return self.verify(can_run_command("git crypt version"), "git-crypt is <not/> installed")
90
-
91
-
92
- class GitCryptUnlocked(Check):
93
- name = "git.crypt.unlocked"
94
- depends_on = [GitCryptInstalled]
95
-
96
- def __init__(self, fileToCheck: str):
97
- self.fileToCheck = fileToCheck
98
-
99
- suggestions = {
100
- OS.GENERIC: """
101
- Unlock this repository with:
102
- <cmd>git-crypt unlock</cmd>
103
- """,
104
- }
105
-
106
- def check(self) -> CheckResult:
107
- is_unlocked = is_ascii(self.fileToCheck)
108
- return self.verify(is_unlocked, "Encrypted files have <not/> been unlocked")
109
-
110
-
111
- class PreCommitInstalled(Check):
112
- name = "preCommit.installed"
113
- depends_on = [GitInstalled]
114
-
115
- def __init__(self, required_version: Optional[str] = None, recommended_version: Optional[str] = None):
116
- self.required_version = required_version
117
- self.recommended_version = recommended_version
118
-
119
- suggestions = {
120
- OS.OS_X: "<cmd>brew install pre-commit</cmd>",
121
- OS.GENERIC: "Install pre-commit: https://pre-commit.com/#installation",
122
- }
123
-
124
- def check(self) -> CheckResult:
125
- installed_version = get_simple_cli_version("pre-commit")
126
- return self.validate_semver_expression(
127
- "pre-commit", installed_version, self.required_version, self.recommended_version
128
- )
129
-
130
-
131
- class PreCommitGitHooksInstalled(Check):
132
- name = "preCommit.gitHooksInstalled"
133
- depends_on = [PreCommitInstalled]
134
-
135
- suggestions = {
136
- OS.GENERIC: "<cmd>pre-commit install</cmd>",
137
- }
138
-
139
- def check(self) -> CheckResult:
140
- git_hooks_installed = file_contains_text(".git/hooks/pre-commit", "pre-commit.com")
141
- return self.verify(git_hooks_installed, "pre-commit Git hooks are <not/> installed")
142
-
143
-
144
- class GpgInstalled(Check):
145
- name = "gpg.installed"
146
-
147
- suggestions = {
148
- OS.OS_X: "<cmd>brew install gpg2 gnupg pinentry-mac</cmd>",
149
- OS.UBUNTU: "<cmd>sudo apt install gpg</cmd>",
150
- OS.GENERIC: "Install gpg: https://gnupg.org/",
151
- }
152
-
153
- def check(self) -> CheckResult:
154
- return self.verify_install("gpg")
155
-
156
-
157
- class GitCommitSigningSetUp(Check):
158
- name = "git.commitSigningSetUp"
159
-
160
- suggestions = {
161
- OS.OS_X: "Follow instructions to set up commit signing: "
162
- "https://gist.github.com/troyfontaine/18c9146295168ee9ca2b30c00bd1b41e#file-2-using-gpg-md",
163
- OS.UBUNTU: "Follow instructions to set up commit signing: "
164
- "https://brain2life.hashnode.dev/how-to-sign-your-git-commits-in-ubuntu-2004-and-why-you-need-it",
165
- }
166
-
167
- def check(self) -> CheckResult:
168
- key = get_stdout("git config user.signingkey")
169
- passed = key is not None and key != ""
170
- return self.verify(passed, "user.signingkey is <not/> set")
171
-
172
-
173
- class GitCommitAutoSigningEnabled(Check):
174
- name = "git.commitAutoSigningEnabled"
175
- depends_on = [GitCommitSigningSetUp]
176
-
177
- suggestions = {OS.GENERIC: "<cmd>git config commit.gpgsign true</cmd>"}
178
-
179
- def check(self) -> CheckResult:
180
- setting = get_stdout("git config commit.gpgsign")
181
- passed = setting == "true"
182
- return self.verify(passed, "commit.gpgsign is <not/> enabled")
183
-
184
-
185
- class GitCommitSigningFormat(Check):
186
- name = "git.commitSigningFormat"
187
-
188
- def __init__(self, required_format: str, suggestion: str):
189
- self.required_format = required_format
190
- self.suggestions = {OS.GENERIC: suggestion}
191
-
192
- def check(self) -> CheckResult:
193
- format_setting = get_stdout("git config gpg.format")
194
- return self.verify(
195
- format_setting == self.required_format,
196
- f"gpg.format is {self.required_format}",
197
- f"gpg.format is not {self.required_format}: {format_setting}",
198
- )
daktari/checks/google.py DELETED
@@ -1,113 +0,0 @@
1
- import json
2
- import logging
3
- import os.path
4
- from json import JSONDecodeError
5
- from typing import Optional
6
-
7
- from daktari.check import Check, CheckResult
8
- from daktari.command_utils import can_run_command
9
- from daktari.file_utils import file_exists
10
- from daktari.os import OS
11
- from daktari.version_utils import get_simple_cli_version
12
-
13
-
14
- class GoogleCloudSdkInstalled(Check):
15
- name = "google.cloudSdkInstalled"
16
-
17
- suggestions = {
18
- OS.OS_X: """<cmd>brew install --cask google-cloud-sdk</cmd>
19
-
20
- Then, add the gcloud components to your PATH.
21
-
22
- For bash users, add this to ~/.bashrc:
23
- source "$(brew --prefix)/Caskroom/google-cloud-sdk/latest/google-cloud-sdk/path.bash.inc"
24
-
25
- For zsh users, add this to ~/.zhsrc:
26
- source "$(brew --prefix)/Caskroom/google-cloud-sdk/latest/google-cloud-sdk/path.zsh.inc\" """,
27
- OS.UBUNTU: "<cmd>sudo snap install google-cloud-sdk --classic</cmd>",
28
- OS.GENERIC: "Install gcloud: https://cloud.google.com/sdk/docs/quickstart",
29
- }
30
-
31
- def check(self) -> CheckResult:
32
- return self.verify(can_run_command("gcloud --version"), "Google Cloud SDK is <not/> installed and on $PATH")
33
-
34
-
35
- class CloudSqlProxyInstalled(Check):
36
- name = "google.cloudSqlProxyInstalled"
37
-
38
- def __init__(self, required_version: Optional[str] = None, recommended_version: Optional[str] = None):
39
- self.required_version = required_version
40
- self.recommended_version = recommended_version
41
-
42
- suggestions = {
43
- OS.GENERIC: "Install Cloud SQL Proxy: <cmd>gcloud components install cloud_sql_proxy</cmd>",
44
- }
45
-
46
- def check(self) -> CheckResult:
47
- installed_version = get_simple_cli_version("cloud_sql_proxy")
48
- return self.validate_semver_expression(
49
- "cloud_sql_proxy", installed_version, self.required_version, self.recommended_version
50
- )
51
-
52
-
53
- class GkeGcloudAuthPluginInstalled(Check):
54
- name = "google.gkeGcloudAuthPluginInstalled"
55
- depends_on = [GoogleCloudSdkInstalled]
56
-
57
- suggestions = {
58
- OS.UBUNTU: "<cmd>sudo apt-get install google-cloud-sdk-gke-gcloud-auth-plugin</cmd>",
59
- OS.GENERIC: "<cmd>gcloud components install gke-gcloud-auth-plugin</cmd>",
60
- }
61
-
62
- def check(self) -> CheckResult:
63
- return self.verify(can_run_command("gke-gcloud-auth-plugin --version "), "GKE auth plugin is <not/> installed")
64
-
65
-
66
- class DockerGoogleCloudAuthConfigured(Check):
67
- name = "google.dockerGCloudAuthConfigured"
68
- depends_on = [GoogleCloudSdkInstalled]
69
-
70
- def __init__(self, cloud_project, region, registry):
71
- self.registry = registry
72
- self.suggestions = {
73
- OS.GENERIC: f"""
74
- Setup gcloud authentication and docker credential helper for gcloud.
75
- The following commands will open your browser and ask you to login and approve.
76
- Run:
77
- <cmd>rm -r ~/.config/gcloud</cmd>
78
- <cmd>gcloud auth login</cmd>
79
- <cmd>gcloud config set project {cloud_project}</cmd>
80
- <cmd>gcloud config set --quiet compute/zone {region}</cmd>
81
- <cmd>gcloud auth application-default login</cmd>
82
- <cmd>gcloud auth configure-docker {registry}</cmd>
83
- """
84
- }
85
-
86
- def check(self) -> CheckResult:
87
- # Logged in with gcloud
88
- google_config_path = os.path.expanduser("~/.config/gcloud/application_default_credentials.json")
89
- if not file_exists(google_config_path):
90
- return self.failed(f"{google_config_path} does not exist")
91
-
92
- if not can_run_command("gcloud auth application-default print-access-token"):
93
- return self.failed("Application Default Credentials are not correctly set up")
94
-
95
- # Docker configured correctly
96
- docker_config_path = os.path.expanduser("~/.docker/config.json")
97
- if not file_exists(docker_config_path):
98
- return self.failed(f"{docker_config_path} does not exist")
99
-
100
- try:
101
- with open(docker_config_path, "rb") as docker_config_file:
102
- docker_config = json.load(docker_config_file)
103
- except IOError:
104
- logging.error(f"Exception reading {docker_config_path}", exc_info=True)
105
- return self.failed(f"Failed to read {docker_config_path}")
106
- except JSONDecodeError:
107
- logging.error(f"Exception parsing {docker_config_path}", exc_info=True)
108
- return self.failed(f"Failed to parse {docker_config_path}")
109
-
110
- if docker_config.get("credHelpers", {}).get(self.registry) != "gcloud":
111
- return self.failed("docker gcloud auth for {self.registry} not configured")
112
-
113
- return self.passed("docker gcloud auth configured")
@@ -1,248 +0,0 @@
1
- import json
2
- import logging
3
- import os
4
- from json.decoder import JSONDecodeError
5
- from pathlib import Path
6
- from typing import Optional
7
- from xml.etree.ElementTree import Element
8
-
9
- import dpath.util
10
- from semver import VersionInfo
11
-
12
- from daktari.check import Check, CheckResult
13
- from daktari.checks.files import FilesExist
14
- from daktari.checks.xml import XmlFileXPathCheck
15
- from daktari.command_utils import get_stdout
16
- from daktari.os import OS, detect_os
17
- from daktari.version_utils import try_parse_semver, sanitise_version_string
18
-
19
- BUNDLE_ID_INTELLIJ_IDEA = "com.jetbrains.intellij"
20
- BUNDLE_ID_INTELLIJ_IDEA_CE = "com.jetbrains.intellij.ce"
21
-
22
- SNAP_NAME_INTELLIJ_IDEA = "intellij-idea-ultimate"
23
- SNAP_NAME_INTELLIJ_IDEA_CE = "intellij-idea-community"
24
-
25
-
26
- def locate_intellij_idea_mac():
27
- from AppKit import NSWorkspace
28
-
29
- for bundle_id in (BUNDLE_ID_INTELLIJ_IDEA, BUNDLE_ID_INTELLIJ_IDEA_CE):
30
- url = NSWorkspace.sharedWorkspace().URLForApplicationWithBundleIdentifier_(bundle_id)
31
- if url is not None:
32
- logging.debug(f"IntelliJ IDEA location (via NSWorkspace): {url}")
33
- return url
34
-
35
- logging.debug("Could not find IntelliJ IDEA (via NSWorkspace)")
36
- return None
37
-
38
-
39
- def get_intellij_idea_version_mac() -> Optional[VersionInfo]:
40
- intellij_url = locate_intellij_idea_mac()
41
- if intellij_url is None:
42
- return None
43
- else:
44
- from Foundation import NSBundle
45
-
46
- version_str = NSBundle.bundleWithURL_(intellij_url).objectForInfoDictionaryKey_("CFBundleShortVersionString")
47
-
48
- version_str = sanitise_version_string(version_str)
49
- version = try_parse_semver(version_str)
50
-
51
- logging.debug(f"IntelliJ IDEA version (via NSBundle): {version} ({version_str})")
52
- return version
53
-
54
-
55
- def get_intellij_idea_version_snap() -> Optional[VersionInfo]:
56
- if not Path("/run/snapd.socket").is_socket():
57
- logging.debug("/run/snapd.socket does not exist, not querying snapd")
58
- return None
59
-
60
- from requests_unixsocket import Session
61
-
62
- session = Session()
63
- snaps_req = session.get(
64
- f"http+unix://%2Frun%2Fsnapd.socket/v2/snaps?snaps={SNAP_NAME_INTELLIJ_IDEA},{SNAP_NAME_INTELLIJ_IDEA_CE}"
65
- )
66
- snaps_info = snaps_req.json()
67
- logging.debug(f"response from snapd: {snaps_info}")
68
- version_str = dpath.util.get(snaps_info, "/result/0/version", default=None)
69
- logging.debug(f"raw snapd version: {version_str}")
70
- if not isinstance(version_str, str):
71
- return None
72
- version_str = sanitise_version_string(version_str)
73
-
74
- version = try_parse_semver(version_str)
75
- logging.debug(f"IntelliJ IDEA version (via snapd): {version}")
76
- return version
77
-
78
-
79
- def get_intellij_idea_version_tarball() -> Optional[VersionInfo]:
80
- idea_bin_path = get_stdout(["sh", "-c", "which idea.sh"])
81
- if idea_bin_path is None:
82
- return None
83
-
84
- product_info_path = os.path.join(os.path.dirname(idea_bin_path), "..", "product-info.json")
85
- return get_intellij_version_from_product_info(product_info_path)
86
-
87
-
88
- def get_intellij_idea_toolbox_version() -> Optional[VersionInfo]:
89
- idea_bin_path = get_stdout(["sh", "-c", "which idea"])
90
- if idea_bin_path is None:
91
- return None
92
-
93
- apps_dir = os.path.join(os.path.dirname(idea_bin_path), "..", "apps")
94
- toolbox_apps = os.listdir(apps_dir)
95
- logging.debug(f"Toolbox apps found: {toolbox_apps}", exc_info=True)
96
- intellij_installs = [app for app in toolbox_apps if "intellij-idea" in app]
97
- if len(intellij_installs) == 0:
98
- logging.debug("No IntelliJ IDEA installs found")
99
- return None
100
-
101
- product_info_path = os.path.join(apps_dir, intellij_installs[0], "product-info.json")
102
- return get_intellij_version_from_product_info(product_info_path)
103
-
104
-
105
- def get_intellij_version_from_product_info(product_info_path: str) -> Optional[VersionInfo]:
106
- try:
107
- with open(product_info_path, "rb") as product_info_file:
108
- product_info = json.load(product_info_file)
109
- except IOError:
110
- logging.debug("Failed to read IntelliJ IDEA product-info.json", exc_info=True)
111
- return None
112
- except JSONDecodeError:
113
- logging.debug("Failed to parse IntelliJ IDEA product-info.json", exc_info=True)
114
- return None
115
-
116
- version_str = product_info.get("version", None)
117
- version = try_parse_semver(version_str)
118
- logging.debug(f"IntelliJ IDEA version (via product-info.json): {version}")
119
- return version
120
-
121
-
122
- def get_intellij_idea_version() -> Optional[VersionInfo]:
123
- os = detect_os()
124
- if os == OS.OS_X:
125
- return get_intellij_idea_version_mac()
126
- elif os == OS.UBUNTU:
127
- return (
128
- get_intellij_idea_version_snap()
129
- or get_intellij_idea_version_tarball()
130
- or get_intellij_idea_toolbox_version()
131
- )
132
- else:
133
- return get_intellij_idea_version_tarball() or get_intellij_idea_toolbox_version()
134
-
135
-
136
- class IntelliJIdeaInstalled(Check):
137
- name = "intellij.installed"
138
-
139
- suggestions = {OS.GENERIC: "Install IntelliJ Ultimate: https://www.jetbrains.com/idea/download/"}
140
-
141
- def __init__(self, required_version: Optional[str] = None, recommended_version: Optional[str] = None):
142
- self.required_version = required_version
143
- self.recommended_version = recommended_version
144
-
145
- def check(self) -> CheckResult:
146
- intellij_version = get_intellij_idea_version()
147
- return self.validate_semver_expression(
148
- "IntelliJ IDEA", intellij_version, self.required_version, self.recommended_version
149
- )
150
-
151
-
152
- class IntelliJProjectImported(FilesExist):
153
- name = "intellij.projectImported"
154
- file_paths = [".idea/workspace.xml"]
155
- pass_fail_message = "Project <not/> imported into IntelliJ"
156
- depends_on = [IntelliJIdeaInstalled]
157
- suggestions = {
158
- OS.GENERIC: """
159
- From the IntelliJ start screen, click 'Open or Import' and choose the repository root directory
160
- """
161
- }
162
-
163
-
164
- class IntelliJNodePackageManagerConfigured(XmlFileXPathCheck):
165
- name = "intellij.nodePackageManagerConfigured"
166
- file_path = ".idea/workspace.xml"
167
- xpath_query = "./component[@name='PropertiesComponent']"
168
- depends_on = [IntelliJProjectImported]
169
-
170
- def __init__(self, package_manager_path: str):
171
- self.package_manager_path = package_manager_path
172
- self.pass_fail_message = f"IntelliJ package manager has <not/> been set to {package_manager_path}"
173
-
174
- self.suggestions = {
175
- OS.GENERIC: f"""
176
- Follow the steps to configure {self.package_manager_path} as your package manager:
177
- https://www.jetbrains.com/help/idea/installing-and-removing-external-software-using-node-package-manager.html#ws_npm_yarn_configure_package_manager
178
- """
179
- }
180
-
181
- def validate_query_result(self, result):
182
- key_json = None if result is None else json.loads(result.text)
183
- logging.debug(f"Raw properties json: {key_json}")
184
- current_package_manager = str(key_json["keyToString"]["nodejs_package_manager_path"])
185
- logging.debug(f"IntelliJ node package manager set to: {current_package_manager}")
186
- return current_package_manager.__contains__(self.package_manager_path)
187
-
188
-
189
- class IntelliJTypescriptCompilerPathConfigured(XmlFileXPathCheck):
190
- name = "intellij.typescriptCompilerPathConfigured"
191
- file_path = ".idea/compiler.xml"
192
- xpath_query = "./component[@name='TypeScriptCompiler']/option[@name='typeScriptServiceDirectory']"
193
- depends_on = [IntelliJProjectImported]
194
-
195
- def __init__(self, typescript_compiler_path: str):
196
- self.typescript_compiler_path = typescript_compiler_path
197
- resolved_path = typescript_compiler_path.replace("$PROJECT_DIR$", os.getcwd())
198
- self.pass_fail_message = f"IntelliJ typescript compiler path has <not/> been set to {resolved_path}"
199
-
200
- self.suggestions = {
201
- OS.GENERIC: f"""
202
- Follow the steps to set {resolved_path} as your typescript compiler path:
203
- https://www.jetbrains.com/help/idea/typescript-support.html#ws_ts_use_ts_service_checkbox
204
- """
205
- }
206
-
207
- def validate_query_result(self, result):
208
- if result is None:
209
- self.pass_fail_message = "IntelliJ typescript compiler path is <not/> set"
210
- return False
211
- current_typescript_compiler_path = result.get("value")
212
- logging.debug(f"IntelliJ typescript compiler set to: {current_typescript_compiler_path}")
213
- return current_typescript_compiler_path == self.typescript_compiler_path
214
-
215
-
216
- class IntelliJProjectSdkJavaVersion(XmlFileXPathCheck):
217
- name = "intellij.jdkVersionConfigured"
218
- file_path = ".idea/misc.xml"
219
- xpath_query = "./component[@name='ProjectRootManager']"
220
- depends_on = [IntelliJProjectImported]
221
-
222
- def __init__(self, jdk_version: int):
223
- self.jdk_version = jdk_version
224
-
225
- self.suggestions = {
226
- OS.GENERIC: f"""
227
- Follow the steps to configure JDK {jdk_version}:
228
- https://www.jetbrains.com/help/idea/sdk.html#change-project-sdk
229
- """
230
- }
231
-
232
- def validate_query_result(self, result: Optional[Element]):
233
- if result is None:
234
- self.pass_fail_message = "IntelliJ Project SDK is not set"
235
- return False
236
-
237
- try:
238
- jdk_type = result.attrib["project-jdk-type"]
239
- if jdk_type != "JavaSDK":
240
- self.pass_fail_message = f"IntelliJ Project SDK is not a Java JDK: {jdk_type}"
241
- return False
242
- except KeyError:
243
- self.pass_fail_message = "IntelliJ Project SDK is not a Java JDK"
244
- return False
245
-
246
- language_level = result.attrib["languageLevel"]
247
- self.pass_fail_message = f"IntelliJ Project SDK is <not/> set to Java {self.jdk_version}: {language_level}"
248
- return language_level == f"JDK_{self.jdk_version}"
daktari/checks/java.py DELETED
@@ -1,104 +0,0 @@
1
- import logging
2
- import re
3
- from typing import Optional
4
-
5
- from semver import VersionInfo
6
-
7
- from daktari.check import Check, CheckResult
8
- from daktari.command_utils import get_stderr, run_command
9
- from daktari.os import OS
10
-
11
- java_version_pattern = re.compile('^.*version "(.*?)".*$', re.MULTILINE)
12
- javac_version_pattern = re.compile("^javac (.*)$", re.MULTILINE)
13
-
14
- one_dot_pattern = re.compile("1\\.([0-9]+)")
15
- other_pattern = re.compile("([0-9]+)")
16
-
17
-
18
- def get_java_version() -> Optional[VersionInfo]:
19
- version_output = get_stderr("java -version")
20
- return parse_java_version_output(version_output)
21
-
22
-
23
- def get_jdk_version() -> Optional[VersionInfo]:
24
- try:
25
- version_output = run_command("javac -version")
26
- except Exception:
27
- return None
28
-
29
- return parse_javac_version_output(version_output.stdout + version_output.stderr)
30
-
31
-
32
- def parse_java_version_output(version_output: Optional[str]) -> Optional[VersionInfo]:
33
- if version_output:
34
- match = java_version_pattern.search(version_output)
35
- if match:
36
- version_string = match.group(1)
37
- logging.debug(f"Java version string: {version_string}")
38
- return parse_java_version_string(version_string)
39
- return None
40
-
41
-
42
- def parse_javac_version_output(version_output: Optional[str]) -> Optional[VersionInfo]:
43
- if version_output:
44
- match = javac_version_pattern.search(version_output)
45
- if match:
46
- version_string = match.group(1)
47
- logging.debug(f"JDK version string: {version_string}")
48
- return parse_java_version_string(version_string)
49
- return None
50
-
51
-
52
- def parse_java_version_string(version_string: str) -> Optional[VersionInfo]:
53
- try:
54
- return VersionInfo.parse(version_string)
55
- except ValueError:
56
- return parse_alternative_java_version_numbers(version_string)
57
-
58
-
59
- def parse_alternative_java_version_numbers(version_string: str) -> Optional[VersionInfo]:
60
- one_dot_match = one_dot_pattern.search(version_string)
61
- if one_dot_match:
62
- return VersionInfo(int(one_dot_match.group(1)))
63
- other_pattern_match = other_pattern.search(version_string)
64
- if other_pattern_match:
65
- return VersionInfo(int(other_pattern_match.group(1)))
66
- return None
67
-
68
-
69
- class JavaVersion(Check):
70
- name = "java.version"
71
-
72
- def __init__(
73
- self,
74
- required_version: Optional[str] = None,
75
- recommended_version: Optional[str] = None,
76
- java_instructions: Optional[str] = None,
77
- ):
78
- self.required_version = required_version
79
- self.recommended_version = recommended_version
80
-
81
- java_instructions = f"\n\n{java_instructions}" if java_instructions else ""
82
- self.suggestions = {OS.GENERIC: f"""Install Java{java_instructions}"""}
83
-
84
- def check(self) -> CheckResult:
85
- java_version = get_java_version()
86
- logging.info(f"Java version: {java_version}")
87
- return self.validate_semver_expression("Java", java_version, self.required_version, self.recommended_version)
88
-
89
-
90
- class JdkVersion(Check):
91
- name = "jdk.version"
92
-
93
- def __init__(self, required_version: str, recommended_version: Optional[str] = None):
94
- self.required_version = required_version
95
- self.recommended_version = recommended_version
96
-
97
- suggestions = {
98
- OS.GENERIC: "Install Java JDK",
99
- }
100
-
101
- def check(self) -> CheckResult:
102
- jdk_version = get_jdk_version()
103
- logging.info(f"JDK version: {jdk_version}")
104
- return self.validate_semver_expression("JDK", jdk_version, self.required_version, self.recommended_version)