Skip to content

Commit c81b593

Browse files
committed
removed solc-select dependency, try to use solc from PATH
1 parent 9aa6e89 commit c81b593

File tree

5 files changed

+135
-284
lines changed

5 files changed

+135
-284
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ dependencies = [
3838
"semver>=3.0.1,<4",
3939
"pydantic>=2.10.0,<3",
4040
"rich>=13.7.0,<14",
41-
"solc-select>=1.0.4,<2",
4241
"filelock>=3.15.1,<4",
4342
"ethereum-types>=0.2.1,<0.3",
4443
"pyyaml>=6.0.2,<7",
@@ -50,6 +49,7 @@ dependencies = [
5049
"pytest-regex>=0.2.0,<0.3",
5150
"eth-abi>=5.2.0",
5251
"joblib>=1.4.2",
52+
"ckzg>=2.1.1,<3",
5353
]
5454

5555
[project.urls]

src/pytest_plugins/solc/solc.py

Lines changed: 76 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,13 @@
1-
"""Pytest plugin for configuring and installing the solc compiler."""
1+
"""Pytest plugin for configuring and verifying the solc compiler."""
22

3-
import platform
43
import subprocess
5-
from argparse import ArgumentTypeError
64
from shutil import which
75

86
import pytest
9-
import solc_select.solc_select as solc_select # type: ignore
107
from pytest_metadata.plugin import metadata_key # type: ignore
118
from semver import Version
129

1310
from ethereum_test_forks import Frontier
14-
from ethereum_test_tools.code import Solc
15-
16-
DEFAULT_SOLC_VERSION = "0.8.24"
1711

1812

1913
def pytest_addoption(parser: pytest.Parser):
@@ -26,110 +20,109 @@ def pytest_addoption(parser: pytest.Parser):
2620
type=str,
2721
default=None,
2822
help=(
29-
"Path to a solc executable (for Yul source compilation). "
30-
"No default; if unspecified `--solc-version` is used."
23+
"Path to a solc executable (for Yul source compilation). Default: solc binary in PATH."
3124
),
3225
)
33-
solc_group.addoption(
34-
"--solc-version",
35-
action="store",
36-
dest="solc_version",
37-
default=None,
38-
help=f"Version of the solc compiler to use. Default: {DEFAULT_SOLC_VERSION}.",
39-
)
4026

4127

4228
@pytest.hookimpl(tryfirst=True)
4329
def pytest_configure(config: pytest.Config):
44-
"""
45-
Ensure that the specified solc version is:
46-
- available if --solc_bin has been specified,
47-
- installed via solc_select if --solc_version has been specified.
48-
"""
30+
"""Ensure that solc is available and get its version."""
4931
solc_bin = config.getoption("solc_bin")
50-
solc_version = config.getoption("solc_version")
51-
52-
if solc_bin and solc_version:
53-
raise pytest.UsageError(
54-
"You cannot specify both --solc-bin and --solc-version. Please choose one."
55-
)
5632

33+
# Use provided solc binary or find it in PATH
5734
if solc_bin:
58-
# will raise an error if the solc binary is not found.
59-
solc_version_semver = Solc(config.getoption("solc_bin")).version
35+
if not which(solc_bin):
36+
pytest.exit(
37+
f"Specified solc binary not found: {solc_bin}",
38+
returncode=pytest.ExitCode.USAGE_ERROR,
39+
)
6040
else:
61-
# if no solc binary is specified, use solc-select
62-
solc_version = solc_version or DEFAULT_SOLC_VERSION
63-
try:
64-
version, _ = solc_select.current_version()
65-
except ArgumentTypeError:
66-
version = None
67-
if version != solc_version:
68-
# solc-select current does not support ARM linux
69-
if platform.system().lower() == "linux" and platform.machine().lower() == "aarch64":
70-
error_message = (
71-
f"Version {version} does not match solc_version {solc_version} "
72-
"and since solc-select currently does not support ARM linux you must "
73-
"manually do the following: "
74-
"Build solc from source, and manually move the binary to "
75-
".venv/.solc-select/artifacts/solc-x.y.z/solc-x.y.z, then run "
76-
"'uv run solc-select use <x.y.z>'"
77-
)
78-
pytest.exit(error_message, returncode=pytest.ExitCode.USAGE_ERROR)
79-
80-
if config.getoption("verbose") > 0:
81-
print(f"Setting solc version {solc_version} via solc-select...")
82-
try:
83-
solc_select.switch_global_version(solc_version, always_install=True)
84-
except Exception as e:
85-
message = f"Failed to install solc version {solc_version}: {e}. "
86-
if isinstance(e, ArgumentTypeError):
87-
message += "\nList available versions using `uv run solc-select install`."
88-
pytest.exit(message, returncode=pytest.ExitCode.USAGE_ERROR)
89-
solc_version_semver = Version.parse(solc_version)
90-
config.option.solc_bin = which("solc") # save for fixture
41+
solc_bin = which("solc")
42+
if not solc_bin:
43+
pytest.exit(
44+
"solc binary not found in PATH. Please install solc and ensure it's in your PATH.",
45+
returncode=pytest.ExitCode.USAGE_ERROR,
46+
)
47+
48+
# Get solc version using subprocess
49+
try:
50+
result = subprocess.run(
51+
[solc_bin, "--version"],
52+
stdout=subprocess.PIPE,
53+
stderr=subprocess.STDOUT,
54+
text=True,
55+
check=True,
56+
timeout=10,
57+
)
58+
except subprocess.CalledProcessError as e:
59+
pytest.exit(
60+
f"Failed to get solc version. Command output: {e.stdout}",
61+
returncode=pytest.ExitCode.USAGE_ERROR,
62+
)
63+
except subprocess.TimeoutExpired:
64+
pytest.exit("Timeout while getting solc version.", returncode=pytest.ExitCode.USAGE_ERROR)
65+
except Exception as e:
66+
pytest.exit(
67+
f"Unexpected error while getting solc version: {e}",
68+
returncode=pytest.ExitCode.USAGE_ERROR,
69+
)
70+
71+
# Parse version from output
72+
version_output = result.stdout
73+
version_line = None
74+
75+
# Look for version in output (format: "Version: X.Y.Z+commit.hash")
76+
for line in version_output.split("\n"):
77+
if line.startswith("Version:"):
78+
version_line = line
79+
break
80+
81+
if not version_line:
82+
pytest.exit(
83+
f"Could not parse solc version from output:\n{version_output}",
84+
returncode=pytest.ExitCode.USAGE_ERROR,
85+
)
9186

