Skip to content

Commit

Permalink
List templates.
Browse files Browse the repository at this point in the history
  • Loading branch information
kubaplas committed May 16, 2024
1 parent 43347f9 commit b98c06d
Show file tree
Hide file tree
Showing 10 changed files with 133 additions and 70 deletions.
3 changes: 2 additions & 1 deletion src/actions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ pub mod generate;
pub mod init;
pub mod schema;
pub mod test;
mod utils;

pub mod list_templates;
3 changes: 1 addition & 2 deletions src/actions/build.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
//! Module for managing and building wasm files.
use super::utils;
use crate::{command, errors::Error, log, paths, project::Project};
use crate::{command, errors::Error, log, paths, project::Project, utils};

/// BuildAction configuration.
pub struct BuildAction<'a> {
Expand Down
49 changes: 5 additions & 44 deletions src/actions/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ use std::path::{Path, PathBuf};
use cargo_generate::{GenerateArgs, TemplatePath, Vcs};
use cargo_toml::{Dependency, DependencyDetail};
use chrono::Utc;
use ureq::serde_json;

use crate::{
cli::InitCommand,
command::{rename_file, replace_in_file},
consts::{ODRA_GITHUB_API_DATA, ODRA_TEMPLATE_GH_RAW_REPO, ODRA_TEMPLATE_GH_REPO},
consts::{ODRA_TEMPLATE_GH_RAW_REPO, ODRA_TEMPLATE_GH_REPO},
errors::Error,
log,
paths,
project::OdraLocation,
template::TemplateGenerator,
utils::odra_latest_version,
};

/// InitAction configuration.
Expand All @@ -31,7 +31,7 @@ impl InitAction {

log::info("Generating a new project...");

let odra_location = Self::odra_location(init_command.source);
let odra_location = OdraLocation::from_source(init_command.source);

let template_repository_path =
TemplateGenerator::new(ODRA_TEMPLATE_GH_RAW_REPO.to_string(), odra_location.clone())
Expand Down Expand Up @@ -74,14 +74,12 @@ impl InitAction {
},
};

dbg!("generating");

