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

feat: add ion template inspect command #11

Merged
merged 10 commits into from
Feb 16, 2023
Merged
Show file tree
Hide file tree
Changes from 4 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
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ion"
version = "0.1.14"
version = "0.1.15"
Roger-luo marked this conversation as resolved.
Show resolved Hide resolved
edition = "2021"
publish = false
authors = ["Roger Luo <[email protected]>"]
Expand Down
27 changes: 25 additions & 2 deletions src/bin/ion/commands/template.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use clap::parser::ArgMatches;
use clap::Command;
use ion::blueprints::list_templates;
use clap::{arg, Command};
use ion::blueprints::{
ask_inspect_template, inspect_all_templates, inspect_template, list_templates,
};
use ion::config::Config;
use ion::errors::CliResult;
use ion::template::RemoteTemplate;
Expand All @@ -10,6 +12,12 @@ pub fn cli() -> Command {
.about("template management")
.subcommand(Command::new("list").about("list all available templates"))
.subcommand(Command::new("update").about("update the templates from registry"))
.subcommand(
Command::new("inspect")
.about("inspect the contents of a template")
.arg(arg!([TEMPLATE] "Selects which template to print out"))
.arg(arg!(--"all" "Inspect all installed templates")),
)
.arg_required_else_help(true)
}

Expand All @@ -19,6 +27,21 @@ pub fn exec(config: &mut Config, matches: &ArgMatches) -> CliResult {
Some(("update", _)) => {
RemoteTemplate::new(config).download()?;
}
Some(("inspect", matches)) => {
// Iff a template name is provided, inspect template; otherwise, check for --all flag; if no --all, ask user to select template from list

match matches.get_one::<String>("TEMPLATE") {
Some(template) => inspect_template(config, template.to_owned())?,
None => {
let all_flag = matches.get_flag("all");
if all_flag {
inspect_all_templates(config)?;
} else {
ask_inspect_template(config)?;
}
}
};
}
_ => unreachable!(),
}
Ok(())
Expand Down
106 changes: 105 additions & 1 deletion src/ion/blueprints/utils.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::blueprints::*;
use crate::spec::Author;
use anyhow::{format_err, Error, Result};
use dialoguer::{Confirm, Input};
use dialoguer::{theme::ColorfulTheme, Confirm, Input, Select};

pub fn git_get_user() -> Result<(String, String)> {
let user = if let Some(name) = git_config_get("user.name") {
Expand Down Expand Up @@ -112,6 +112,110 @@ pub fn list_templates(config: &Config) -> Result<()> {
Ok(())
}

pub fn inspect_template(config: &Config, template_name: String) -> Result<()> {
let templates = config.template_dir().read_dir()?;

let mut template_found: bool = false;

for entry in templates {
let entry = match entry {
Ok(e) => e,
Err(e) => {
return Err(Error::new(e));
}
};

let path = entry.path();
if path.is_dir() {
let source = std::fs::read_to_string(path.join("template.toml"))?;

let template = match toml::from_str::<Template>(&source) {
Ok(t) => t,
Err(e) => {
return Err(format_err!("Error parsing template: {}", e));
}
};
if template.name == template_name {
template_found = true;
println!("{}", source);
}
}
}

// If the template the user requested is not in the list of downloaded templates, ask user to select existing template to inspect
if !template_found {
println!(
"The {} template was not found.\nInstalled templates are:",
template_name
);
ask_inspect_template(config)?
}
Ok(())
}

pub fn inspect_all_templates(config: &Config) -> Result<()> {
let templates = config.template_dir().read_dir()?;

for entry in templates {
let entry = match entry {
Ok(e) => e,
Err(e) => {
return Err(Error::new(e));
}
};

let path = entry.path();
if path.is_dir() {
let source = std::fs::read_to_string(path.join("template.toml"))?;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we probably should just provide a pretty-printing for Template so we can just use that here. But I think directly print the source is also good, we can improve it later.


println!("\n{}\n**********", source);
}
}
Ok(())
}

pub fn ask_inspect_template(config: &Config) -> Result<()> {
// Get selection options from installed templates
let mut selection_options = vec![];

let templates = config.template_dir().read_dir()?;
for entry in templates {
let entry = match entry {
Ok(e) => e,
Err(e) => {
return Err(Error::new(e));
}
};

let path = entry.path();
if path.is_dir() {
let source = std::fs::read_to_string(path.join("template.toml"))?;

let template = match toml::from_str::<Template>(&source) {
Ok(t) => t,
Err(e) => {
return Err(format_err!("Error parsing template: {}", e));
}
};

selection_options.push(template.name);
}
}

// Ask for template to print to console
let template_name = Select::with_theme(&ColorfulTheme::default())
.items(&selection_options)
.default(1)
.interact_opt()
.unwrap();

match template_name {
Some(index) => inspect_template(config, selection_options[index].to_owned())?,
_ => unreachable!(),
}
Ok(())
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be an if let Some(...) = ...? and the select error should be thrown to with ? to that user can exit without backtrace and exit code

}

pub fn git_config_get(key: &str) -> Option<String> {
let output = std::process::Command::new("git")
.arg("config")
Expand Down
1 change: 1 addition & 0 deletions tests/bin/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ pub mod clone;
pub mod new;
pub mod pkg;
pub mod script;
pub mod template;

pub mod utils;
pub use utils::*;
Expand Down
22 changes: 22 additions & 0 deletions tests/bin/template.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use super::*;

#[test]
fn test_template() {
Ion::new().arg("template").arg("list").assert().success();

Ion::new().arg("template").arg("update").assert().success();

Ion::new()
.arg("template")
.arg("inspect")
.arg("--all")
.assert()
.success();

Ion::new()
.arg("template")
.arg("inspect")
.arg("package")
.assert()
.success();
}