87+
# Extract version number
88+
try:
89+
# Format is typically "Version: 0.8.24+commit.e11b9ed9.Linux.g++"
90+
version_str = version_line.split()[1].split("+")[0]
91+
solc_version_semver = Version.parse(version_str)
92+
except (IndexError, ValueError) as e:
93+
pytest.exit(
94+
f"Failed to parse solc version from: {version_line}\nError: {e}",
95+
returncode=pytest.ExitCode.USAGE_ERROR,
96+
)
97+
98+
# Store version in metadata
9299
if "Tools" not in config.stash[metadata_key]:
93100
config.stash[metadata_key]["Tools"] = {
94101
"solc": str(solc_version_semver),
95102
}
96103
else:
97104
config.stash[metadata_key]["Tools"]["solc"] = str(solc_version_semver)
98105

106+
# Check minimum version requirement
99107
if solc_version_semver < Frontier.solc_min_version():
100108
pytest.exit(
101-
f"Unsupported solc version: {solc_version}. Minimum required version is "
109+
f"Unsupported solc version: {solc_version_semver}. Minimum required version is "
102110
f"{Frontier.solc_min_version()}",
103111
returncode=pytest.ExitCode.USAGE_ERROR,
104112
)
113+
114+
# Store for later use
105115
config.solc_version = solc_version_semver # type: ignore
116+
config.option.solc_bin = solc_bin # save for fixture
106117

107-
# test whether solc_version matches actual one
108-
# using subprocess because that's how yul is compiled in
109-
# ./src/ethereum_test_specs/static_state/common/compile_yul.py
110-
expected_solc_version_string: str = str(solc_version_semver)
111-
actual_solc_version = subprocess.run(
112-
["solc", "--version"],
113-
stdout=subprocess.PIPE,
114-
stderr=subprocess.STDOUT,
115-
text=True,
116-
check=True,
117-
)
118-
actual_solc_version_string = actual_solc_version.stdout
119-
# use only look at first 10 chars to pass e.g.
120-
# actual: 0.8.25+commit.b61c2a91.Linux.g++ should pass with expected: "0.8.25+commit.b61c2a91
121-
if (
122-
expected_solc_version_string[:10] not in actual_solc_version_string
123-
) or expected_solc_version_string == "":
124-
error_message = f"Expected solc version {solc_version_semver} but detected a\
125-
different solc version:\n{actual_solc_version_string}\nCritical error, aborting.."
126-
pytest.exit(error_message, returncode=pytest.ExitCode.USAGE_ERROR)
118+
if config.getoption("verbose") > 0:
119+
print(f"Using solc version {solc_version_semver} from {solc_bin}")
127120

128121

129122
@pytest.fixture(autouse=True, scope="session")
130123
def solc_bin(request: pytest.FixtureRequest):
131124
"""Return configured solc binary path."""
132-
return request.config.getoption("solc_bin")
125+
return request.config.getoption("solc_bin") or which("solc")
133126

134127

135128
@pytest.hookimpl(trylast=True)
@@ -138,4 +131,5 @@ def pytest_report_header(config, start_path):
138131
if config.option.collectonly:
139132
return
140133
solc_version = config.stash[metadata_key]["Tools"]["solc"]
141-
return [(f"solc: {solc_version}")]
134+
solc_path = config.option.solc_bin or which("solc")
135+
return [f"solc: {solc_version}", f"solc path: {solc_path}"]

src/pytest_plugins/solc/tests/__init__.py

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)