Skip to content
Open
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
93 changes: 93 additions & 0 deletions .github/workflows/python.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
on: [push, pull_request, workflow_dispatch]

name: Aderyn-py

jobs:
check:
name: Check
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v2

- name: Install stable toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true

- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"

- name: Install git submodules
run: |
git submodule update --init --recursive

- name: Run cargo check
uses: actions-rs/cargo@v1
with:
command: check

reports:
name: Check Reports
runs-on: ubuntu-latest
steps:
- name: foundry-toolchain
uses: foundry-rs/foundry-toolchain@v1.2.0

- name: Checkout sources
uses: actions/checkout@v2

- name: Install stable toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true

- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
cache: "pip"

- name: Submodule init
run: |
git submodule update --init --recursive

- uses: actions/checkout@v3

- uses: actions/setup-node@v3
with:
node-version: 20
cache: "npm"

- uses: pnpm/action-setup@v3
with:
version: 8

- uses: bahmutov/npm-install@v1
with:
useLockFile: false
working-directory: tests/2024-05-Sablier/v2-core

- uses: bahmutov/npm-install@v1
with:
useLockFile: false
working-directory: tests/prb-math/

- name: Setup virtual environment
run: |
python -m venv venv
source venv/bin/activate
pip install -r ./aderyn_py/requirements.txt

- name: Run tests
run: |
source venv/bin/activate
cd aderyn_py
maturin develop
pytest tests
66 changes: 49 additions & 17 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions aderyn_driver/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ serde = { version = "1.0.160", features = ["derive"] }
serde_repr = "0.1.12"
cyfrin-foundry-config = { version = "0.2.1" }
toml = "0.8.13"
field_access = "0.1.8"

[dev-dependencies]
criterion = "0.5.1"
Expand Down
3 changes: 2 additions & 1 deletion aderyn_driver/src/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@ use aderyn_core::{
},
run,
};
use field_access::FieldAccess;
use std::{collections::HashMap, error::Error, path::PathBuf};

#[derive(Clone)]
#[derive(Clone, FieldAccess)]
pub struct Args {
pub root: String,
pub output: String,
Expand Down
5 changes: 3 additions & 2 deletions aderyn_py/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ crate-type = ["cdylib"]

[dependencies]
aderyn_driver = { path = "../aderyn_driver", version = "0.1.10" }
field_access = "0.1.8"

[dependencies.pyo3]
version = "0.19.0"
version = "0.22.2"
# "abi3-py38" tells pyo3 (and maturin) to build using the stable ABI with minimum Python version 3.8
features = ["abi3-py37"]
features = ["abi3-py38"]
2 changes: 2 additions & 0 deletions aderyn_py/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pytest==8.3.2
maturin==1.7.0
43 changes: 30 additions & 13 deletions aderyn_py/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,34 +1,51 @@
#![allow(unused)]

use aderyn_driver::driver;
use field_access::{FieldAccess, FieldMut};

fn main() {
use pyo3::prelude::*;
use pyo3::types::{PyBool, PyDict};

#[pyfunction]
fn generate_report(root: String, output: String) {
let args = driver::Args {
#[pyo3(signature = (root, output, **py_kwargs))]
fn generate_report(root: String, output: String, py_kwargs: Option<&Bound<'_, PyDict>>) {
let mut args = driver::Args {
root,
output,
src: None, // TODO support this later
no_snippets: false, // TODO support this later
skip_build: false, // TODO support this later
skip_cloc: false, // TODO support this later
path_includes: None, // TODO support this later
path_excludes: None, // TODO support this later
stdout: false, // TODO support this later
skip_update_check: false, // TODO support this later
auditor_mode: false, // TODO support this later
highs_only: false, // TODO support this later
src: None,
no_snippets: false,
skip_build: false,
skip_cloc: false,
path_includes: None,
path_excludes: None,
stdout: false,
skip_update_check: false,
auditor_mode: false,
highs_only: false,
};

if let Some(kwargs) = py_kwargs {
kwargs.iter().for_each(|(py_key, py_value)| {
let rust_key: String = py_key.extract().unwrap();
if py_value.is_instance_of::<PyBool>() {
let rust_value: bool = py_value.extract().unwrap();
args.field_mut(&rust_key).unwrap().replace(rust_value);
} else {
let rust_value: Vec<String> = py_value.extract().unwrap_or_default();
args.field_mut(&rust_key).unwrap().replace(Some(rust_value));
}
})
}

driver::drive(args);
}

/// A Python module implemented in Rust. The name of this function must match
/// the `lib.name` setting in the `Cargo.toml`, else Python will not be able to
/// import the module.
#[pymodule]
fn aderynpy(_py: Python, m: &PyModule) -> PyResult<()> {
fn aderynpy(m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_function(wrap_pyfunction!(generate_report, m)?)?;

Ok(())
Expand Down
27 changes: 27 additions & 0 deletions aderyn_py/tests/test_generate_report.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import subprocess
import pytest
from aderynpy import generate_report

@pytest.mark.parametrize("root, report", [
("../tests/contract-playground", "../reports/report.md"),
("../tests/2024-05-Sablier", "../reports/sablier-aderyn-toml-nested-root.md"),
("../tests/adhoc-sol-files", "../reports/adhoc-sol-files-report.md"),
("../tests/foundry-nft-f23", "../reports/nft-report.md"),
("../tests/prb-math", "../reports/prb-math-report.md"),
])
def test_generate_report(root, report):
# Define output file path
out_file = f"./{root.split('../')[-1]}-workflow.md"

# Call the generate_report function
generate_report(root, out_file)

# Run the diff command to compare the generated report with the original report
result = subprocess.run(
["diff", str(out_file), report],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)

# Check if diff command found any differences (result.returncode == 0 means no differences)
assert result.returncode == 1