Skip to content

Convert project to use RelativePath where appropriate. #597

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

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ tempdir = "0.3.4"
itertools = "0.7"
shlex = "0.1"
toml-query = "0.6"
relative-path = { version = "0.3", features = ["serde"] }

# Watch feature
notify = { version = "4.0", optional = true }
Expand Down
56 changes: 26 additions & 30 deletions src/book/book.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use std::fmt::{self, Display, Formatter};
use std::path::{Path, PathBuf};
use std::path::{Path};
use std::collections::VecDeque;
use std::fs::{self, File};
use std::io::{Read, Write};

use super::summary::{parse_summary, Link, SectionNumber, Summary, SummaryItem};
use config::BuildConfig;
use errors::*;
use relative_path::RelativePathBuf;

/// Load a book into memory from its `src/` directory.
pub fn load_book<P: AsRef<Path>>(src_dir: P, cfg: &BuildConfig) -> Result<Book> {
Expand Down Expand Up @@ -39,7 +40,8 @@ fn create_missing(src_dir: &Path, summary: &Summary) -> Result<()> {
let next = items.pop().expect("already checked");

if let SummaryItem::Link(ref link) = *next {
let filename = src_dir.join(&link.location);
let filename = link.location.to_path(src_dir);

if !filename.exists() {
if let Some(parent) = filename.parent() {
if !parent.exists() {
Expand Down Expand Up @@ -150,13 +152,15 @@ pub struct Chapter {
pub number: Option<SectionNumber>,
/// Nested items.
pub sub_items: Vec<BookItem>,
/// The chapter's location, relative to the `SUMMARY.md` file.
pub path: PathBuf,
/// The chapter's relative location.
pub path: RelativePathBuf,
}

impl Chapter {
/// Create a new chapter with the provided content.
pub fn new<P: Into<PathBuf>>(name: &str, content: String, path: P) -> Chapter {
pub fn new<P: Into<RelativePathBuf>>(
name: &str, content: String, path: P,
) -> Chapter {
Chapter {
name: name.to_string(),
content: content,
Expand Down Expand Up @@ -201,24 +205,16 @@ fn load_chapter<P: AsRef<Path>>(link: &Link, src_dir: P) -> Result<Chapter> {
debug!("Loading {} ({})", link.name, link.location.display());
let src_dir = src_dir.as_ref();

let location = if link.location.is_absolute() {
link.location.clone()
} else {
src_dir.join(&link.location)
};
let location = &link.location;

let mut f = File::open(&location)
let mut f = File::open(location.to_path(src_dir))
.chain_err(|| format!("Chapter file not found, {}", link.location.display()))?;

let mut content = String::new();
f.read_to_string(&mut content)
.chain_err(|| format!("Unable to read \"{}\" ({})", link.name, location.display()))?;

let stripped = location
.strip_prefix(&src_dir)
.expect("Chapters are always inside a book");

let mut ch = Chapter::new(&link.name, content, stripped);
let mut ch = Chapter::new(&link.name, content, &link.location);
ch.number = link.number.clone();

let sub_items = link.nested_items
Expand Down Expand Up @@ -289,8 +285,9 @@ And here is some \
fn dummy_link() -> (Link, TempDir) {
let temp = TempDir::new("book").unwrap();

let chapter_path = temp.path().join("chapter_1.md");
File::create(&chapter_path)
let chapter_path = RelativePathBuf::from("chapter_1.md");

File::create(&chapter_path.to_path(temp.path()))
.unwrap()
.write(DUMMY_SRC.as_bytes())
.unwrap();
Expand All @@ -304,9 +301,9 @@ And here is some \
fn nested_links() -> (Link, TempDir) {
let (mut root, temp_dir) = dummy_link();

let second_path = temp_dir.path().join("second.md");
let second_path = RelativePathBuf::from("second.md");

File::create(&second_path)
File::create(&second_path.to_path(&temp_dir))
.unwrap()
.write_all("Hello World!".as_bytes())
.unwrap();
Expand All @@ -332,7 +329,7 @@ And here is some \

#[test]
fn cant_load_a_nonexistent_chapter() {
let link = Link::new("Chapter 1", "/foo/bar/baz.md");
let link = Link::new("Chapter 1", "foo/bar/baz.md");

let got = load_chapter(&link, "");
assert!(got.is_err());
Expand All @@ -346,14 +343,14 @@ And here is some \
name: String::from("Nested Chapter 1"),
content: String::from("Hello World!"),
number: Some(SectionNumber(vec![1, 2])),
path: PathBuf::from("second.md"),
path: RelativePathBuf::from("second.md"),
sub_items: Vec::new(),
};
let should_be = BookItem::Chapter(Chapter {
name: String::from("Chapter 1"),
content: String::from(DUMMY_SRC),
number: None,
path: PathBuf::from("chapter_1.md"),
path: RelativePathBuf::from("chapter_1.md"),
sub_items: vec![
BookItem::Chapter(nested.clone()),
BookItem::Separator,
Expand All @@ -377,7 +374,7 @@ And here is some \
BookItem::Chapter(Chapter {
name: String::from("Chapter 1"),
content: String::from(DUMMY_SRC),
path: PathBuf::from("chapter_1.md"),
path: RelativePathBuf::from("chapter_1.md"),
..Default::default()
}),
],
Expand Down Expand Up @@ -416,7 +413,7 @@ And here is some \
name: String::from("Chapter 1"),
content: String::from(DUMMY_SRC),
number: None,
path: PathBuf::from("Chapter_1/index.md"),
path: RelativePathBuf::from("Chapter_1/index.md"),
sub_items: vec![
BookItem::Chapter(Chapter::new(
"Hello World",
Expand Down Expand Up @@ -463,7 +460,7 @@ And here is some \
name: String::from("Chapter 1"),
content: String::from(DUMMY_SRC),
number: None,
path: PathBuf::from("Chapter_1/index.md"),
path: RelativePathBuf::from("Chapter_1/index.md"),
sub_items: vec![
BookItem::Chapter(Chapter::new(
"Hello World",
Expand Down Expand Up @@ -497,7 +494,7 @@ And here is some \
numbered_chapters: vec![
SummaryItem::Link(Link {
name: String::from("Empty"),
location: PathBuf::from(""),
location: RelativePathBuf::from(""),
..Default::default()
}),
],
Expand All @@ -511,14 +508,13 @@ And here is some \
#[test]
fn cant_load_chapters_when_the_link_is_a_directory() {
let (_, temp) = dummy_link();
let dir = temp.path().join("nested");
fs::create_dir(&dir).unwrap();
fs::create_dir(temp.path().join("nested")).unwrap();

let summary = Summary {
numbered_chapters: vec![
SummaryItem::Link(Link {
name: String::from("nested"),
location: dir,
location: RelativePathBuf::from("nested"),
..Default::default()
}),
],
Expand Down
6 changes: 3 additions & 3 deletions src/book/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,13 +221,13 @@ impl MDBook {

for item in self.iter() {
if let BookItem::Chapter(ref ch) = *item {
if !ch.path.as_os_str().is_empty() {
let path = self.source_dir().join(&ch.path);
if !ch.path.as_str().is_empty() {
let path = ch.path.to_path(self.source_dir());
let content = utils::fs::file_to_string(&path)?;
info!("Testing file: {:?}", path);

// write preprocessed file to tempdir
let path = temp_dir.path().join(&ch.path);
let path = ch.path.to_path(temp_dir.path());
let mut tmpf = utils::fs::create_file(&path)?;
tmpf.write_all(content.as_bytes())?;

Expand Down
30 changes: 15 additions & 15 deletions src/book/summary.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use std::fmt::{self, Display, Formatter};
use std::iter::FromIterator;
use std::ops::{Deref, DerefMut};
use std::path::{Path, PathBuf};
use memchr::{self, Memchr};
use pulldown_cmark::{self, Alignment, Event, Tag};
use relative_path::{RelativePath, RelativePathBuf};
use errors::*;

/// Parse the text from a `SUMMARY.md` file into a sort of "recipe" to be
Expand Down Expand Up @@ -71,7 +71,7 @@ pub struct Link {
pub name: String,
/// The location of the chapter's source file, taking the book's `src`
/// directory as the root.
pub location: PathBuf,
pub location: RelativePathBuf,
/// The section number, if this chapter is in the numbered section.
pub number: Option<SectionNumber>,
/// Any nested items this chapter may contain.
Expand All @@ -80,10 +80,10 @@ pub struct Link {

impl Link {
/// Create a new link with no nested items.
pub fn new<S: Into<String>, P: AsRef<Path>>(name: S, location: P) -> Link {
pub fn new<S: Into<String>, P: AsRef<RelativePath>>(name: S, location: P) -> Link {
Link {
name: name.into(),
location: location.as_ref().to_path_buf(),
location: location.as_ref().to_relative_path_buf(),
number: None,
nested_items: Vec::new(),
}
Expand All @@ -94,7 +94,7 @@ impl Default for Link {
fn default() -> Self {
Link {
name: String::new(),
location: PathBuf::new(),
location: RelativePathBuf::new(),
number: None,
nested_items: Vec::new(),
}
Expand Down Expand Up @@ -277,7 +277,7 @@ impl<'a> SummaryParser<'a> {
} else {
Ok(Link {
name: name,
location: PathBuf::from(href.to_string()),
location: RelativePathBuf::from(href.to_string()),
number: None,
nested_items: Vec::new(),
})
Expand Down Expand Up @@ -617,12 +617,12 @@ mod tests {
let should_be = vec![
SummaryItem::Link(Link {
name: String::from("First"),
location: PathBuf::from("./first.md"),
location: RelativePathBuf::from("./first.md"),
..Default::default()
}),
SummaryItem::Link(Link {
name: String::from("Second"),
location: PathBuf::from("./second.md"),
location: RelativePathBuf::from("./second.md"),
..Default::default()
}),
];
Expand Down Expand Up @@ -661,7 +661,7 @@ mod tests {
let src = "[First](./first.md)";
let should_be = Link {
name: String::from("First"),
location: PathBuf::from("./first.md"),
location: RelativePathBuf::from("./first.md"),
..Default::default()
};

Expand All @@ -682,7 +682,7 @@ mod tests {
let src = "- [First](./first.md)\n";
let link = Link {
name: String::from("First"),
location: PathBuf::from("./first.md"),
location: RelativePathBuf::from("./first.md"),
number: Some(SectionNumber(vec![1])),
..Default::default()
};
Expand All @@ -703,20 +703,20 @@ mod tests {
let should_be = vec![
SummaryItem::Link(Link {
name: String::from("First"),
location: PathBuf::from("./first.md"),
location: RelativePathBuf::from("./first.md"),
number: Some(SectionNumber(vec![1])),
nested_items: vec![
SummaryItem::Link(Link {
name: String::from("Nested"),
location: PathBuf::from("./nested.md"),
location: RelativePathBuf::from("./nested.md"),
number: Some(SectionNumber(vec![1, 1])),
nested_items: Vec::new(),
}),
],
}),
SummaryItem::Link(Link {
name: String::from("Second"),
location: PathBuf::from("./second.md"),
location: RelativePathBuf::from("./second.md"),
number: Some(SectionNumber(vec![2])),
nested_items: Vec::new(),
}),
Expand All @@ -740,13 +740,13 @@ mod tests {
let should_be = vec![
SummaryItem::Link(Link {
name: String::from("First"),
location: PathBuf::from("./first.md"),
location: RelativePathBuf::from("./first.md"),
number: Some(SectionNumber(vec![1])),
nested_items: Vec::new(),
}),
SummaryItem::Link(Link {
name: String::from("Second"),
location: PathBuf::from("./second.md"),
location: RelativePathBuf::from("./second.md"),
number: Some(SectionNumber(vec![2])),
nested_items: Vec::new(),
}),
Expand Down
5 changes: 3 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ extern crate shlex;
extern crate tempdir;
extern crate toml;
extern crate toml_query;
extern crate relative_path;

#[cfg(test)]
#[macro_use]
Expand All @@ -114,7 +115,7 @@ pub use config::Config;

/// The error types used through out this crate.
pub mod errors {
use std::path::PathBuf;
use relative_path::RelativePathBuf;

error_chain!{
foreign_links {
Expand Down Expand Up @@ -142,7 +143,7 @@ pub mod errors {
}

/// The user tried to use a reserved filename.
ReservedFilenameError(filename: PathBuf) {
ReservedFilenameError(filename: RelativePathBuf) {
description("Reserved Filename")
display("{} is reserved for internal use", filename.display())
}
Expand Down
6 changes: 3 additions & 3 deletions src/preprocess/links.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ impl Preprocessor for LinkPreprocessor {

book.for_each_mut(|section: &mut BookItem| {
if let BookItem::Chapter(ref mut ch) = *section {
let base = ch.path
let base = ch.path.to_path(&src_dir)
.parent()
.map(|dir| src_dir.join(dir))
.expect("All book items have a parent");
.expect("All book items have a parent")
.to_owned();

let content = replace_all(&ch.content, base);
ch.content = content;
Expand Down
Loading