Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: use thiserror within crates #111

Merged
merged 51 commits into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
abf13fa
refactor: move everything to crates folder
AlexD10S Apr 9, 2024
778d380
refactor: new and build contracts
AlexD10S Apr 9, 2024
b16f4b2
refactor: test contract functionality in pop_contracts
AlexD10S Apr 9, 2024
2a45362
refactor: up and call contracts
AlexD10S Apr 9, 2024
36c14c8
refactor: cargo
AlexD10S Apr 9, 2024
9dd8965
refactor: new parachain and pallet
AlexD10S Apr 10, 2024
1cd078d
refactor: build parachain
AlexD10S Apr 10, 2024
faeeec5
refactor: up parachain
AlexD10S Apr 10, 2024
6a38865
refactor: clean cargo pop-cli
AlexD10S Apr 10, 2024
60d0b51
docs: pop-contracts README
AlexD10S Apr 10, 2024
9c91278
docs: pop-parachains README
AlexD10S Apr 10, 2024
0f3e95a
chore: fmt
AlexD10S Apr 10, 2024
710d8ca
chore: versions of crates to 0.0.0
AlexD10S Apr 10, 2024
537c812
chore: version 0.1.0 for crates
AlexD10S Apr 11, 2024
9f1fb32
refactor: shared dependencies in workspace Cargo.toml
AlexD10S Apr 11, 2024
f061585
refactor: move dependencies to workspace
AlexD10S Apr 12, 2024
9d214e1
docs: feedback on docs
AlexD10S Apr 13, 2024
5da3761
chore: merge main
AlexD10S Apr 13, 2024
1842974
chore: remove version for local dependencies
AlexD10S Apr 15, 2024
a405e7d
use thiserror
brunopgalvao Apr 16, 2024
00c028a
use thiserror
brunopgalvao Apr 16, 2024
c8e4c47
add thiserror dependency
brunopgalvao Apr 16, 2024
8fd7502
docs: update nitpicks in README
AlexD10S Apr 16, 2024
c373100
fixes: typo
weezy20 Apr 17, 2024
9fceacf
use thiserror
brunopgalvao Apr 17, 2024
8601484
use thiserror
brunopgalvao Apr 17, 2024
4107e44
use thiserror in build
brunopgalvao Apr 17, 2024
d112c9a
use thiserror
brunopgalvao Apr 17, 2024
2651e78
use thiserror
brunopgalvao Apr 17, 2024
a62d074
Merge branch 'alex/refactor-frontend-backend' into bruno/use-thiserror
brunopgalvao Apr 17, 2024
710336d
use thiserror
brunopgalvao Apr 17, 2024
c36fe01
remove braces
brunopgalvao Apr 17, 2024
1613722
Merge branch 'main' into bruno/use-thiserror
brunopgalvao Apr 17, 2024
00a4c7b
cargo fmt --all
brunopgalvao Apr 17, 2024
b0df29f
revert changes
brunopgalvao Apr 17, 2024
b3c970e
cargo fmt --all
brunopgalvao Apr 17, 2024
3bcf5c5
rename NewContractError to NewContractFailed
brunopgalvao Apr 18, 2024
744c370
create an error module for the crate
brunopgalvao Apr 18, 2024
2c69229
refactor errors
brunopgalvao Apr 18, 2024
bb2b882
create errors module on crate level
brunopgalvao Apr 18, 2024
878723d
refactor thiserror to use crate module
brunopgalvao Apr 18, 2024
0059d7a
replace with thiserror
brunopgalvao Apr 18, 2024
ae4edfd
cargo fmt --all
brunopgalvao Apr 18, 2024
238cb01
rename
brunopgalvao Apr 18, 2024
bd34ff4
use crate thiserror
brunopgalvao Apr 18, 2024
6f5469b
use thiserror
brunopgalvao Apr 18, 2024
4bee9fe
remove duplicate
brunopgalvao Apr 18, 2024
9989c1d
cargo fmt --all
brunopgalvao Apr 18, 2024
df0efa8
use thiserror crate
brunopgalvao Apr 18, 2024
694957f
remove `result.status.success`
brunopgalvao Apr 21, 2024
0dcf72f
remove unused `result`
brunopgalvao Apr 21, 2024
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
2 changes: 2 additions & 0 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 Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ members = ["crates/*"]

