daktari 0.0.237__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/__init__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.0.237"
1
+ __version__ = "0.0.254"
@@ -1,40 +1,41 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: daktari
3
- Version: 0.0.237
3
+ Version: 0.0.254
4
4
  Summary: Assist in setting up and maintaining developer environments
5
- Home-page: https://github.com/sonocent/daktari
6
- Author: Matt Russell
7
- Author-email: matthew.russell@sonocent.com
8
- License: MIT
9
- Classifier: License :: OSI Approved :: MIT License
10
- Classifier: Programming Language :: Python
5
+ Author-email: Matt Russell <matthew.russell@sonocent.com>
6
+ License: Copyright 2021 Sonocent Ltd
7
+
8
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11
+
12
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13
+ Project-URL: Homepage, https://github.com/sonocent/daktari
11
14
  Requires-Python: >=3.9
12
15
  Description-Content-Type: text/markdown
13
16
  License-File: LICENSE.txt
14
- Requires-Dist: PyYAML ==5.3.1
15
- Requires-Dist: ansicolors ==1.1.8
16
- Requires-Dist: distro ==1.9.0
17
- Requires-Dist: dpath ==2.2.0
18
- Requires-Dist: importlib-resources ==6.5.2
19
- Requires-Dist: packaging ==20.9
20
- Requires-Dist: pyOpenSSL ==25.0.0
21
- Requires-Dist: pyclip ==0.7.0
22
- Requires-Dist: pyfiglet ==0.8.post1
23
- Requires-Dist: python-hosts ==1.0.7
24
- Requires-Dist: requests-unixsocket ==0.3.0
25
- Requires-Dist: requests ==2.32.3
26
- Requires-Dist: responses ==0.25.6
27
- Requires-Dist: semver ==3.0.2
28
- Requires-Dist: setuptools ==70.3.0
29
- Requires-Dist: tabulate ==0.9.0
30
- Requires-Dist: types-PyYAML ==6.0.12.20241230
31
- Requires-Dist: types-pyOpenSSL ==24.1.0.20240722
32
- Requires-Dist: types-tabulate ==0.9.0.20241207
33
- Requires-Dist: urllib3 <1.27
34
- Requires-Dist: dataclasses ==0.8 ; python_version < "3.7"
35
- Requires-Dist: types-dataclasses ==0.1.5 ; python_version < "3.7"
36
- Requires-Dist: pyobjc-core ==11.0 ; sys_platform == "darwin"
37
- Requires-Dist: pyobjc-framework-Cocoa ==11.0 ; sys_platform == "darwin"
17
+ Requires-Dist: ansicolors==1.1.8
18
+ Requires-Dist: distro==1.9.0
19
+ Requires-Dist: pyfiglet==1.0.2
20
+ Requires-Dist: importlib_resources==6.5.2
21
+ Requires-Dist: packaging==24.2
22
+ Requires-Dist: setuptools==76.0.0
23
+ Requires-Dist: requests==2.32.3
24
+ Requires-Dist: responses==0.25.6
25
+ Requires-Dist: semver==3.0.4
26
+ Requires-Dist: python-hosts==1.0.7
27
+ Requires-Dist: tabulate==0.9.0
28
+ Requires-Dist: types-tabulate==0.9.0.20241207
29
+ Requires-Dist: PyYAML==6.0.2
30
+ Requires-Dist: types-PyYAML==6.0.12.20241230
31
+ Requires-Dist: pyobjc-core==11.0; sys_platform == "darwin"
32
+ Requires-Dist: pyobjc-framework-Cocoa==11.0; sys_platform == "darwin"
33
+ Requires-Dist: requests-unixsocket==0.4.1
34
+ Requires-Dist: dpath==2.2.0
35
+ Requires-Dist: pyOpenSSL==25.0.0
36
+ Requires-Dist: types-pyOpenSSL==24.1.0.20240722
37
+ Requires-Dist: pyclip==0.7.0
38
+ Requires-Dist: urllib3==2.3.0
38
39
 
