diff --git a/README.md b/README.md index 210a783..bf2269f 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,17 @@ ape compile The byte-code and ABI for your contracts should now exist in a `__local__.json` file in a `.build/` directory. +### Solidity Versioning + +By default, `ape-solidity` tries to use the best versions of Solidity by looking at all the source files' pragma specifications. +However, it is often better to specify a version directly. +If you know the best version to use, set it in your `ape-config.yaml`, like this: + +```yaml +solidity: + version: 0.8.14 +``` + ### Dependency Mapping To configure import remapping, use your project's `ape-config.yaml` file: diff --git a/ape_solidity/compiler.py b/ape_solidity/compiler.py index b92fa38..68e8333 100644 --- a/ape_solidity/compiler.py +++ b/ape_solidity/compiler.py @@ -224,9 +224,7 @@ def _add_dependencies( cached_source.parent.mkdir(parents=True, exist_ok=True) if src.content: cached_source.touch() - cached_source.write_text( - src.content if isinstance(src.content, str) else str(src.content) - ) + cached_source.write_text(str(src.content)) # Add dependency remapping that may be needed. for compiler in manifest.compilers or []: @@ -264,21 +262,36 @@ def _add_dependencies( break - if version is None: - raise CompilerError(f"Unable to discern dependency type '{uri_str}'.") - # Find matching package for package in packages_dir.iterdir(): if package.name.replace("_", "-").lower() == dependency_name: dependency_name = str(package.name) break - dependency_path = ( - self.config_manager.packages_folder - / Path(dependency_name) - / version - / f"{dependency_name}.json" - ) + dependency_root_path = self.config_manager.packages_folder / Path(dependency_name) + + if version is None: + version_dirs = [ + d + for d in list(dependency_root_path.iterdir()) + if d.is_dir() and not d.name.startswith(".") + ] + if len(version_dirs) == 1: + # Use the only existing version. + version = version_dirs[0].name + + elif (dependency_root_path / "local").is_dir(): + # If not specified, and local exists, use local by default. + version = "local" + + else: + options = ", ".join([x.name for x in dependency_root_path.iterdir()]) + raise CompilerError( + f"Ambiguous dependency version. " + f"Please specify. Available versions: '{options}'." + ) + + dependency_path = dependency_root_path / version / f"{dependency_name}.json" if dependency_path.is_file(): sub_manifest = PackageManifest.parse_file(dependency_path) dep_id = Path(dependency_name) / version diff --git a/setup.py b/setup.py index 848d459..4fb919f 100644 --- a/setup.py +++ b/setup.py @@ -21,6 +21,7 @@ "mdformat>=0.7.16", # Auto-formatter for markdown "mdformat-gfm>=0.3.5", # Needed for formatting GitHub-flavored markdown "mdformat-frontmatter>=0.4.1", # Needed for frontmatters-style headers in issue templates + "pydantic<2.0", # Needed for successful type check. TODO: Remove after full v2 support. ], "doc": [ "Sphinx>=3.4.3,<4", # Documentation generator diff --git a/tests/conftest.py b/tests/conftest.py index 22ee7f6..d40004b 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -105,8 +105,13 @@ def project(data_folder, config): @pytest.fixture -def compiler(): - return ape.compilers.registered_compilers[Extension.SOL.value] +def compiler_manager(): + return ape.compilers + + +@pytest.fixture +def compiler(compiler_manager): + return compiler_manager.registered_compilers[Extension.SOL.value] @pytest.fixture