Skip to content

Commit

Permalink
Add crate *version* to a template generator (#20)
Browse files Browse the repository at this point in the history
* Add crate *version* to a template generator

* Update `README`, add integration tests for a *vesrion**

.. also fix a typo in the `lib.rs` (hence in `README.md` as well)

* Minor changes to the description
  • Loading branch information
mexus authored and livioribeiro committed Sep 17, 2018
1 parent c61a9ee commit d0301c1
Show file tree
Hide file tree
Showing 9 changed files with 78 additions and 14 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ cargo install cargo-readme

As you write documentation, you often have to show examples of how to use your software. But
how do you make sure your examples are all working properly? That we didn't forget to update
them after a braking change and left our (possibly new) users with errors they will have to
them after a breaking change and left our (possibly new) users with errors they will have to
figure out by themselves?

With `cargo-readme`, you just write the rustdoc, run the tests, and then run:
Expand Down Expand Up @@ -105,6 +105,8 @@ content:
{{readme}}
Current version: {{version}}
Some additional info here
License: {{license}}
Expand All @@ -117,6 +119,8 @@ The output will look like this

# my_crate

Current version: 3.0.0

This is my awesome crate

Here goes some other description of what it is and what is does
Expand Down
5 changes: 4 additions & 1 deletion src/config/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ pub struct Manifest {
pub lib: Option<ManifestLib>,
pub bin: Vec<ManifestLib>,
pub badges: Vec<String>,
pub version: String,
}

impl Manifest {
Expand All @@ -49,7 +50,8 @@ impl Manifest {
}).unwrap_or_default(),
badges: cargo_toml.badges
.map(|b| process_badges(b))
.unwrap_or_default()
.unwrap_or_default(),
version: cargo_toml.package.version,
}
}
}
Expand Down Expand Up @@ -103,6 +105,7 @@ struct CargoToml {
struct CargoTomlPackage {
pub name: String,
pub license: Option<String>,
pub version: String,
}

/// Cargo.toml crate lib information
Expand Down
6 changes: 5 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
//!
//! As you write documentation, you often have to show examples of how to use your software. But
//! how do you make sure your examples are all working properly? That we didn't forget to update
//! them after a braking change and left our (possibly new) users with errors they will have to
//! them after a breaking change and left our (possibly new) users with errors they will have to
//! figure out by themselves?
//!
//! With `cargo-readme`, you just write the rustdoc, run the tests, and then run:
Expand Down Expand Up @@ -101,6 +101,8 @@
//!
//! {{readme}}
//!
//! Current version: {{version}}
//!
//! Some additional info here
//!
//! License: {{license}}
Expand All @@ -113,6 +115,8 @@
//!
//! # my_crate
//!
//! Current version: 3.0.0
//!
//! This is my awesome crate
//!
//! Here goes some other description of what it is and what is does
Expand Down
36 changes: 25 additions & 11 deletions src/readme/template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ pub fn render(

let license: Option<&str> = cargo.license.as_ref().map(AsRef::as_ref);

let version: &str = cargo.version.as_ref();

if let Some(template) = template {
process_template(template, readme, title, badges, license)
process_template(template, readme, title, badges, license, version)
} else {
process_string(readme, title, badges, license, add_title, add_badges, add_license)
}
Expand All @@ -32,12 +34,14 @@ pub fn render(
/// - `{{crate}}` crate name defined in `Cargo.toml`
/// - `{{badges}}` badges defined in `Cargo.toml`
/// - `{{license}}` license defined in `Cargo.toml`
/// - `{{version}}` version defined in `Cargo.toml`
fn process_template(
mut template: String,
readme: String,
title: &str,
badges: &[&str],
license: Option<&str>,
version: &str,
) -> Result<String, String> {

template = template.trim_right_matches("\n").to_owned();
Expand Down Expand Up @@ -70,6 +74,8 @@ fn process_template(
}
}

template = template.replace("{{version}}", version);

let result = template.replace("{{readme}}", &readme);
Ok(result)
}
Expand Down Expand Up @@ -133,63 +139,71 @@ mod tests {
const TEMPLATE_WITH_TITLE: &str = "# {{crate}}\n\n{{readme}}";
const TEMPLATE_WITH_BADGES: &str = "{{badges}}\n\n{{readme}}";
const TEMPLATE_WITH_LICENSE: &str = "{{readme}}\n\n{{license}}";
const TEMPLATE_FULL: &str = "{{badges}}\n\n# {{crate}}\n\n{{readme}}\n\n{{license}}";
const TEMPLATE_WITH_VERSION: &str = "{{readme}}\n\n{{version}}";
const TEMPLATE_FULL: &str = "{{badges}}\n\n# {{crate}}\n\n{{readme}}\n\n{{license}}\n\n{{version}}";

// process template
#[test]
fn template_without_readme_should_fail() {
let result = super::process_template(String::new(), String::new(), "", &[], None);
let result = super::process_template(String::new(), String::new(), "", &[], None, "");
assert!(result.is_err());
assert_eq!("Missing `{{readme}}` in template", result.unwrap_err());
}

#[test]
fn template_with_badge_tag_but_missing_badges_should_fail() {
let result = super::process_template(TEMPLATE_WITH_BADGES.to_owned(), String::new(), "", &[], None);
let result = super::process_template(TEMPLATE_WITH_BADGES.to_owned(), String::new(), "", &[], None, "");
assert!(result.is_err());
assert_eq!("`{{badges}}` was found in template but no badges were provided", result.unwrap_err());
}

#[test]
fn template_with_license_tag_but_missing_license_should_fail() {
let result = super::process_template(TEMPLATE_WITH_LICENSE.to_owned(), String::new(), "", &[], None);
let result = super::process_template(TEMPLATE_WITH_LICENSE.to_owned(), String::new(), "", &[], None, "");
assert!(result.is_err());
assert_eq!("`{{license}}` was found in template but no license was provided", result.unwrap_err());
}

#[test]
fn template_minimal() {
let result = super::process_template(TEMPLATE_MINIMAL.to_owned(), "readme".to_owned(), "", &[], None);
let result = super::process_template(TEMPLATE_MINIMAL.to_owned(), "readme".to_owned(), "", &[], None, "");
assert!(result.is_ok());
assert_eq!("readme", result.unwrap());
}

#[test]
fn template_with_title() {
let result = super::process_template(TEMPLATE_WITH_TITLE.to_owned(), "readme".to_owned(), "title", &[], None);
let result = super::process_template(TEMPLATE_WITH_TITLE.to_owned(), "readme".to_owned(), "title", &[], None, "");
assert!(result.is_ok());
assert_eq!("# title\n\nreadme", result.unwrap());
}

#[test]
fn template_with_badges() {
let result = super::process_template(TEMPLATE_WITH_BADGES.to_owned(), "readme".to_owned(), "", &["badge1", "badge2"], None);
let result = super::process_template(TEMPLATE_WITH_BADGES.to_owned(), "readme".to_owned(), "", &["badge1", "badge2"], None, "");
assert!(result.is_ok());
assert_eq!("badge1\nbadge2\n\nreadme", result.unwrap());
}

#[test]
fn template_with_license() {
let result = super::process_template(TEMPLATE_WITH_LICENSE.to_owned(), "readme".to_owned(), "", &[], Some("license"));
let result = super::process_template(TEMPLATE_WITH_LICENSE.to_owned(), "readme".to_owned(), "", &[], Some("license"), "");
assert!(result.is_ok());
assert_eq!("readme\n\nlicense", result.unwrap());
}

#[test]
fn template_with_version() {
let result = super::process_template(TEMPLATE_WITH_VERSION.to_owned(), "readme".to_owned(), "", &[], None, "3.0.1");
assert!(result.is_ok());
assert_eq!("readme\n\n3.0.1", result.unwrap());
}

#[test]
fn template_full() {
let result = super::process_template(TEMPLATE_FULL.to_owned(), "readme".to_owned(), "title", &["badge1", "badge2"], Some("license"));
let result = super::process_template(TEMPLATE_FULL.to_owned(), "readme".to_owned(), "title", &["badge1", "badge2"], Some("license"), "3.0.2");
assert!(result.is_ok());
assert_eq!("badge1\nbadge2\n\n# title\n\nreadme\n\nlicense", result.unwrap());
assert_eq!("badge1\nbadge2\n\n# title\n\nreadme\n\nlicense\n\n3.0.2", result.unwrap());
}

// process string
Expand Down
26 changes: 26 additions & 0 deletions tests/project-with-version.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
extern crate assert_cli;

use assert_cli::Assert;

const EXPECTED: &str = "# project-with-version
Current version: 0.1.0
A test project with a version provided.";

#[test]
fn template_with_version() {
let args = [
"readme",
"--project-root",
"tests/project-with-version",
"--template",
"README.tpl",
];

Assert::main_binary()
.with_args(&args)
.succeeds()
.and().stdout().is(EXPECTED)
.unwrap();
}
1 change: 1 addition & 0 deletions tests/project-with-version/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Cargo.lock
6 changes: 6 additions & 0 deletions tests/project-with-version/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[package]
name = "project-with-version"
version = "0.1.0"
authors = ["mexus <[email protected]>"]

[dependencies]
5 changes: 5 additions & 0 deletions tests/project-with-version/README.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# {{crate}}

Current version: {{version}}

{{readme}}
1 change: 1 addition & 0 deletions tests/project-with-version/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
//! A test project with a version provided.

0 comments on commit d0301c1

Please sign in to comment.