Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions crates/resolc/src/build/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,9 +321,7 @@ impl Build {
/// # Panics
/// If the path does not contain a colon.
fn normalize_full_path(path: &str) -> String {
let mut iterator = path.split(':');
let path = iterator.next().expect("Always exists");
let name = iterator.next().expect("Always exists");
let (path, name) = path.rsplit_once(':').expect("Always exists");

let path = PathBuf::from(path);
let mut full_path = path
Expand Down
25 changes: 23 additions & 2 deletions crates/resolc/src/cli_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use std::{
fs::File,
path::PathBuf,
path::{Path, PathBuf},
process::{Command, Stdio},
};

Expand Down Expand Up @@ -49,6 +49,8 @@ pub const SOLIDITY_LIBRARY_CALL_CONTRACT_PATH: &str = "src/tests/data/solidity/l
pub const SOLIDITY_COLLISION_NESTED_PATH: &str = "src/tests/data/solidity/collision/a/c.sol";
/// The paritytech/revive#622 reproducer contract at `a_c.sol`.
pub const SOLIDITY_COLLISION_UNDERSCORE_PATH: &str = "src/tests/data/solidity/collision/a_c.sol";
/// Two contracts named `First` and `Second` returning `1` and `2`.
pub const SOLIDITY_TWO_CONTRACTS_PATH: &str = "src/tests/data/solidity/two_contracts.sol";
/// The verbatim reproducer from paritytech/revive#632: two contracts calling the same library.
pub const SOLIDITY_LINK_INDEPENDENT_OBJECTS_PATH: &str =
"src/tests/data/solidity/link_independent_objects.sol";
Expand Down Expand Up @@ -245,6 +247,11 @@ pub fn execute_resolc_with_stdin_input(arguments: &[&str], stdin_file_path: &str
execute_command("resolc", arguments, Some(stdin_file_path))
}

/// Executes the `resolc` command with the given `arguments` inside `directory`.
pub fn execute_resolc_in_directory(arguments: &[&str], directory: &Path) -> CommandResult {
execute_command_in_directory("resolc", arguments, None, Some(directory))
}

/// Executes the `solc` command with the given `arguments`.
pub fn execute_solc(arguments: &[&str]) -> CommandResult {
execute_command(SolcCompiler::DEFAULT_EXECUTABLE_NAME, arguments, None)
Expand All @@ -264,6 +271,16 @@ pub fn execute_command(
command: &str,
arguments: &[&str],
stdin_file_path: Option<&str>,
) -> CommandResult {
execute_command_in_directory(command, arguments, stdin_file_path, None)
}

/// Executes the `command` like [`execute_command`], inside `directory` if given.
pub fn execute_command_in_directory(
command: &str,
arguments: &[&str],
stdin_file_path: Option<&str>,
directory: Option<&Path>,
) -> CommandResult {
log::trace!(
"executing command: '{command} {}{}'",
Expand All @@ -277,7 +294,11 @@ pub fn execute_command(
Some(path) => Stdio::from(File::open(path).unwrap()),
None => Stdio::null(),
};
let result = Command::new(command)
let mut command = Command::new(command);
if let Some(directory) = directory {
command.current_dir(directory);
}
let result = command
.args(arguments)
.stdin(stdin_config)
.stdout(Stdio::piped())
Expand Down
40 changes: 36 additions & 4 deletions crates/resolc/src/tests/cli/combined_json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ use revive_solc_json_interface::{combined_json::CombinedJson, CombinedJsonInvali

use crate::cli_utils::{
assert_command_failure, assert_command_success, assert_equal_exit_codes, execute_resolc,
execute_solc, SOLIDITY_CONTRACT_PATH, SOLIDITY_INCLUDED_IMPORT_PATH,
SOLIDITY_REMAPPED_IMPORT_PATH, SOLIDITY_REMAPPINGS_ORDER_FIRST_DIRECTORY,
SOLIDITY_REMAPPINGS_ORDER_MAIN_PATH, SOLIDITY_REMAPPINGS_ORDER_SECOND_DIRECTORY,
YUL_CONTRACT_PATH,
execute_resolc_in_directory, execute_solc, SOLIDITY_CONTRACT_PATH,
SOLIDITY_INCLUDED_IMPORT_PATH, SOLIDITY_REMAPPED_IMPORT_PATH,
SOLIDITY_REMAPPINGS_ORDER_FIRST_DIRECTORY, SOLIDITY_REMAPPINGS_ORDER_MAIN_PATH,
SOLIDITY_REMAPPINGS_ORDER_SECOND_DIRECTORY, SOLIDITY_TWO_CONTRACTS_PATH, YUL_CONTRACT_PATH,
};
use crate::ResolcVersion;

Expand Down Expand Up @@ -217,3 +217,35 @@ fn resolves_imports_with_base_and_include_paths() {
],
);
}

/// Contracts in a source whose path contains a colon keep their own entries.
#[test]
fn keeps_contracts_of_source_path_with_colon_apart() {
const SOURCE_PATH_WITH_COLON: &str = "directory:file.sol";

let directory = tempfile::tempdir().unwrap();
std::fs::copy(
SOLIDITY_TWO_CONTRACTS_PATH,
directory.path().join(SOURCE_PATH_WITH_COLON),
)
.unwrap();

let result = execute_resolc_in_directory(
&[SOURCE_PATH_WITH_COLON, JSON_OPTION, "bin"],
directory.path(),
);
assert_command_success(&result, "Compiling a source path with a colon");

let combined_json: serde_json::Value =
serde_json::from_str(&result.stdout).expect("Combined JSON output should deserialize");
let bytecode = |name: &str| {
combined_json["contracts"][format!("{SOURCE_PATH_WITH_COLON}:{name}")]["bin"]
.as_str()
.unwrap_or_else(|| panic!("Combined JSON output should contain `{name}` bytecode"))
.to_owned()
};
let first = bytecode("First");
let second = bytecode("Second");
assert!(!first.is_empty() && !second.is_empty());
assert_ne!(first, second);
}
14 changes: 14 additions & 0 deletions crates/resolc/src/tests/data/solidity/two_contracts.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;

contract First {
function value() external pure returns (uint256) {
return 1;
}
}

contract Second {
function value() external pure returns (uint256) {
return 2;
}
}
Loading