Skip to content

Commit

Permalink
Merge branch 'zerosnacks/fix-tree-command' of github.com:foundry-rs/b…
Browse files Browse the repository at this point in the history
…ook into zerosnacks/fix-tree-command
  • Loading branch information
zerosnacks committed Sep 17, 2024
2 parents 08c66d4 + 455329f commit 5bdd940
Show file tree
Hide file tree
Showing 189 changed files with 1,796 additions and 879 deletions.
4 changes: 2 additions & 2 deletions projects/cheatcodes/test/BlastMock.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// ANCHOR: all
pragma solidity 0.8.10;

import "forge-std/Test.sol";
import {Test} from "forge-std/Test.sol";

// Firstly, we implement a mock emulating the actual precompile behavior
contract YieldMock {
Expand Down Expand Up @@ -38,4 +38,4 @@ contract SomeBlastTest is Test {
function testSomething() public {
// Now we can interact with Blast contracts without reverts
}
}
}
2 changes: 1 addition & 1 deletion projects/cheatcodes/test/EmitContract.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// ANCHOR: all
pragma solidity 0.8.10;

import "forge-std/Test.sol";
import {Test} from "forge-std/Test.sol";

contract EmitContractTest is Test {
event Transfer(address indexed from, address indexed to, uint256 amount);
Expand Down
2 changes: 1 addition & 1 deletion projects/cheatcodes/test/OwnerUpOnly.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// ANCHOR: prelude
pragma solidity 0.8.10;

import "forge-std/Test.sol";
import {Test} from "forge-std/Test.sol";

error Unauthorized();
// ANCHOR_END: prelude
Expand Down
2 changes: 1 addition & 1 deletion projects/fuzz_testing/test/Safe.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// ANCHOR: all
pragma solidity 0.8.10;

import "forge-std/Test.sol";
import {Test} from "forge-std/Test.sol";

contract Safe {
receive() external payable {}
Expand Down
2 changes: 1 addition & 1 deletion projects/fuzz_testing/test/Safe.t.sol.1
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// ANCHOR: all
pragma solidity 0.8.10;

import "forge-std/Test.sol";
import {Test} from "forge-std/Test.sol";

contract Safe {
receive() external payable {}
Expand Down
2 changes: 1 addition & 1 deletion projects/fuzz_testing/test/Safe.t.sol.2
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// ANCHOR: all
pragma solidity 0.8.10;

import "forge-std/Test.sol";
import {Test} from "forge-std/Test.sol";

contract Safe {
receive() external payable {}
Expand Down
2 changes: 1 addition & 1 deletion projects/fuzz_testing/test/Safe.t.sol.3
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// ANCHOR: all
pragma solidity 0.8.10;

import "forge-std/Test.sol";
import {Test} from "forge-std/Test.sol";

contract Safe {
receive() external payable {}
Expand Down
2 changes: 1 addition & 1 deletion projects/test_filters/test/ComplicatedContract.t.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.10;

import "forge-std/Test.sol";
import {Test} from "forge-std/Test.sol";

contract ComplicatedContractTest is Test {
function test_DepositERC20() public pure {
Expand Down
2 changes: 1 addition & 1 deletion projects/test_filters/test/ContractB.t.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.10;

import "forge-std/Test.sol";
import {Test} from "forge-std/Test.sol";

contract ContractBTest is Test {
function testExample() public {
Expand Down
2 changes: 1 addition & 1 deletion projects/writing_tests/test/Basic.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
pragma solidity 0.8.10;

// ANCHOR: import
import "forge-std/Test.sol";
import {Test} from "forge-std/Test.sol";
// ANCHOR_END: import

contract ContractBTest is Test {
Expand Down
2 changes: 1 addition & 1 deletion projects/writing_tests/test/Basic2.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
pragma solidity 0.8.10;

// ANCHOR: import
import "forge-std/Test.sol";
import {Test, stdError} from "forge-std/Test.sol";
// ANCHOR_END: import

contract ContractBTest is Test {
Expand Down
92 changes: 50 additions & 42 deletions scripts/gen_output/help.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ regex = "1"
use clap::Parser;
use regex::Regex;
use std::borrow::Cow;
use std::fs::{self, File};
use std::io::{self, Write};
use std::fs;
use std::io;
use std::iter::once;
use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};
Expand Down Expand Up @@ -46,11 +46,11 @@ macro_rules! regex {
#[command(about, long_about = None)]
struct Args {
/// Root directory
#[arg(long, default_value_t = String::from("."))]
root_dir: String,
#[arg(long, default_value = ".")]
root_dir: PathBuf,

/// Indentation for the root SUMMARY.md file
#[arg(long, default_value_t = 2)]
#[arg(long, default_value = "2")]
root_indentation: usize,

/// Output directory
Expand Down Expand Up @@ -98,19 +98,15 @@ fn main() -> io::Result<()> {
.commands
.iter()
.rev() // reverse to keep the order (pop)
.map(Cmd::new)
.map(|path| Cmd::new(path, vec![]))
.collect();
let mut output = Vec::new();

// Iterate over all commands and their subcommands.
while let Some(cmd) = todo_iter.pop() {
let (new_subcmds, stdout) = get_entry(&cmd)?;
if args.verbose && !new_subcmds.is_empty() {
println!(
"Found subcommands for \"{}\": {:?}",
cmd.command_name(),
new_subcmds
);
println!("Found subcommands for `{cmd}`: {}", new_subcmds.join(", "));
}
// Add new subcommands to todo_iter (so that they are processed in the correct order).
for subcmd in new_subcmds.into_iter().rev() {
Expand All @@ -121,10 +117,7 @@ fn main() -> io::Result<()> {
.chain(once(subcmd))
.collect();

todo_iter.push(Cmd {
cmd: cmd.cmd,
subcommands: new_subcmds,
});
todo_iter.push(Cmd::new(cmd.cmd, new_subcmds));
}
output.push((cmd, stdout));
}
Expand All @@ -147,7 +140,7 @@ fn main() -> io::Result<()> {
if args.readme {
let path = &out_dir.join("README.md");
if args.verbose {
println!("Writing README.md to \"{}\"", path.to_string_lossy());
println!("Writing README.md to {}", path.display());
}
write_file(path, README)?;
}
Expand All @@ -162,9 +155,9 @@ fn main() -> io::Result<()> {
})
.collect();

let path = Path::new(args.root_dir.as_str());
let path = &args.root_dir;
if args.verbose {
println!("Updating root summary in \"{}\"", path.to_string_lossy());
println!("Updating root summary in {}", path.display());
}
update_root_summary(path, &root_summary)?;
}
Expand All @@ -178,7 +171,7 @@ fn get_entry(cmd: &Cmd) -> io::Result<(Vec<String>, String)> {
.args(&cmd.subcommands)
.arg("--help")
.env("NO_COLOR", "1")
.env("COLUMNS", "100")
.env("COLUMNS", "80")
.env("LINES", "10000")
.stdout(Stdio::piped())
.output()?;
Expand Down Expand Up @@ -227,7 +220,7 @@ fn parse_sub_commands(s: &str) -> Vec<String> {
fn cmd_markdown(out_dir: &Path, cmd: &Cmd, stdout: &str) -> io::Result<()> {
let out = format!("# {}\n\n{}", cmd, help_markdown(cmd, stdout));

let out_path = out_dir.join(cmd.to_string().replace(" ", "/"));
let out_path = out_dir.join(cmd.md_path());
fs::create_dir_all(out_path.parent().unwrap())?;
write_file(&out_path.with_extension("md"), &out)?;

Expand All @@ -237,12 +230,8 @@ fn cmd_markdown(out_dir: &Path, cmd: &Cmd, stdout: &str) -> io::Result<()> {
/// Returns the markdown for a command's help output.
fn help_markdown(cmd: &Cmd, stdout: &str) -> String {
let (description, s) = parse_description(stdout);
format!(
"{}\n\n```bash\n$ {} --help\n{}\n```",
description,
cmd,
preprocess_help(s.trim())
)
let help = preprocess_help(s.trim());
format!("{description}\n\n```bash\n$ {cmd} --help\n```\n\n```txt\n{help}\n```")
}

/// Splits the help output into a description and the rest.
Expand All @@ -258,14 +247,13 @@ fn parse_description(s: &str) -> (&str, &str) {

/// Returns the summary for a command and its subcommands.
fn cmd_summary(md_root: Option<PathBuf>, cmd: &Cmd, indent: usize) -> String {
let cmd_s = cmd.to_string();
let cmd_path = cmd_s.replace(" ", "/");
let cmd_path = cmd.md_path();
let full_cmd_path = match md_root {
None => cmd_path,
Some(md_root) => format!("{}/{}", md_root.to_string_lossy(), cmd_path),
};
let indent_string = " ".repeat(indent + (cmd.subcommands.len() * 2));
format!("{}- [`{}`](./{}.md)\n", indent_string, cmd_s, full_cmd_path)
format!("{indent_string}- [`{cmd}`](./{full_cmd_path}.md)\n")
}

/// Replaces the CLI_REFERENCE section in the root SUMMARY.md file.
Expand Down Expand Up @@ -297,8 +285,7 @@ fn update_root_summary(root_dir: &Path, root_summary: &str) -> io::Result<()> {
.replace(&original_summary_content, replace_with.as_str())
.to_string();

let mut root_summary_file = File::create(&summary_file)?;
root_summary_file.write_all(new_root_summary.as_bytes())
fs::write(&summary_file, &new_root_summary)
}

/// Preprocesses the help output of a command.
Expand All @@ -322,36 +309,57 @@ fn preprocess_help(s: &str) -> Cow<'_, str> {
s
}

/// Command with subcommands.
#[derive(Hash, Debug, PartialEq, Eq)]
struct Cmd<'a> {
/// path to binary (e.g. ./target/debug/reth)
/// Path to the binary file (e.g. ./target/debug/reth).
cmd: &'a Path,
/// subcommands (e.g. [db, stats])
/// Subcommands (e.g. [db, stats]).
subcommands: Vec<String>,
}

impl<'a> Cmd<'a> {
#[track_caller]
fn new(cmd: &'a Path, subcommands: Vec<String>) -> Self {
let cmd = Self { cmd, subcommands };
cmd.assert();
cmd
}

#[track_caller]
fn assert(&self) {
for subcmd in &self.subcommands {
assert!(!subcmd.is_empty(), "subcommand is empty");
assert!(
subcmd.chars().all(|c| !c.is_whitespace()),
"subcommand contains invalid characters: {subcmd}"
);
}
}

fn command_name(&self) -> &str {
self.cmd
.file_name()
.and_then(|os_str| os_str.to_str())
.expect("Expect valid command")
}

fn new(cmd: &'a PathBuf) -> Self {
Self {
cmd,
subcommands: Vec::new(),
fn md_path(&self) -> String {
self.join_s("/")
}

fn join_s(&self, sep: &str) -> String {
let mut joined = self.command_name().to_string();
for subcmd in &self.subcommands {
joined.push_str(sep);
joined.push_str(subcmd);
}
joined
}
}

impl<'a> fmt::Display for Cmd<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.command_name())?;
if !self.subcommands.is_empty() {
write!(f, " {}", self.subcommands.join(" "))?;
}
Ok(())
self.join_s(" ").fmt(f)
}
}
2 changes: 1 addition & 1 deletion src/cheatcodes/parse-json.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ If your JSON object has `hex numbers`, they will be encoded as bytes. The way to

### How to use StdJson

1. Import the library `import "../StdJson.sol";`
1. Import the library `import {stdJson} from "forge-std/StdJson.sol";`
2. Define its usage with `string`: `using stdJson for string;`
3. If you want to parse simple values (numbers, address, etc.) use the helper functions
4. If you want to parse entire JSON objects:
Expand Down
2 changes: 1 addition & 1 deletion src/cheatcodes/parse-toml.md
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ for (uint256 i = 0; i < fruitstall.apples.length; i++) {

### How to use StdToml

1. Import the library `import "../StdToml.sol";`
1. Import the library `import {stdToml} from "forge-std/StdToml.sol";`
2. Define its usage with `string`: `using stdToml for string;`
3. If you want to parse simple values (numbers, address, etc.) use the helper functions
4. If you want to parse entire TOML tables:
Expand Down
2 changes: 1 addition & 1 deletion src/config/vscode.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,5 +86,5 @@ Add line to `.vscode/settings.json` file (solidity extension settings):
Now all contracts from the OpenZeppelin documentation can be used.

```javascript
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
```
2 changes: 1 addition & 1 deletion src/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ Alternatively, you can use [Forge Std][forge-std] which comes bundled with `cons
you have to import it:

```solidity
import "forge-std/console.sol";
import {console} from "forge-std/console.sol";
```

### How do I run specific tests?
Expand Down
4 changes: 2 additions & 2 deletions src/forge/differential-ffi-testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Below are some examples of how Forge is used for differential testing.
[`ffi`](../cheatcodes/ffi.md) allows you to execute an arbitrary shell command and capture the output. Here's a mock example:

```solidity
import "forge-std/Test.sol";
import {Test} from "forge-std/Test.sol";
contract TestContract is Test {
Expand Down Expand Up @@ -90,7 +90,7 @@ Finally, the test asserts that the both roots are exactly equal. If they are not
You may want to use differential testing against another Solidity implementation. In that case, `ffi` is not needed. Instead, the reference implementation is imported directly into the test.

```solidity
import "openzeppelin-contracts/contracts/utils/cryptography/MerkleProof.sol";
import {MerkleProof} from "openzeppelin-contracts/contracts/utils/cryptography/MerkleProof.sol";
//...
function testCompatibilityOpenZeppelinProver(bytes32[] memory _data, uint256 node) public {
vm.assume(_data.length > 1);
Expand Down
8 changes: 4 additions & 4 deletions src/forge/forge-std.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ It provides all the essential functionality you need to get started writing test
Simply import `Test.sol` and inherit from `Test` in your test contract:

```solidity
import "forge-std/Test.sol";
import {Test} from "forge-std/Test.sol";
contract ContractTest is Test { ...
```
Expand All @@ -38,17 +38,17 @@ deal(address(dai), alice, 10000e18);
To import the `Vm` interface or the `console` library individually:

```solidity
import "forge-std/Vm.sol";
import {Vm} from "forge-std/Vm.sol";
```

```solidity
import "forge-std/console.sol";
import {console} from "forge-std/console.sol";
```

**Note:** `console2.sol` contains patches to `console.sol` that allows Forge to decode traces for calls to the console, but it is not compatible with Hardhat.

```solidity
import "forge-std/console2.sol";
import {console2} from "forge-std/console2.sol";
```

### Standard libraries
Expand Down
Loading

0 comments on commit 5bdd940

Please sign in to comment.