39
40
  **Daktari** is a tool to help the initial setup and ongoing maintenance of developer environments. It runs a series of checks (for example, that required software is installed) and provides suggestions on how to fix the issue if the check fails.
40
41
 
@@ -45,7 +46,7 @@ In the root of the project repository, create a `.daktari.py` configuration file
45
46
  ```python
46
47
  from daktari.checks.git import *
47
48
 
48
- version = "0.0.237"
49
+ version = "0.0.254"
49
50
  title = "My Project"
50
51
 
51
52
  checks = [
@@ -107,7 +108,7 @@ In case of a need to manually release, the steps are:
107
108
 
108
109
  ```
109
110
  bumpversion --verbose patch
110
- python setup.py sdist bdist_wheel
111
+ python -m build
111
112
  twine check dist/*
112
113
  twine upload dist/*
113
114
  ```
@@ -0,0 +1,35 @@
1
+ daktari/__init__.py,sha256=a871puGudVEgAlfgYgd9bLziU_VQH-T2wDmeGFBU0JM,24
2
+ daktari/__main__.py,sha256=iYwgtZZE2HD9Eh9Io6OliGQwCNZJSde_66jI6kF8xJU,1463
3
+ daktari/asdf.py,sha256=fALVL6UTz1AYxuabw9MZeAES7J_CvImutUDD1Y2yWwM,509
4
+ daktari/check.py,sha256=WzIiCrrdH7gCbElNwYbYkjhpmaOs_nUWfvkTBkfZlgs,4133
5
+ daktari/check_runner.py,sha256=PwJkERyEYTKdHKtZEjN-kSt6nQxjDKaLadCRmUagW4I,2634
6
+ daktari/check_sorter.py,sha256=r6tgPDEnSjq_GVFJFEIpnBvN2azmfZ1oYY4YgbGQ028,1005
7
+ daktari/check_utils.py,sha256=rrmYWdekusXT4A2Tecbry_eV9DNt7bN9L5R0IJSPm5k,1027
8
+ daktari/collection_utils.py,sha256=JOCcaSkXFPbj2ROszTS-FGv1s35HgHv0MCWgaHio4XE,165
9
+ daktari/command_utils.py,sha256=3s3A3urin40eK40q9bzVnWGsSuU27FZbRkoDotlVKFk,2355
10
+ daktari/config.py,sha256=75l_jhq7tcCIdl78RMcUlUu1fiG8cqKtwC3yV_H5FVE,6719
11
+ daktari/file_utils.py,sha256=R2WA7XCtSx68cjdlJtBd6iIr1MEmR3fQDVTgSNvoBx4,1251
12
+ daktari/options.py,sha256=DTTCqn3BdfncWkkAFyag239fxgyxIo3IkM0R9bZhXgQ,1440
13
+ daktari/os.py,sha256=usoya1LQThE68aXUfbgq67hJlHmtbEZtXpi7oRfnXXY,767
14
+ daktari/resource_utils.py,sha256=LibGDZYOni6iVQq6OjF0cvFZrP5QmAmHoNKe4G_3BRc,331
15
+ daktari/result_printer.py,sha256=rTKxMFVI8Bi9FKIQ8YPFNPkZ08vtBugxv3a8_iJEpag,3492
16
+ daktari/test_asdf.py,sha256=xSTdf8GD2V-6byBfiaAa5qy201rZxgW8pMVyph-BIVY,946
17
+ daktari/test_check.py,sha256=8DC_MDABa0swRbAww98NB1vXVt5cykoGZyNS4r6IFa4,3866
18
+ daktari/test_check_factory.py,sha256=rGxX-rHHedotCrzi4xLrEgDl9XDdq3yCOSo_qxLEiOY,884
19
+ daktari/test_check_runner.py,sha256=dGMt1ksVGRHxuyoaMyfhvkXel6ZCakCCVJHF-QKQBfY,4071
20
+ daktari/test_check_sorter.py,sha256=6lroiF0fofh0UlLnuoLa9l7Opa1aT2WZEd7XATCHYKE,2631
21
+ daktari/test_check_utils.py,sha256=WLNDzmVQQSABTnS3zAFdWaZ0Z0nKAdlTnd66aiAtrX8,2268
22
+ daktari/test_collection_utils.py,sha256=AtPJnvFLwfiWHKdmrzwcku92vwCVDTvdP2XPBLkQAfE,347
23
+ daktari/test_config.py,sha256=SYLJa4emkW1C2ThLUWd1l_mq8VRZ8semmRnc5TjImCg,7538
24
+ daktari/test_result_printer.py,sha256=1BpR4eApbajaFwChcoUIOM6FdKM53kGzuWVr1w18pSk,1003
25
+ daktari/test_version_utils.py,sha256=cqudpmYKvqNkgBB9L5qLaxpVM7nD-XYuBMQXY3VohmA,1193
26
+ daktari/version_utils.py,sha256=gAE-hfVbdG4fyvT2qBQFYzzz2CFMTA2p_6AUYsgg8a4,1086
27
+ daktari/resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
+ daktari/resources/daktari-local-template.yaml,sha256=ik7KzMcG1r90nxDOk7t5G7P-BSxQIl2PocGUVe14c44,503
29
+ daktari/resources/mock_cert.pem,sha256=AIc9dZOVIuxm7KFLunP5WSA1-LDWLOwpfu48B9xQ_Wg,82
30
+ daktari-0.0.254.dist-info/LICENSE.txt,sha256=sMo18UdnQ7rY1SYg9gmop08ubzEQOGO1URYXu1Hxdx0,1051
31
+ daktari-0.0.254.dist-info/METADATA,sha256=aPU9jBKDKk90KvtHyEnG-tpA4BPgl3960ZXnmwNYygQ,4612
32
+ daktari-0.0.254.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
33
+ daktari-0.0.254.dist-info/entry_points.txt,sha256=mfQXkwKyloAzf7sv78icBo1PtRwf9hCP_816F6REf-I,50
34
+ daktari-0.0.254.dist-info/top_level.txt,sha256=LW6kawKAAyxUbGqpAbdedKRUyVy2DBzEZOalp0qDdF8,8
35
+ daktari-0.0.254.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.42.0)
2
+ Generator: setuptools (76.0.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
File without changes
daktari/checks/android.py DELETED
@@ -1,26 +0,0 @@
1
- from daktari.check import Check, CheckResult
2
- from daktari.os import OS, get_env_var_value
3
-
4
-
5
- class AndroidNdkHomeSet(Check):
6
- name = "android.ndkHomeSet"
7
-
8
- def __init__(self, expected_version):
9
- self.variable_name = "ANDROID_NDK_HOME"
10
- self.expected_version = expected_version
11
- self.suggestions = {
12
- OS.GENERIC: f"""
13
- Export {self.variable_name} in your shell config.
14
- The expected value is ANDROID_SDK_HOME/ndk/{self.expected_version}.
15
- If you manage your android sdk using Android Studio, you can find your ANDROID_SDK_HOME by going to
16
- Tools > SDK Manager and copying the Android SDK location.
17
- You may need to check under SDK Tools that you have the NDK installed.
18
- """
19
- }
20
-
21
- def check(self) -> CheckResult:
22
- expected_substring = f"ndk/{self.expected_version}"
23
- return self.verify(
24
- expected_substring in get_env_var_value(self.variable_name),
25
- f"{self.variable_name} is <not/> set with expected version {self.expected_version}",
26
- )
daktari/checks/aws.py DELETED
@@ -1,34 +0,0 @@
1
- from daktari.check import Check, CheckResult
2
- from daktari.command_utils import can_run_command, get_stdout
3
- from daktari.os import OS
4
-
5
-
6
- class AWSCLIInstalled(Check):
7
- name = "aws.cliInstalled"
8
-
9
- suggestions = {
10
- OS.OS_X: """<cmd>curl "https://awscli.amazonaws.com/AWSCLIV2.pkg" -o "AWSCLIV2.pkg" && \
11
- sudo installer -pkg AWSCLIV2.pkg -target /</cmd>""",
12
- OS.UBUNTU: """"<cmd>curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" && \
13
- unzip awscliv2.zip && \
14
- sudo ./aws/install</cmd>""",
15
- }
16
-
17
- def check(self) -> CheckResult:
18
- return self.verify(can_run_command("aws --version"), "AWS CLI is <not/> installed and on $PATH")
19
-
20
-
21
- class AWSProfileExists(Check):
22
- depends_on = [AWSCLIInstalled]
23
-
24
- def __init__(self, profile_name: str, suggestions: dict[str, str]):
25
- self.profile_name = profile_name
26
- self.name = f"aws.profileExists.{profile_name}"
27
- self.suggestions = suggestions
28
-
29
- def check(self) -> CheckResult:
30
- output = get_stdout("aws configure list-profiles")
31
- passed = bool(output and self.profile_name in output)
32
- if not passed:
33
- return self.failed(f"{self.profile_name} is not configured for the current user")
34
- return self.passed(f"{self.profile_name} is configured for the current user")
daktari/checks/certs.py DELETED
@@ -1,34 +0,0 @@
1
- import logging
2
- import os
3
- from datetime import datetime
4
- from OpenSSL import crypto
5
-
6
- from daktari.check import Check, CheckResult
7
- from daktari.os import OS
8
-
9
-
10
- class CertificateIsNotExpired(Check):
11
- name = "certificate.isNotExpired"
12
-
13
- def __init__(self, certificate_path: str):
14
- self.certificate_path = certificate_path
15
- self.suggestions = {
16
- OS.GENERIC: f"Regenerate the certificate at {certificate_path}",
17
- }
18
-
19
- def check(self) -> CheckResult:
20
- with open(self.certificate_path, "rb") as f:
21
- cert = crypto.load_certificate(crypto.FILETYPE_PEM, f.read())
22
- logging.debug(f"Raw expiry: {cert.get_notAfter()!r}")
23
-
24
- expiry_bytes = cert.get_notAfter()
25
- if expiry_bytes is None:
26
- return self.passed_with_warning(
27
- f"Unable to determine expiry date of {os.path.basename(self.certificate_path)}"
28
- )
29
-
30
- expiry = datetime.strptime(expiry_bytes.decode(), "%Y%m%d%H%M%SZ")
31
- if expiry > datetime.now():
32
- return self.passed(f"{os.path.basename(self.certificate_path)} is not expired")
33
- else:
34
- return self.failed(f"{os.path.basename(self.certificate_path)} expired on {expiry}")
daktari/checks/conan.py DELETED
@@ -1,96 +0,0 @@
1
- import json
2
- import logging
3
- from typing import Optional
4
-
5
- from daktari.check import Check, CheckResult
6
- from daktari.command_utils import get_stdout
7
- from daktari.os import OS
8
-
9
-
10
- class ConanInstalled(Check):
11
- name = "conan.installed"
12
-
13
- def __init__(self, required_version: Optional[str] = None, recommended_version: Optional[str] = None):
14
- self.required_version = required_version
15
- self.recommended_version = recommended_version
16
- self.suggestions = {OS.GENERIC: "Install conan: <cmd>pip install conan</cmd>"}
17
-
18
- def check(self) -> CheckResult:
19
- return self.verify_install("conan")
20
-
21
-
22
- class ConanProfileDetected(Check):
23
- name = "conan.profileDetected"
24
-
25
- def __init__(self, expected_string: str):
26
- self.suggestions = {OS.GENERIC: "<cmd>conan profile detect</cmd>"}
27
- self.expected_string = expected_string
28
- self.depends_on = [ConanInstalled]
29
-
30
- def check(self) -> CheckResult:
31
- output = get_stdout("conan profile list")
32
- expected_profile_detected = output is not None and self.expected_string in output
33
- return self.verify(expected_profile_detected, f"conan profile {self.expected_string} <not/> detected")
34
-
35
-
36
- class ConanRemoteDetected(Check):
37
- name = "conan.remoteDetected"
38
-
39
- def __init__(self, remote_name: str, remote_url: str):
40
- self.suggestions = {OS.GENERIC: f"<cmd>conan remote add {remote_name} {remote_url}</cmd>"}
41
- self.remote_name = remote_name
42
- self.remote_url = remote_url
43
- self.depends_on = [ConanInstalled]
44
-
45
- def check(self) -> CheckResult:
46
- output = get_stdout("conan remote list -f json")
47
- if output is None:
48
- return self.failed("No conan remotes configured for the current user.")
49
- remote_json = json.loads(output)
50
- remote = next(filter(lambda remote_details: remote_details.get("name") == self.remote_name, remote_json), None)
51
- if remote is None:
52
- return self.failed(f"{self.remote_name} conan remote is not configured for the current user.")
53
-
54
- configured_url = remote["url"].strip("/")
55
- logging.debug(f"{self.remote_name} conan remote is configured with URL {configured_url}.")
56
-
57
- if configured_url != self.remote_url:
58
- self.suggestions = {
59
- OS.GENERIC: f"<cmd>conan remote update --url {self.remote_url} {self.remote_name}</cmd>"
60
- }
61
- return self.failed(
62
- f"{self.remote_name} conan remote is configured with URL {configured_url}, expected {self.remote_url}"
63
- )
64
-
65
- if not remote["enabled"]:
66
- self.suggestions = {OS.GENERIC: f"<cmd>conan remote enable {self.remote_name}</cmd>"}
67
- return self.failed(f"{self.remote_name} conan remote is not enabled.")
68
-
69
- return self.passed(f"{self.remote_name} conan remote is configured for the current user.")
70
-
71
-
72
- class ConanRemoteAuthenticated(Check):
73
- name = "conan.remoteAuthenticated"
74
-
75
- def __init__(self, remote_name: str, authentication_command: Optional[str] = None):
76
- self.suggestions = (
77
- {OS.GENERIC: authentication_command}
78
- if authentication_command
79
- else {OS.GENERIC: f"<cmd>conan remote login {remote_name}</cmd>"}
80
- )
81
- self.remote_name = remote_name
82
- self.depends_on = [ConanRemoteDetected]
83
-
84
- def check(self) -> CheckResult:
85
- output = get_stdout("conan remote list-users -f json")
86
- if output is None:
87
- return self.failed("No conan remotes configured for the current user.")
88
- remote_json = json.loads(output)
89
- remote = next(filter(lambda remote_details: remote_details.get("name") == self.remote_name, remote_json), None)
90
- if remote is None:
91
- return self.failed(f"{self.remote_name} conan remote is not configured for the current user.")
92
-
93
- if not remote["authenticated"]:
94
- return self.failed(f"{self.remote_name} conan remote is not authenticated.")
95
-
96
- return self.passed(f"{self.remote_name} conan remote is authenticated for the current user.")
daktari/checks/direnv.py DELETED
@@ -1,59 +0,0 @@
1
- import re
2
-
3
- from daktari.command_utils import get_stdout
4
-
5
- from daktari.os import OS
6
- from daktari.check import Check, CheckResult
7
- from daktari.version_utils import get_simple_cli_version
8
- from daktari.file_utils import file_contains_text
9
- from typing import Optional
10
- from os import getcwd
11
-
12
-
13
- class DirenvInstalled(Check):
14
- name = "direnv.installed"
15
-
16
- def __init__(self, required_version: Optional[str] = None, recommended_version: Optional[str] = None):
17
- self.required_version = required_version
18
- self.recommended_version = recommended_version
19
- self.suggestions = {
20
- OS.GENERIC: "Install direnv: https://direnv.net/#getting-started",
21
- OS.OS_X: "Install direnv using brew: <cmd>brew install direnv</cmd>",
22
- OS.UBUNTU: "Install direnv using apt-get: <cmd>sudo apt-get install direnv</cmd>",
23
- }
24
-
25
- def check(self) -> CheckResult:
26
- installed_version = get_simple_cli_version("direnv")
27
- return self.validate_semver_expression(
28
- "direnv", installed_version, self.required_version, self.recommended_version
29
- )
30
-
31
-
32
- class EnvrcContainsText(Check):
33
- name = "direnv.envrc.containsText"
34
-
35
- def __init__(self, expected_string: str, suggestion: str):
36
- self.file_path = f"{getcwd()}/.envrc"
37
- self.expected_string = expected_string
38
- self.pass_fail_message = f"{self.file_path} does <not/> contain '{expected_string}'"
39
- self.suggestions = {OS.GENERIC: suggestion}
40
-
41
- def check(self) -> CheckResult:
42
- return self.verify(file_contains_text(self.file_path, self.expected_string), self.pass_fail_message)
43
-
44
-
45
- class DirenvAllowed(Check):
46
- name = "direnv.allowed"
47
- depends_on = [DirenvInstalled, EnvrcContainsText]
48
-
49
- def __init__(self):
50
- self.suggestions = {OS.GENERIC: "<cmd>direnv allow .</cmd>"}
51
-
52
- def check(self) -> CheckResult:
53
- direnv_status = get_stdout("direnv status")
54
- if direnv_status is None:
55
- return self.failed("direnv status returned no output")
56
- cwd = getcwd()
57
- query = f"Found RC path {cwd}/.envrc(\n.*)*Found RC allowed (true|0)"
58
- direnv_allowed = re.search(query, direnv_status) is not None
59
- return self.verify(direnv_allowed, f"{cwd} is <not/> allowed to use direnv")
daktari/checks/docker.py DELETED
@@ -1,50 +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_stdout
9
- from daktari.os import OS
10
- from daktari.version_utils import try_parse_semver
11
-
12
-
13
- class DockerInstalled(Check):
14
- name = "docker.installed"
15
-
16
- suggestions = {
17
- OS.GENERIC: "Install docker: https://docs.docker.com/get-docker/",
18
- OS.OS_X: "Install docker: https://docs.docker.com/docker-for-mac/install/",
19
- }
20
-
21
- def __init__(self, required_version: Optional[str] = None):
22
- self.required_version = required_version
23
-
24
- def check(self) -> CheckResult:
25
- installed_version = get_docker_version()
26
- return self.validate_semver_expression("Docker", installed_version, self.required_version)
27
-
28
-
29
- major_version_pattern = re.compile("Docker version ([0-9.]+)")
30
-
31
-
32
- def get_docker_version() -> Optional[VersionInfo]:
33
- raw_version = get_stdout("docker --version")
34
- if raw_version:
35
- match = major_version_pattern.search(raw_version)
36
- if match:
37
- version_string = match.group(1)
38
- version = try_parse_semver(version_string)
39
- logging.debug(f"Docker version - raw: {version_string}, parsed: {version}")
40
- return version
41
- return None
42
-
43
-
44
- class DockerComposeInstalled(Check):
45
- name = "docker-compose.installed"
46
-
47
- suggestions = {OS.GENERIC: "Install docker-compose: https://docs.docker.com/compose/install/"}
48
-
49
- def check(self) -> CheckResult:
50
- return self.verify_install("docker-compose")
daktari/checks/files.py DELETED
@@ -1,72 +0,0 @@
1
- from os.path import expanduser
2
- from typing import List
3
-
4
- from daktari.check import Check, CheckResult
5
- from daktari.file_utils import dir_exists, file_exists, get_file_owner
6
- from daktari.os import OS
7
-
8
-
9
- class FilesExist(Check):
10
- name = "files.exist"
11
- file_paths: List[str] = []
12
- pass_fail_message = ""
13
-
14
- def check(self) -> CheckResult:
15
- files_exist = all([file_exists(expanduser(file_path)) for file_path in self.file_paths])
16
- return self.verify(files_exist, self.pass_fail_message)
17
-
18
-
19
- class FileExists(FilesExist):
20
- name = "file.exists"
21
-
22
- def __init__(self, file_path: str, suggestion: str):
23
- self.file_paths = [file_path]
24
- self.pass_fail_message = f"{file_path} is <not/> present"
25
- self.suggestions = {OS.GENERIC: suggestion}
26
-
27
-
28
- class DirsExist(Check):
29
- name = "directories.exist"
30
- dir_paths: List[str] = []
31
- pass_fail_message = ""
32
-
33
- def check(self) -> CheckResult:
34
- dirs_exist = all([dir_exists(expanduser(dir_path)) for dir_path in self.dir_paths])
35
- return self.verify(dirs_exist, self.pass_fail_message)
36
-
37
-
38
- class DirExists(DirsExist):
39
- name = "dir.exists"
40
-
41
- def __init__(self, dir_path: str, suggestion: str):
42
- self.dir_paths = [dir_path]
43
- self.pass_fail_message = f"{dir_path} is <not/> present"
44
- self.suggestions = {OS.GENERIC: suggestion}
45
-
46
-
47
- class FilesOwnedByUser(Check):
48
- name = "files.ownedByUser"
49
-
50
- def __init__(
51
- self,
52
- file_paths: List[str],
53
- expected_owner: str = "root",
54
- pass_fail_message: str = "",
55
- follow_symlinks: bool = False,
56
- ):
57
- self.file_paths = file_paths
58
- self.expected_owner = expected_owner
59
- file_paths_str = ", ".join(file_paths)
60
- self.pass_fail_message = pass_fail_message or f"{file_paths_str} are <not/> owned by {expected_owner}"
61
- self.follow_symlinks = follow_symlinks
62
-
63
- def check(self) -> CheckResult:
64
- for file_path in self.file_paths:
65
- expanded_file_path = expanduser(file_path)
66
- if file_exists(expanded_file_path):
67
- if get_file_owner(expanded_file_path, self.follow_symlinks) != self.expected_owner:
68
- return self.verify(False, self.pass_fail_message)
69
- else:
70
- return self.failed(f"{expanded_file_path} is not present")
71
-
72
- return self.verify(True, self.pass_fail_message)
daktari/checks/flutter.py DELETED
@@ -1,46 +0,0 @@
1
- import logging
2
- import re
3
- from semver import VersionInfo
4
- from typing import Optional
5
-
6
- from daktari.check import Check, CheckResult
7
- from daktari.command_utils import get_stdout
8
- from daktari.os import OS
9
- from daktari.version_utils import try_parse_semver
10
-
11
-
12
- flutter_version_pattern = re.compile(r"Flutter\s+([\d\.]+)")
13
-
14
-
15
- def parse_flutter_version_output(version_output: Optional[str]) -> Optional[VersionInfo]:
16
- if version_output:
17
- match = flutter_version_pattern.search(version_output)
18
- if match:
19
- version_string = match.group(1)
20
- logging.debug(f"Flutter version string: {version_string}")
21
- return try_parse_semver(version_string)
22
- return None
23
-
24
-
25
- def get_flutter_version() -> Optional[VersionInfo]:
26
- version_output = get_stdout("flutter --version")
27
- return parse_flutter_version_output(version_output)
28
-
29
-
30
- class FlutterInstalled(Check):
31
- name = "flutter.installed"
32
-
33
- suggestions = {
34
- OS.GENERIC: "Install Flutter: https://flutter.dev/docs/get-started/install",
35
- }
36
-
37
- def __init__(self, required_version: Optional[str] = None, recommended_version: Optional[str] = None):
38
- self.required_version = required_version
39
- self.recommended_version = recommended_version
40
-
41
- def check(self) -> CheckResult:
42
- flutter_version = get_flutter_version()
43
- logging.info(f"Flutter version: {flutter_version}")
44
- return self.validate_semver_expression(
45
- "Flutter", flutter_version, self.required_version, self.recommended_version
46
- )