Skip to content

Commit be6aba4

Browse files
authored
fix(consume): fixes issue where nethtest would not be recognized as valid t8n on certain systems (#1973)
* fixes issue where nethtest would not be recognized/found on certain systems depending on how it was compiled
1 parent 47ae439 commit be6aba4

File tree

2 files changed

+65
-16
lines changed

2 files changed

+65
-16
lines changed

src/ethereum_clis/clis/nethermind.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ class Nethtest(EthereumCLI):
2222
"""Nethermind `nethtest` binary base class."""
2323

2424
default_binary = Path("nethtest")
25-
detect_binary_pattern = re.compile(r"^\d+\.\d+\.\d+-[a-zA-Z0-9]+(\+[a-f0-9]{40})?$")
25+
# new pattern allows e.g. '1.2.3', in the past that was denied
26+
detect_binary_pattern = re.compile(r"^\d+\.\d+\.\d+(-[a-zA-Z0-9]+)?(\+[a-f0-9]{40})?$")
2627
version_flag: str = "--version"
2728
cached_version: Optional[str] = None
2829

src/ethereum_clis/ethereum_cli.py

Lines changed: 63 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
from re import Pattern
99
from typing import Any, List, Optional, Type
1010

11+
from pytest_plugins.logging import get_logger
12+
13+
logger = get_logger(__name__)
14+
1115

1216
class UnknownCLIError(Exception):
1317
"""Exception raised if an unknown CLI is encountered."""
@@ -78,46 +82,90 @@ def from_binary_path(cls, *, binary_path: Optional[Path], **kwargs) -> Any:
7882
"""
7983
assert cls.default_tool is not None, "default CLI implementation was never set"
8084

85+
# ensure provided t8n binary can be found and used
8186
if binary_path is None:
87+
logger.debug("Binary path of provided t8n is None!")
8288
return cls.default_tool(binary=binary_path, **kwargs)
8389

84-
resolved_path = Path(os.path.expanduser(binary_path)).resolve()
90+
expanded_path = Path(os.path.expanduser(binary_path))
91+
logger.debug(f"Expanded path of provided t8n: {expanded_path}")
92+
93+
resolved_path = expanded_path.resolve()
94+
logger.debug(f"Resolved path of provided t8n: {resolved_path}")
95+
8596
if resolved_path.exists():
86-
binary_path = resolved_path
87-
binary = shutil.which(binary_path) # type: ignore
97+
logger.debug("Resolved path exists")
98+
binary = Path(resolved_path)
99+
else:
100+
logger.debug(
101+
f"Resolved path does not exist: {resolved_path}\nTrying to find it via `which`"
102+
)
88103

89-
if not binary:
90-
raise CLINotFoundInPathError(binary=binary)
104+
# it might be that the provided binary exists in path
105+
filename = os.path.basename(resolved_path)
106+
binary = shutil.which(filename) # type: ignore
107+
logger.debug(f"Output of 'which {binary_path}': {binary}")
91108

92-
binary = Path(binary) # type: ignore[assignment]
109+
if binary is None:
110+
logger.error(f"Resolved t8n binary path does not exist: {resolved_path}")
111+
raise CLINotFoundInPathError(binary=resolved_path)
112+
113+
assert binary is not None
114+
logger.debug(f"Successfully located the path of the t8n binary: {binary}")
115+
binary = Path(binary)
93116

94117
# Group the tools by version flag, so we only have to call the tool once for all the
95118
# classes that share the same version flag
96119
for version_flag, subclasses in groupby(
97120
cls.registered_tools, key=lambda x: x.version_flag
98121
):
122+
logger.debug(
123+
f"Trying this `version` flag to determine if t8n supported: {version_flag}"
124+
)
125+
# adding more logging reveals we check for `-v` twice..
126+
99127
try:
100128
result = subprocess.run(
101129
[binary, version_flag], stdout=subprocess.PIPE, stderr=subprocess.PIPE
102130
)
131+
logger.debug(
132+
f"Subprocess:\n\tstdout: {result.stdout}\n\n\n\tstderr: {result.stderr}\n\n\n" # type: ignore
133+
)
134+
103135
if result.returncode != 0:
104-
raise Exception(f"Non-zero return code: {result.returncode}")
136+
logger.debug(f"Subprocess returncode is not 0! It is: {result.returncode}")
137+
continue # don't raise exception, you are supposed to keep trying different version flags # noqa: E501
105138

106139
if result.stderr:
107-
raise Exception(f"Tool wrote to stderr: {result.stderr.decode()}")
140+
logger.debug(f"Stderr detected: {result.stderr}") # type: ignore
141+
continue
108142

109143
binary_output = ""
110144
if result.stdout:
111145
binary_output = result.stdout.decode().strip()
112-
except Exception:
113-
# If the tool doesn't support the version flag,
114-
# we'll get an non-zero exit code.
146+
# e.g. 1.31.10+f62cfede9b4abfb5cd62d6f138240668620a2b0d should be treated as 1.31.10 # noqa: E501
147+
# if "+" in binary_output:
148+
# binary_output = binary_output.split("+")[0]
149+
150+
logger.debug(f"Stripped subprocess stdout: {binary_output}")
151+
152+
for subclass in subclasses:
153+
logger.debug(f"Trying subclass {subclass}")
154+
155+
if subclass.detect_binary(binary_output):
156+
return subclass(binary=binary, **kwargs)
157+
158+
logger.debug(
159+
f"T8n with version {binary_output} does not belong to subclass {subclass}"
160+
)
161+
162+
except Exception as e:
163+
logger.debug(
164+
f"Trying to determine t8n version with flag `{version_flag}` failed: {e}"
165+
)
115166
continue
116-
for subclass in subclasses:
117-
if subclass.detect_binary(binary_output):
118-
return subclass(binary=binary, **kwargs)
119167

120-
raise UnknownCLIError(f"Unknown CLI: {binary_path}")
168+
raise UnknownCLIError(f"Unknown CLI: {binary}")
121169

122170
@classmethod
123171
def detect_binary(cls, binary_output: str) -> bool:

0 commit comments

Comments
 (0)