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 +1 -1
- {daktari-0.0.237.dist-info → daktari-0.0.254.dist-info}/METADATA +35 -34
- daktari-0.0.254.dist-info/RECORD +35 -0
- {daktari-0.0.237.dist-info → daktari-0.0.254.dist-info}/WHEEL +1 -1
- daktari/checks/__init__.py +0 -0
- daktari/checks/android.py +0 -26
- daktari/checks/aws.py +0 -34
- daktari/checks/certs.py +0 -34
- daktari/checks/conan.py +0 -96
- daktari/checks/direnv.py +0 -59
- daktari/checks/docker.py +0 -50
- daktari/checks/files.py +0 -72
- daktari/checks/flutter.py +0 -46
- daktari/checks/git.py +0 -198
- daktari/checks/google.py +0 -113
- daktari/checks/intellij_idea.py +0 -248
- daktari/checks/java.py +0 -104
- daktari/checks/kubernetes.py +0 -154
- daktari/checks/misc.py +0 -302
- daktari/checks/nodejs.py +0 -92
- daktari/checks/onepassword.py +0 -105
- daktari/checks/python.py +0 -16
- daktari/checks/ssh.py +0 -33
- daktari/checks/terraform.py +0 -70
- daktari/checks/test_certs.py +0 -32
- daktari/checks/test_intellij_idea.py +0 -66
- daktari/checks/test_java.py +0 -88
- daktari/checks/test_misc.py +0 -18
- daktari/checks/test_onepassword.py +0 -31
- daktari/checks/test_ssh.py +0 -22
- daktari/checks/test_yarn.py +0 -86
- daktari/checks/xml.py +0 -33
- daktari/checks/yarn.py +0 -156
- daktari-0.0.237.dist-info/RECORD +0 -64
- {daktari-0.0.237.dist-info → daktari-0.0.254.dist-info}/LICENSE.txt +0 -0
- {daktari-0.0.237.dist-info → daktari-0.0.254.dist-info}/entry_points.txt +0 -0
- {daktari-0.0.237.dist-info → daktari-0.0.254.dist-info}/top_level.txt +0 -0
daktari/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.0.
|
|
1
|
+
__version__ = "0.0.254"
|
|
@@ -1,40 +1,41 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: daktari
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.254
|
|
4
4
|
Summary: Assist in setting up and maintaining developer environments
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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:
|
|
15
|
-
Requires-Dist:
|
|
16
|
-
Requires-Dist:
|
|
17
|
-
Requires-Dist:
|
|
18
|
-
Requires-Dist:
|
|
19
|
-
Requires-Dist:
|
|
20
|
-
Requires-Dist:
|
|
21
|
-
Requires-Dist:
|
|
22
|
-
Requires-Dist:
|
|
23
|
-
Requires-Dist: python-hosts
|
|
24
|
-
Requires-Dist:
|
|
25
|
-
Requires-Dist:
|
|
26
|
-
Requires-Dist:
|
|
27
|
-
Requires-Dist:
|
|
28
|
-
Requires-Dist:
|
|
29
|
-
Requires-Dist:
|
|
30
|
-
Requires-Dist:
|
|
31
|
-
Requires-Dist:
|
|
32
|
-
Requires-Dist:
|
|
33
|
-
Requires-Dist:
|
|
34
|
-
Requires-Dist:
|
|
35
|
-
Requires-Dist:
|
|
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.
|
|
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
|
|
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,,
|
daktari/checks/__init__.py
DELETED
|
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
|
-
)
|