Skip to content

Commit

Permalink
Reworked the fqn and module handling mechanism (#72)
Browse files Browse the repository at this point in the history
* Reworked the fqn and module handling mechanism
Closes: #70

* Unify casing boundaries when converting between snake and camel case

* Fix casing when scanning for contract names.
Closes: #71

* Removed cargo update command.
* Updated README.

* Fix for rust complaining about templates being in workspace
  • Loading branch information
kubaplas authored Feb 2, 2024
1 parent 51fe151 commit f9edb33
Show file tree
Hide file tree
Showing 14 changed files with 105 additions and 82 deletions.
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ $ cargo odra test -b casper
* `test` - runs tests,
* `generate` - generates sample contract,
* `clean` - removes temporary files (builders and wasm files),
* `update` - runs cargo update on project and backends.
* `completions` - generates autocomplete script for given shell

To see exact syntax of each command, type `cargo odra command --help`.
Expand All @@ -63,11 +62,16 @@ To see exact syntax of each command, type `cargo odra command --help`.
file into root of your workspace. If you have multiple odra crates in your
workspace, put all contracts in the same Odra.toml folder.

You can use a template to create a project with workspace:

```bash
$ cargo odra new --name myproject --template workspace && cd myproject
```

## Links

* [Odra](https://github.com/odradev/odra)
* [Cargo Odra](https://github.com/odradev/cargo-odra)
* [Odra Casper](https://github.com/odradev/odra-casper)
* [Odra framework repository](https://github.com/odradev/odra)
* [Odra docs](https://odra.dev/docs)

## Contact
Write **[email protected]**
Expand Down
1 change: 0 additions & 1 deletion src/actions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,4 @@ pub mod generate;
pub mod init;
pub mod schema;
pub mod test;
pub mod update;
mod utils;
8 changes: 4 additions & 4 deletions src/actions/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ impl BuildAction<'_> {
});

for contract in contracts {
let build_contract = format!("{}_build_contract", &contract.crate_name());
let build_contract = format!("{}_build_contract", &contract.crate_name(self.project));
command::cargo_build_wasm_files(
self.project.project_root(),
&contract.struct_name(),
&contract.crate_name(),
&contract.crate_name(self.project),
);
let source = paths::wasm_path_in_target(&build_contract, self.project.project_root());
let target =
Expand All @@ -56,7 +56,7 @@ impl BuildAction<'_> {
let module_wasm_dir = self
.project
.project_root()
.join(contract.crate_name())
.join(contract.module_name())
.join("wasm");
command::mkdir(module_wasm_dir.clone());
let mut module_wasm_path = module_wasm_dir.clone().join(&contract.struct_name());
Expand All @@ -80,7 +80,7 @@ impl BuildAction<'_> {
if self.project.is_workspace() {
command::process_wasm(
&contract.struct_name(),
self.project.project_root().join(contract.crate_name()),
self.project.project_root().join(contract.module_name()),
);
}
}
Expand Down
61 changes: 36 additions & 25 deletions src/actions/generate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,13 @@
use std::path::PathBuf;

use convert_case::{Case, Casing};

use crate::{
command,
consts::ODRA_TEMPLATE_GH_RAW_REPO,
errors::Error,
log,
odra_toml::Contract,
paths,
paths::{to_camel_case, to_snake_case},
project::Project,
template::TemplateGenerator,
};
Expand All @@ -21,20 +19,24 @@ pub struct GenerateAction<'a> {
contract_name: String,
contract_module_ident: String,
module_root: PathBuf,
module_name: String,
module_name: Option<String>,
template_generator: TemplateGenerator,
}

/// GenerateAction implementation.
impl<'a> GenerateAction<'a> {
/// Crate a new GenerateAction for a given contract.
pub fn new(project: &'a Project, contract_name: String, module_name: Option<String>) -> Self {
if project.is_workspace() && module_name.is_none() {
Error::ModuleNotProvided.print_and_die();
}

GenerateAction {
project,
contract_name: contract_name.clone(),
contract_module_ident: contract_name.to_case(Case::UpperCamel),
contract_module_ident: to_snake_case(contract_name),
module_root: project.module_root(module_name.clone()),
module_name: project.module_name(module_name),
module_name,
template_generator: TemplateGenerator::new(
ODRA_TEMPLATE_GH_RAW_REPO.to_string(),
project.project_odra_location(),
Expand All @@ -57,14 +59,15 @@ impl GenerateAction<'_> {
&self.contract_name
}

/// Returns the module identifier. It is the struct name.
fn module_ident(&self) -> String {
/// Returns the contract identifier. It is the struct name.
fn contract_struct_name(&self) -> String {
let contract_name = self.contract_name();
contract_name.to_case(Case::UpperCamel)
to_camel_case(contract_name)
}

fn contract_snake_case(&self) -> String {
paths::to_snake_case(self.contract_name())
/// Returns the module name.
fn module_name(&self) -> String {
to_snake_case(self.contract_name())
}

/// Returns the module Ref identifier.
Expand All @@ -76,7 +79,7 @@ impl GenerateAction<'_> {
fn module_file_path(&self) -> PathBuf {
self.module_root
.join("src")
.join(self.contract_snake_case())
.join(self.module_name())
.with_extension("rs")
}

Expand All @@ -85,10 +88,10 @@ impl GenerateAction<'_> {
// Rename module name.
let contract_body = self
.template_generator
.module_template(&self.module_ident())
.module_template(&self.contract_struct_name())
.unwrap_or_else(|err| err.print_and_die());

// Make sure the file do not exists.
// Make sure the file do not exist.
let path = self.module_file_path();
if path.exists() {
Error::FileAlreadyExists(path).print_and_die();
Expand All @@ -103,7 +106,7 @@ impl GenerateAction<'_> {
// Prepare code to add.
let register_module_code = self
.template_generator
.register_module_snippet(&self.contract_snake_case(), &self.module_ident())
.register_module_snippet(&self.module_name(), &self.contract_struct_name())
.unwrap_or_else(|err| err.print_and_die());

// Read the file.
Expand All @@ -118,7 +121,8 @@ impl GenerateAction<'_> {

// Check if he file might have the module registered in another form.
if lib_rs.contains(self.contract_name())
|| (lib_rs.contains(&self.module_ident()) && lib_rs.contains(&self.module_ref_ident()))
|| (lib_rs.contains(&self.contract_struct_name())
&& lib_rs.contains(&self.module_ref_ident()))
{
log::warn(format!(
"src/lib.rs probably already has {} enabled. Skipping.",
Expand All @@ -137,23 +141,30 @@ impl GenerateAction<'_> {
/// Add contract definition to Odra.toml.
fn update_odra_toml(&self) {
let mut odra_toml = self.project.odra_toml();
let contract_name = self.module_ident();
let contract_name = self.contract_struct_name();

// Check if Odra.toml has already a contract.
let exists = odra_toml.has_contract(contract_name.as_str());
if exists {
Error::ContractAlreadyInOdraToml(contract_name).print_and_die();
}

let fqn = match self.module_name.clone() {
None => {
format!("{}::{}", self.module_name(), contract_name)
}
Some(module_name) => {
format!(
"{}::{}::{}",
self.project.crate_name(Some(module_name)),
self.contract_module_ident,
contract_name
)
}
};

// Add contract to Odra.toml.
odra_toml.contracts.push(Contract {
fqn: format!(
"{}::{}::{}",
self.module_name,
self.module_ident(),
self.module_ident()
),
});
odra_toml.contracts.push(Contract { fqn });

// Write to file.
odra_toml.save();
Expand Down
9 changes: 5 additions & 4 deletions src/actions/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use ureq::serde_json;

use crate::{
cli::InitCommand,
command::replace_in_file,
command::{rename_file, replace_in_file},
consts::{ODRA_GITHUB_API_DATA, ODRA_TEMPLATE_GH_REPO},
errors::Error,
log,
Expand Down Expand Up @@ -93,13 +93,13 @@ impl InitAction {
let cargo_toml_path = match init {
true => {
let mut path = current_dir;
path.push("Cargo.toml");
path.push("_Cargo.toml");
path
}
false => {
let mut path = current_dir;
path.push(paths::to_snake_case(&init_command.name));
path.push("Cargo.toml");
path.push("_Cargo.toml");
path
}
};
Expand All @@ -122,7 +122,7 @@ impl InitAction {
);

replace_in_file(
cargo_toml_path,
cargo_toml_path.clone(),
"#odra_test_dependency",
format!(
"odra-test = {{ {} }}",
Expand All @@ -138,6 +138,7 @@ impl InitAction {
.as_str(),
);

rename_file(cargo_toml_path, "Cargo.toml");
log::info("Done!");
}
fn assert_dir_is_empty(dir: PathBuf) {
Expand Down
2 changes: 1 addition & 1 deletion src/actions/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ impl SchemaAction<'_> {
command::cargo_generate_schema_files(
self.project.project_root(),
&contract.struct_name(),
&contract.crate_name(),
&contract.module_name(),
);
}
}
Expand Down
16 changes: 0 additions & 16 deletions src/actions/update.rs

This file was deleted.

3 changes: 2 additions & 1 deletion src/actions/utils.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{command, errors::Error, odra_toml::Contract, project::Project};
use crate::{command, errors::Error, odra_toml::Contract, paths::to_camel_case, project::Project};

/// Check if wasm32-unknown-unknown target is installed.
pub fn check_target_requirements() {
Expand Down Expand Up @@ -54,6 +54,7 @@ fn parse_contracts_names(names_string: String) -> Result<Vec<String>, &'static s
string
.split(' ')
.map(ToString::to_string)
.map(to_camel_case)
.collect::<Vec<_>>()
}),
}
Expand Down
7 changes: 0 additions & 7 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ use crate::{
init::InitAction,
schema::SchemaAction,
test::TestAction,
update::update_action,
},
consts,
errors::Error,
Expand Down Expand Up @@ -60,8 +59,6 @@ pub enum OdraSubcommand {
Generate(GenerateCommand),
/// Cleans all temporary data generated by cargo odra.
Clean(CleanCommand),
/// Updates project alongside builders.
Update(UpdateCommand),
/// Generates completions for given shell
Completions {
/// The shell to generate the completions for
Expand Down Expand Up @@ -171,10 +168,6 @@ pub fn make_action() {
let project = Project::detect(current_dir);
clean_action(&project);
}
OdraSubcommand::Update(update) => {
let project = Project::detect(current_dir);
update_action(update, project.project_root());
}
OdraSubcommand::Completions { shell } => {
shell.generate(&mut Cargo::command(), &mut std::io::stdout());
}
Expand Down
13 changes: 8 additions & 5 deletions src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,11 +142,6 @@ pub fn cargo_generate_schema_files(current_dir: PathBuf, contract_name: &str, mo
cargo(current_dir, "run", vec!["--bin", &gen_schema, "--release"]);
}

/// Update a cargo module.
pub fn cargo_update(current_dir: PathBuf) {
cargo(current_dir, "update", vec![]);
}

/// Runs cargo test.
pub fn cargo_test_mock_vm(current_dir: PathBuf, mut args: Vec<&str>) {
log::info("Running cargo test...");
Expand Down Expand Up @@ -194,6 +189,14 @@ pub fn replace_in_file(path: PathBuf, from: &str, to: &str) {
write_to_file(path, new_content.as_str());
}

/// Renames a file.
pub fn rename_file(path: PathBuf, new_name: &str) {
let mut new_path = path.clone();
new_path.pop();
new_path.push(new_name);
fs::rename(path, new_path).unwrap();
}

/// Loads a file to a string.
pub fn read_file_content(path: PathBuf) -> io::Result<String> {
fs::read_to_string(path)
Expand Down
4 changes: 4 additions & 0 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ pub enum Error {

#[error("Module {0} already in src/lib.rs")]
ModuleAlreadyInLibRs(String),

#[error("Project is a workspace, module name is required")]
ModuleNotProvided,
}

impl Error {
Expand Down Expand Up @@ -104,6 +107,7 @@ impl Error {
Error::LibRsNotFound => 22,
Error::ModuleAlreadyInLibRs(_) => 23,
Error::WasmoptDidNotFinish => 24,
Error::ModuleNotProvided => 25,
}
}

Expand Down
11 changes: 10 additions & 1 deletion src/odra_toml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use serde_derive::{Deserialize, Serialize};
use crate::{
command,
errors::{Error, Error::MalformedFqn},
project::Project,
};

/// Struct describing contract.
Expand All @@ -17,14 +18,22 @@ pub struct Contract {

impl Contract {
/// Extracts first part from fqn
pub fn crate_name(&self) -> String {
pub fn module_name(&self) -> String {
self.fqn
.split_terminator("::")
.next()
.unwrap_or_else(|| MalformedFqn.print_and_die())
.to_string()
}

pub fn crate_name(&self, project: &Project) -> String {
if project.is_workspace() {
self.module_name()
} else {
project.project_crate_name()
}
}

pub fn struct_name(&self) -> String {
self.fqn
.split_terminator("::")
Expand Down
Loading

0 comments on commit f9edb33

Please sign in to comment.