[workspace.dependencies]
anyhow = "1.0"
thiserror = "1.0.58"
duct = "0.13"
git2 = "0.18"
tempfile = "3.8"
Expand Down
2 changes: 1 addition & 1 deletion crates/pop-cli/src/commands/new/pallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ impl NewPalletCommand {
&self.name,
))?;
set_theme(Theme);
let target = resolve_pallet_path(self.path.clone());
let target = resolve_pallet_path(self.path.clone())?;
let pallet_name = self.name.clone();
let pallet_path = target.join(pallet_name.clone());
if pallet_path.exists() {
Expand Down
1 change: 1 addition & 0 deletions crates/pop-contracts/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ edition = "2021"

[dependencies]
anyhow.workspace = true
thiserror.workspace = true
duct.workspace = true
url.workspace = true

Expand Down
31 changes: 31 additions & 0 deletions crates/pop-contracts/src/errors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use thiserror::Error;

#[derive(Error, Debug)]
pub enum Error {
#[error("Failed to create new contract project: {0}")]
NewContract(String),

#[error("IO error: {0}")]
IO(#[from] std::io::Error),

#[error("Failed to execute test command: {0}")]
TestCommand(String),

#[error("Failed to parse balance: {0}")]
BalanceParsing(String),

#[error("Failed to parse account address: {0}")]
AccountAddressParsing(String),

#[error("Failed to get manifest path: {0}")]
ManifestPath(String),

#[error("Failed to parse secret URI: {0}")]
ParseSecretURI(String),

#[error("Failed to create keypair from URI: {0}")]
KeyPairCreation(String),

#[error("Failed to parse hex encoded bytes: {0}")]
HexParsing(String),
}
1 change: 1 addition & 0 deletions crates/pop-contracts/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
mod build;
mod call;
mod errors;
mod new;
mod test;
mod up;
Expand Down
35 changes: 24 additions & 11 deletions crates/pop-contracts/src/new.rs
Original file line number Diff line number Diff line change
@@ -1,30 +1,43 @@
use crate::errors::Error;
use contract_build::new_contract_project;
use std::path::Path;

/// Create a new smart contract at `target`
pub fn create_smart_contract(name: String, target: &Path) -> anyhow::Result<()> {
// In this code, out_dir will automatically join `name` to `target`,
// which is created prior to the call to this function
// So we must pass `target.parent()`
new_contract_project(&name, target.canonicalize()?.parent())
pub fn create_smart_contract(name: String, target: &Path) -> Result<(), Error> {
// Canonicalize the target path to ensure consistency and resolve any symbolic links.
let canonicalized_path = target
.canonicalize()
// If an I/O error occurs during canonicalization, convert it into an Error enum variant.
.map_err(|e| Error::IO(e))?;

// Retrieve the parent directory of the canonicalized path.
let parent_path = canonicalized_path
.parent()
// If the parent directory cannot be retrieved (e.g., if the path has no parent),
// return a NewContract variant indicating the failure.
.ok_or(Error::NewContract("Failed to get parent directory".to_string()))?;

// Create a new contract project with the provided name in the parent directory.
new_contract_project(&name, Some(parent_path))
// If an error occurs during the creation of the contract project,
// convert it into a NewContract variant with a formatted error message.
.map_err(|e| Error::NewContract(format!("{}", e)))
}

#[cfg(test)]
mod tests {
use super::*;
use anyhow::{Error, Result};
use std::fs;
use tempfile;

fn setup_test_environment() -> Result<tempfile::TempDir, Error> {
let temp_dir = tempfile::tempdir().expect("Could not create temp dir");
let temp_dir = tempfile::tempdir()?;
let temp_contract_dir = temp_dir.path().join("test_contract");
fs::create_dir(&temp_contract_dir)?;
let result =
create_smart_contract("test_contract".to_string(), temp_contract_dir.as_path());
assert!(result.is_ok(), "Contract test environment setup failed");

create_smart_contract("test_contract".to_string(), temp_contract_dir.as_path())?;
Ok(temp_dir)
}

#[test]
fn test_create_smart_contract_success() -> Result<(), Error> {
let temp_dir = setup_test_environment()?;
Expand Down
41 changes: 25 additions & 16 deletions crates/pop-contracts/src/test.rs
Original file line number Diff line number Diff line change
@@ -1,46 +1,55 @@
use crate::errors::Error;
use duct::cmd;
use std::path::PathBuf;

pub fn test_smart_contract(path: &Option<PathBuf>) -> anyhow::Result<()> {
cmd("cargo", vec!["test"]).dir(path.clone().unwrap_or("./".into())).run()?;

pub fn test_smart_contract(path: &Option<PathBuf>) -> Result<(), Error> {
// Execute `cargo test` command in the specified directory.
cmd("cargo", vec!["test"])
.dir(path.clone().unwrap_or_else(|| PathBuf::from("./")))
.run()
.map_err(|e| Error::TestCommand(format!("Cargo test command failed: {}", e)))?;
Ok(())
}

pub fn test_e2e_smart_contract(path: &Option<PathBuf>) -> anyhow::Result<()> {
pub fn test_e2e_smart_contract(path: &Option<PathBuf>) -> Result<(), Error> {
// Execute `cargo test --features=e2e-tests` command in the specified directory.
cmd("cargo", vec!["test", "--features=e2e-tests"])
.dir(path.clone().unwrap_or("./".into()))
.run()?;

.dir(path.clone().unwrap_or_else(|| PathBuf::from("./")))
.run()
.map_err(|e| Error::TestCommand(format!("Cargo test command failed: {}", e)))?;
Ok(())
}

#[cfg(feature = "unit_contract")]
#[cfg(test)]
mod tests {
use super::*;
use anyhow::{Error, Result};
use std::fs;
use tempfile;

fn setup_test_environment() -> Result<tempfile::TempDir, Error> {
let temp_dir = tempfile::tempdir().expect("Could not create temp dir");
let temp_dir = tempfile::tempdir().map_err(|e| {
Error::TestEnvironmentError(format!("Failed to create temp dir: {}", e))
})?;
let temp_contract_dir = temp_dir.path().join("test_contract");
fs::create_dir(&temp_contract_dir)?;
fs::create_dir(&temp_contract_dir).map_err(|e| {
Error::TestEnvironmentError(format!("Failed to create test contract directory: {}", e))
})?;
let result =
crate::create_smart_contract("test_contract".to_string(), temp_contract_dir.as_path());
crate::create_smart_contract("test_contract".to_string(), temp_contract_dir.as_path())
.map_err(|e| {
Error::TestEnvironmentError(format!("Failed to create smart contract: {}", e))
})?;
assert!(result.is_ok(), "Contract test environment setup failed");

Ok(temp_dir)
}

#[test]
fn test_contract_test() -> Result<(), Error> {
let temp_contract_dir = setup_test_environment()?;

let result = test_smart_contract(&Some(temp_contract_dir.path().join("test_contract")));

// Run unit tests for the smart contract in the temporary contract directory.
let result = test_smart_contract(&Some(temp_contract_dir.path().join("test_contract")))?;
assert!(result.is_ok(), "Result should be Ok");

Ok(())
}
}
29 changes: 13 additions & 16 deletions crates/pop-contracts/src/utils/helpers.rs
Original file line number Diff line number Diff line change
@@ -1,33 +1,30 @@
use anyhow::{anyhow, Result};
use crate::errors::Error;
use contract_build::ManifestPath;
use contract_extrinsics::BalanceVariant;
use ink_env::{DefaultEnvironment, Environment};
use std::{path::PathBuf, str::FromStr};
use subxt::{Config, PolkadotConfig as DefaultConfig};

// If the user specifies a path (which is not the current directory), it will have to manually
// add a Cargo.toml file. If not provided, pop-cli will ask the user for a specific path. or ask
// to the user the specific path (Like cargo-contract does)
pub fn get_manifest_path(path: &Option<PathBuf>) -> anyhow::Result<ManifestPath> {
if path.is_some() {
let full_path: PathBuf =
PathBuf::from(path.as_ref().unwrap().to_string_lossy().to_string() + "/Cargo.toml");

return ManifestPath::try_from(Some(full_path));
pub fn get_manifest_path(path: &Option<PathBuf>) -> Result<ManifestPath, Error> {
if let Some(path) = path {
let full_path = PathBuf::from(path.to_string_lossy().to_string() + "/Cargo.toml");
return ManifestPath::try_from(Some(full_path))
.map_err(|e| Error::ManifestPath(format!("Failed to get manifest path: {}", e)));
} else {
return ManifestPath::try_from(path.as_ref());
return ManifestPath::try_from(path.as_ref())
.map_err(|e| Error::ManifestPath(format!("Failed to get manifest path: {}", e)));
}
}

/// Parse a balance from string format
pub fn parse_balance(
balance: &str,
) -> Result<BalanceVariant<<DefaultEnvironment as Environment>::Balance>> {
BalanceVariant::from_str(balance).map_err(|e| anyhow!("Balance parsing failed: {e}"))
) -> Result<BalanceVariant<<DefaultEnvironment as Environment>::Balance>, Error> {
BalanceVariant::from_str(balance).map_err(|e| Error::BalanceParsing(format!("{}", e)))
}
pub fn parse_account(account: &str) -> Result<<DefaultConfig as Config>::AccountId> {

pub fn parse_account(account: &str) -> Result<<DefaultConfig as Config>::AccountId, Error> {
<DefaultConfig as Config>::AccountId::from_str(account)
.map_err(|e| anyhow::anyhow!("Account address parsing failed: {e}"))
.map_err(|e| Error::AccountAddressParsing(format!("{}", e)))
}

#[cfg(test)]
Expand Down
14 changes: 8 additions & 6 deletions crates/pop-contracts/src/utils/signer.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
use anyhow::Result;
use crate::errors::Error;
use contract_build::util::decode_hex;
use sp_core::Bytes;
use subxt_signer::{sr25519::Keypair, SecretUri};

/// Create a Signer from a secret URI.
pub(crate) fn create_signer(suri: &str) -> Result<Keypair> {
let uri = <SecretUri as std::str::FromStr>::from_str(suri)?;
let keypair = Keypair::from_uri(&uri)?;
pub(crate) fn create_signer(suri: &str) -> Result<Keypair, Error> {
let uri = <SecretUri as std::str::FromStr>::from_str(suri)
.map_err(|e| Error::ParseSecretURI(format!("{}", e)))?;
let keypair = Keypair::from_uri(&uri).map_err(|e| Error::KeyPairCreation(format!("{}", e)))?;
Ok(keypair)
}

/// Parse hex encoded bytes.
pub fn parse_hex_bytes(input: &str) -> Result<Bytes> {
let bytes = decode_hex(input)?;
pub fn parse_hex_bytes(input: &str) -> Result<Bytes, Error> {
let bytes = decode_hex(input).map_err(|e| Error::HexParsing(format!("{}", e)))?;
Ok(bytes.into())
}
1 change: 1 addition & 0 deletions crates/pop-parachains/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ edition = "2021"

[dependencies]
anyhow.workspace = true
thiserror.workspace = true
duct.workspace = true
git2.workspace = true
tempfile.workspace = true
Expand Down
50 changes: 50 additions & 0 deletions crates/pop-parachains/src/errors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
use thiserror::Error;
use zombienet_sdk::OrchestratorError;

#[derive(Error, Debug)]
pub enum Error {
#[error("a git error occurred: {0}")]
Git(String),

#[error("Failed to access the current directory")]
CurrentDirAccess,

#[error("Failed to locate the workspace")]
WorkspaceLocate,

#[error("Failed to create pallet directory")]
PalletDirCreation,

#[error("IO error: {0}")]
IO(#[from] std::io::Error),

#[error("HTTP error: {0}")]
HttpError(#[from] reqwest::Error),

#[error("Missing binary: {0}")]
MissingBinary(String),

#[error("Configuration error: {0}")]
Config(String),

#[error("Unsupported command: {0}")]
UnsupportedCommand(String),

#[error("ParseError error: {0}")]
ParseError(#[from] url::ParseError),

#[error("Orchestrator error: {0}")]
OrchestratorError(#[from] OrchestratorError),

#[error("Toml error: {0}")]
TomlError(#[from] toml_edit::de::Error),

#[error("Anyhow error: {0}")]
AnyhowError(#[from] anyhow::Error),

#[error("User aborted due to existing target folder.")]
Aborted,

#[error("Failed to execute rustfmt")]
RustfmtError(std::io::Error),
}
1 change: 1 addition & 0 deletions crates/pop-parachains/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
mod build;
mod errors;
mod generator;
mod new_pallet;
mod new_parachain;
Expand Down
9 changes: 5 additions & 4 deletions crates/pop-parachains/src/new_pallet.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::{fs, path::PathBuf};

use crate::errors::Error;
use crate::{
generator::pallet::{
PalletBenchmarking, PalletCargoToml, PalletItem, PalletLib, PalletMock, PalletTests,
Expand All @@ -17,8 +18,8 @@ pub struct TemplatePalletConfig {
pub fn create_pallet_template(
path: Option<String>,
config: TemplatePalletConfig,
) -> anyhow::Result<()> {
let target = resolve_pallet_path(path);
) -> Result<(), Error> {
let target = resolve_pallet_path(path)?;
let pallet_name = config.name.clone();
let pallet_path = target.join(pallet_name.clone());
sanitize(&pallet_path)?;
Expand All @@ -29,7 +30,7 @@ pub fn create_pallet_template(
}

/// Generate a pallet folder and file structure
fn generate_pallet_structure(target: &PathBuf, pallet_name: &str) -> anyhow::Result<()> {
fn generate_pallet_structure(target: &PathBuf, pallet_name: &str) -> Result<(), Error> {
use fs::{create_dir, File};
let (pallet, src) = (target.join(pallet_name), target.join(pallet_name.to_string() + "/src"));
create_dir(&pallet)?;
Expand All @@ -46,7 +47,7 @@ fn render_pallet(
pallet_name: String,
config: TemplatePalletConfig,
pallet_path: &PathBuf,
) -> anyhow::Result<()> {
) -> Result<(), Error> {
let pallet_name = pallet_name.replace('-', "_");
// Todo `module` must be of the form Template if pallet_name : `pallet_template`
let pallet: Vec<Box<dyn PalletItem>> = vec![
Expand Down
Loading
Loading