Skip to content

Commit

Permalink
Add CLI subcommand to get an item from the content directory.
Browse files Browse the repository at this point in the history
  • Loading branch information
mkantor committed Jun 11, 2020
1 parent e457aed commit 805d695
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 0 deletions.
108 changes: 108 additions & 0 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,33 @@ pub enum RenderCommandError {
WriteError { source: io::Error },
}

#[derive(Error, Debug)]
pub enum GetCommandError {
#[error("Unable to load content.")]
ContentLoadingError {
#[from]
source: ContentLoadingError,
},

#[error("Unable to parse template from content directory.")]
RegisteredTemplateParseError {
#[from]
source: RegisteredTemplateParseError,
},

#[error("Content not found at address '{}'.", .address)]
ContentNotFound { address: String },

#[error("Unable to render template.")]
TemplateRenderError {
#[from]
source: TemplateRenderError,
},

#[error("Failed to write output.")]
WriteError { source: io::Error },
}

/// Reads a template from `input`, renders it, and writes it to `output`.
pub fn render<I: io::Read, O: io::Write>(
content_directory_path: &Path,
Expand All @@ -58,6 +85,26 @@ pub fn render<I: io::Read, O: io::Write>(
Ok(())
}

/// Renders an item from the content directory and write it to `output`.
pub fn get<O: io::Write>(
content_directory_path: &Path,
address: &str,
gluon_version: GluonVersion,
output: &mut O,
) -> Result<(), GetCommandError> {
let engine = ContentEngine::from_content_directory(content_directory_path)?;
let content_item = engine
.get(address)
.ok_or(GetCommandError::ContentNotFound {
address: String::from(address),
})?;
let rendered_output = content_item.render(gluon_version)?;
write!(output, "{}", rendered_output)
.map_err(|source| GetCommandError::WriteError { source })?;

Ok(())
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down Expand Up @@ -113,4 +160,65 @@ mod tests {
);
}
}

#[test]
fn cli_can_get_content() {
let mut output = Vec::new();
let content_directory_path = &example_path("valid/hello-world");
let address = "hello";
let expected_output = "hello world\n";

let result = get(
content_directory_path,
address,
GluonVersion("0.0.0"),
&mut output,
);

assert!(
result.is_ok(),
"Template rendering failed for content at '{}' in '{}': {}",
address,
content_directory_path.to_string_lossy(),
result.unwrap_err(),
);
let output_as_str = str::from_utf8(output.as_slice()).expect("Output was not UTF-8");
assert_eq!(
output_as_str,
expected_output,
"Template rendering for content at '{}' in '{}' did not produce the expected output (\"{}\"), instead got \"{}\"",
address,
content_directory_path.to_string_lossy(),
expected_output,
output_as_str
);
}

#[test]
fn cli_can_fail_to_get_content_which_does_not_exist() {
let mut output = Vec::new();
let content_directory_path = &example_path("valid/hello-world");
let address = "this-address-does-not-refer-to-any-content";

let result = get(
content_directory_path,
address,
GluonVersion("0.0.0"),
&mut output,
);

match result {
Ok(_) => panic!(
"Getting content from '{}' succeeded, but it should have failed",
address
),
Err(GetCommandError::ContentNotFound {
address: address_from_error,
}) => assert_eq!(
address_from_error, address,
"Address from error did not match address used"
),
Err(_) => panic!("Wrong type of error was produced, expected ContentNotFound"),
};
}
}
17 changes: 17 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,18 @@ enum GluonCommand {
#[structopt(long, parse(from_os_str))]
content_directory: PathBuf,
},

/// Gets content from the content directory.
#[structopt(
after_help = "EXAMPLES:\n mkdir content && echo 'hello world' > content/hello.hbs && gluon get --content-directory=content --address=hello"
)]
Get {
#[structopt(long, parse(from_os_str))]
content_directory: PathBuf,

#[structopt(long)]
address: String,
},
}

fn handle_command<I: io::Read, O: io::Write>(
Expand All @@ -31,6 +43,11 @@ fn handle_command<I: io::Read, O: io::Write>(
GluonCommand::Render { content_directory } => {
cli::render(&content_directory, VERSION, input, output).map_err(anyhow::Error::from)
}

GluonCommand::Get {
content_directory,
address,
} => cli::get(&content_directory, &address, VERSION, output).map_err(anyhow::Error::from),
}
}

Expand Down

0 comments on commit 805d695

Please sign in to comment.