cargo_generate::generate(GenerateArgs {
template_path,
list_favorites: false,
name: Some(paths::to_snake_case(&init_command.name)),
force: true,
verbose: true,
verbose: false,
template_values_file: None,
silent: false,
config: None,
Expand All @@ -102,7 +100,6 @@ impl InitAction {
Error::FailedToGenerateProjectFromTemplate(e.to_string()).print_and_die();
});

dbg!("generating 2");
let cargo_toml_path = match init {
true => {
let mut path = current_dir;
Expand All @@ -117,7 +114,6 @@ impl InitAction {
}
};

dbg!("generating 3");
Self::replace_package_placeholder(
init,
&odra_location,
Expand Down Expand Up @@ -185,41 +181,6 @@ impl InitAction {
}
}

fn odra_location(source: Option<String>) -> OdraLocation {
let source = if let Some(source) = source {
source
} else {
Self::odra_latest_version()
};

// location on disk
let local = PathBuf::from(&source);
if local.exists() {
OdraLocation::Local(local)
} else {
// version
let version_regex = regex::Regex::new(r"^\d+\.\d+\.\d+$").unwrap();
if version_regex.is_match(&source) {
OdraLocation::CratesIO(source)
} else {
// branch
OdraLocation::Remote(ODRA_TEMPLATE_GH_REPO.to_string(), Some(source))
}
}
}
fn odra_latest_version() -> String {
let response: serde_json::Value = ureq::get(ODRA_GITHUB_API_DATA)
.call()
.unwrap_or_else(|_| {
Error::FailedToFetchTemplate(ODRA_GITHUB_API_DATA.to_string()).print_and_die()
})
.into_json()
.unwrap_or_else(|_| {
Error::FailedToParseTemplate(ODRA_GITHUB_API_DATA.to_string()).print_and_die()
});
response["tag_name"].as_str().unwrap().to_string()
}

fn odra_project_dependency(
odra_location: OdraLocation,
crate_name: &str,
Expand All @@ -240,7 +201,7 @@ impl InitAction {
(None, Some(path), None, None)
}
OdraLocation::Remote(repo, branch) => match branch {
None => (Some(Self::odra_latest_version()), None, None, None),
None => (Some(odra_latest_version()), None, None, None),
Some(branch) => (None, None, Some(repo), Some(branch)),
},
OdraLocation::CratesIO(version) => (Some(version), None, None, None),
Expand Down
33 changes: 33 additions & 0 deletions src/actions/list_templates.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//! Module responsible for listing templates in cli.
use crate::{
consts::ODRA_TEMPLATE_GH_RAW_REPO,
project::OdraLocation,
template::{TemplateGenerator, TemplateType},
};

/// ListTemplatesAction configuration.
#[derive(Clone)]
pub struct ListTemplatesAction {}

impl ListTemplatesAction {
pub fn list(odra_location: OdraLocation) {
let templates =
TemplateGenerator::new(ODRA_TEMPLATE_GH_RAW_REPO.to_string(), odra_location)
.fetch_templates();
println!("Available contract templates:");
templates
.iter()
.filter(|template| template.template_type == TemplateType::Contract)
.for_each(|template| {
println!("{:<15}{}", template.name, template.description);
});
println!("\nAvailable project templates:");
templates
.iter()
.filter(|template| template.template_type == TemplateType::Project)
.for_each(|template| {
println!("{:<15}{}", template.name, template.description);
});
}
}
3 changes: 1 addition & 2 deletions src/actions/schema.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
//! Module for generating contracts schema.
use super::utils;
use crate::{command, errors::Error, log, project::Project};
use crate::{command, errors::Error, log, project::Project, utils};

/// SchemaAction configuration.
pub struct SchemaAction<'a> {
Expand Down
24 changes: 18 additions & 6 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ use crate::{
clean::clean_action,
generate::GenerateAction,
init::InitAction,
list_templates::ListTemplatesAction,
schema::SchemaAction,
test::TestAction,
},
cargo_toml::load_cargo_toml,
consts,
errors::Error,
project::Project,
project::{OdraLocation, Project},
};

#[derive(Parser)]
Expand Down Expand Up @@ -60,7 +62,7 @@ pub enum OdraSubcommand {
/// Cleans all temporary data generated by cargo odra.
Clean(CleanCommand),
/// Lists all available templates.
ListTemplates,
ListTemplates(ListTemplatesCommand),
/// Generates completions for given shell
Completions {
/// The shell to generate the completions for
Expand Down Expand Up @@ -127,8 +129,9 @@ pub struct GenerateCommand {
/// Name of the module in which the contract will be created.
#[clap(value_parser, long, short)]
pub module: Option<String>,
/// Name of the template to use.
#[clap(value_parser, long, short)]
/// Template to use.
/// To see all available templates, run `cargo odra list-templates`.
#[clap(value_parser, long, short, default_value = consts::MODULE_TEMPLATE)]
pub template: Option<String>,
}

Expand Down Expand Up @@ -192,8 +195,17 @@ pub fn make_action() {
let project = Project::detect(current_dir);
SchemaAction::new(&project, schema.contracts_names).build();
}
OdraSubcommand::ListTemplates => {
println!("Available templates:");
OdraSubcommand::ListTemplates(list) => {
let cargo_toml = Project::find_odra_cargo_toml(current_dir.clone());
let odra_location = match cargo_toml {
None => OdraLocation::from_source(list.source),
Some(cargo_toml_path) => match list.source {
None => OdraLocation::from_project(load_cargo_toml(&cargo_toml_path)),
Some(source) => OdraLocation::from_source(Some(source)),
},
};

ListTemplatesAction::list(odra_location);
}
}
}
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ mod odra_toml;
mod paths;
mod project;
mod template;
mod utils;
61 changes: 48 additions & 13 deletions src/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,15 @@ use std::{
path::{Path, PathBuf},
};

use cargo_toml::{Dependency, DependencyDetail};
use cargo_toml::{Dependency, DependencyDetail, Manifest};

use crate::{cargo_toml::load_cargo_toml, errors::Error, odra_toml::OdraToml};
use crate::{
cargo_toml::load_cargo_toml,
consts::ODRA_TEMPLATE_GH_REPO,
errors::Error,
odra_toml::OdraToml,
utils::odra_latest_version,
};

/// Struct representing the whole project.
#[derive(Debug, Clone)]
Expand All @@ -28,7 +34,7 @@ impl Project {
let odra_toml_path = Self::find_odra_toml(path.clone()).unwrap_or_else(|| {
Error::NotAnOdraProject.print_and_die();
});
let cargo_toml_path = Self::find_cargo_toml(path).unwrap_or_else(|| {
let cargo_toml_path = Self::find_odra_cargo_toml(path).unwrap_or_else(|| {
Error::NotAnOdraProject.print_and_die();
});
let root = odra_toml_path.parent().unwrap().to_path_buf();
Expand Down Expand Up @@ -99,7 +105,8 @@ impl Project {
}

/// Searches for main Projects' Cargo.toml.
pub fn find_cargo_toml(path: PathBuf) -> Option<PathBuf> {
/// Ensures that the project is an Odra project.
pub fn find_odra_cargo_toml(path: PathBuf) -> Option<PathBuf> {
match Self::find_file_upwards("Odra.toml", path) {
None => None,
Some(odra_toml_path) => {
Expand Down Expand Up @@ -136,7 +143,7 @@ impl Project {
.collect()
}

fn find_odra_toml(path: PathBuf) -> Option<PathBuf> {
pub fn find_odra_toml(path: PathBuf) -> Option<PathBuf> {
Self::find_file_upwards("Odra.toml", path)
}

Expand Down Expand Up @@ -169,7 +176,20 @@ impl Project {
}

pub fn project_odra_location(&self) -> OdraLocation {
let cargo_toml = load_cargo_toml(&self.cargo_toml_location);
OdraLocation::from_project(load_cargo_toml(&self.cargo_toml_location))
}
}

#[derive(Debug, Clone)]
pub enum OdraLocation {
Local(PathBuf),
/// git repo, branch
Remote(String, Option<String>),
CratesIO(String),
}

impl OdraLocation {
pub fn from_project(cargo_toml: Manifest) -> OdraLocation {
let dependencies = match cargo_toml.workspace {
None => cargo_toml.dependencies,
Some(workspace) => workspace.dependencies,
Expand Down Expand Up @@ -212,14 +232,29 @@ impl Project {
}
}
}
}

#[derive(Debug, Clone)]
pub enum OdraLocation {
Local(PathBuf),
/// git repo, branch
Remote(String, Option<String>),
CratesIO(String),
pub fn from_source(source: Option<String>) -> OdraLocation {
let source = if let Some(source) = source {
source
} else {
odra_latest_version()
};

// location on disk
let local = PathBuf::from(&source);
if local.exists() {
OdraLocation::Local(local)
} else {
// version
let version_regex = regex::Regex::new(r"^\d+\.\d+\.\d+$").unwrap();
if version_regex.is_match(&source) {
OdraLocation::CratesIO(source)
} else {
// branch
OdraLocation::Remote(ODRA_TEMPLATE_GH_REPO.to_string(), Some(source))
}
}
}
}

#[derive(Debug, Clone)]
Expand Down
2 changes: 1 addition & 1 deletion src/template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ impl TemplateGenerator {
}

/// Fetches templates.json
fn fetch_templates(&self) -> Vec<Template> {
pub fn fetch_templates(&self) -> Vec<Template> {
match self.odra_location.clone() {
OdraLocation::Local(path) => {
let path = path.join(TEMPLATES_JSON_PATH);
Expand Down
24 changes: 23 additions & 1 deletion src/actions/utils.rs → src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
use crate::{command, errors::Error, odra_toml::Contract, paths::to_camel_case, project::Project};
use ureq::serde_json;

use crate::{
command,
consts::ODRA_GITHUB_API_DATA,
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 @@ -59,3 +68,16 @@ fn parse_contracts_names(names_string: String) -> Result<Vec<String>, &'static s
}),
}
}

pub fn odra_latest_version() -> String {
let response: serde_json::Value = ureq::get(ODRA_GITHUB_API_DATA)
.call()
.unwrap_or_else(|_| {
Error::FailedToFetchTemplate(ODRA_GITHUB_API_DATA.to_string()).print_and_die()
})
.into_json()
.unwrap_or_else(|_| {
Error::FailedToParseTemplate(ODRA_GITHUB_API_DATA.to_string()).print_and_die()
});
response["tag_name"].as_str().unwrap().to_string()
}

0 comments on commit b98c06d

Please sign in to comment.