-
Notifications
You must be signed in to change notification settings - Fork 3
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
Changes from all commits
348dc92
d142870
be88ce3
24ec3df
b4f161c
7ecda5a
f6956df
64280da
a8802fb
cf02c96
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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") { | ||
|
@@ -112,6 +112,109 @@ 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"))?; | ||
|
||
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()?; | ||
Comment on lines
+206
to
+209
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this not tested in the integration test? There is a PtySession tool that can be used to test interactive processes using an example you look at is the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please forgive me - I'm not an expert in Rust CLI testing, though I am eager to learn. I'm having difficulty figuring out how to send the [ENTER] or [SPACE] keycodes to the command line with Ion's pty tool, which is required to step through the Templates' test interaction: just calling an empty There doesn't (currently) seem to be a way to send raw keycodes to Ion's Pty... Or is there something I'm missing? Or do I just need to dig deeper into and add to the Pty implementation so that we can send key codes as well as strings to the Pty session during testing? Thanks. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (p.s. I'll have fewer of these silly questions as I get more familiar with working on Ion's codebase. Thank you for your help as I get up to speed!) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Never mind - fixed it. I guess we can't use the Ctrl+M keycode to enter return keycodes for Dialoguer Select fields, but Ctrl+J works. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed with latest commit There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah it's the send control method, thanks! |
||
|
||
if let Some(template_name) = template_name { | ||
inspect_template(config, selection_options[template_name].to_owned())? | ||
}; | ||
|
||
Ok(()) | ||
} | ||
|
||
pub fn git_config_get(key: &str) -> Option<String> { | ||
let output = std::process::Command::new("git") | ||
.arg("config") | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
use super::*; | ||
use anyhow::{Ok, Result}; | ||
|
||
#[test] | ||
fn test_template() -> Result<()> { | ||
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(); | ||
|
||
// Test escape from input / Ctrl+C behaviour with `ion template inspect` (cf. ask_inspect_input fn) | ||
let mut p = Ion::new() | ||
.arg("template") | ||
.arg("inspect") | ||
.arg("nonce") | ||
.spawn(Some(30_000))?; | ||
|
||
p.send_control('c')?; | ||
p.exp_eof()?; | ||
|
||
Ok(())?; | ||
|
||
// Test nonce input | ||
let mut ps = Ion::new() | ||
.arg("template") | ||
.arg("inspect") | ||
.arg("nonce") | ||
.spawn(Some(5_000))?; | ||
|
||
ps.exp_string("Installed templates are:")?; | ||
|
||
// Send <ENTER> keycode to pty | ||
ps.send_control('j')?; | ||
ps.exp_string("name")?; | ||
ps.exp_eof()?; | ||
|
||
Ok(()) | ||
} |
There was a problem hiding this comment.
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.