diff --git a/Cargo.lock b/Cargo.lock index 7101fdae94..22acd88dc0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -221,6 +221,7 @@ version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" dependencies = [ + "jobserver", "libc", ] @@ -591,6 +592,21 @@ version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +[[package]] +name = "git2" +version = "0.18.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "232e6a7bfe35766bf715e55a88b39a700596c0ccfd88cd3680b4cdb40d66ef70" +dependencies = [ + "bitflags 2.4.2", + "libc", + "libgit2-sys", + "log", + "openssl-probe", + "openssl-sys", + "url", +] + [[package]] name = "globset" version = "0.4.14" @@ -836,6 +852,15 @@ version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +[[package]] +name = "jobserver" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6" +dependencies = [ + "libc", +] + [[package]] name = "js-sys" version = "0.3.67" @@ -871,6 +896,20 @@ version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +[[package]] +name = "libgit2-sys" +version = "0.16.2+1.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee4126d8b4ee5c9d9ea891dd875cfdc1e9d0950437179104b183d7d8a74d24e8" +dependencies = [ + "cc", + "libc", + "libssh2-sys", + "libz-sys", + "openssl-sys", + "pkg-config", +] + [[package]] name = "libredox" version = "0.0.1" @@ -882,6 +921,32 @@ dependencies = [ "redox_syscall", ] +[[package]] +name = "libssh2-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dc8a030b787e2119a731f1951d6a773e2280c660f8ec4b0f5e1505a386e71ee" +dependencies = [ + "cc", + "libc", + "libz-sys", + "openssl-sys", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "libz-sys" +version = "1.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e143b5e666b2695d28f6bca6497720813f699c9602dd7f5cac91008b8ada7f9" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "linux-raw-sys" version = "0.4.13" @@ -955,6 +1020,7 @@ dependencies = [ "elasticlunr-rs", "env_logger", "futures-util", + "git2", "handlebars", "ignore", "log", @@ -1121,6 +1187,24 @@ dependencies = [ "winapi", ] +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dda2b0f344e78efc2facf7d195d098df0dd72151b26ab98da807afc26c198dff" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "parking_lot" version = "0.12.1" @@ -1271,6 +1355,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -1945,6 +2035,12 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.4" diff --git a/Cargo.toml b/Cargo.toml index 61a3b66e5a..c0046203ef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,6 +36,7 @@ tempfile = "3.4.0" toml = "0.5.11" # Do not update, see https://github.com/rust-lang/mdBook/issues/2037 topological-sort = "0.2.2" resolve-path = "0.1.0" +git2 = "0.18.3" # Watch feature notify = { version = "6.1.1", optional = true } diff --git a/src/cmd/shelf.rs b/src/cmd/shelf.rs index 6df8a0eacc..78d746b606 100644 --- a/src/cmd/shelf.rs +++ b/src/cmd/shelf.rs @@ -15,11 +15,12 @@ pub fn make_subcommand() -> Command { Command::new("shelf").about("Build a bookshelf from shelf.toml file") } -fn build_book(path: &str) -> Result<()> { +fn process_book(path: &str, index_file: &mut File, summary: &mut File) -> Result<()> { let book_dir = path.try_resolve()?; let book_dir = std::fs::canonicalize(book_dir)?; - println!("{book_dir:?}"); let mut book = MDBook::load(book_dir)?; + + // Build book let mut path = current_dir()?; let title = book.config.book.title.clone().unwrap(); path.push("books/"); @@ -27,13 +28,6 @@ fn build_book(path: &str) -> Result<()> { book.config.build.build_dir = path; book.config.book.shelf_url = Some(PathBuf::from(r"../../shelf/book/index.html")); book.build()?; - Ok(()) -} - -fn process_book(path: &str, index_file: &mut File, summary: &mut File) -> Result<()> { - let book_dir = path.try_resolve()?; - let book_dir = std::fs::canonicalize(book_dir)?; - let book = MDBook::load(book_dir)?; // Create post in index file let title = book.config.book.title.unwrap_or_default(); @@ -62,12 +56,7 @@ pub fn execute(_args: &ArgMatches) -> Result<()> { let mut contents = String::new(); file.read_to_string(&mut contents)?; let shelf: Shelf = toml::from_str(&contents)?; - if let Some(local) = &shelf.book.local { - for sb in local { - println!("{:?}", sb); - build_book(&sb.path)?; - } - } + let _ = std::fs::remove_dir_all("shelf"); let _ = MDBook::init("shelf").create_gitignore(false).build(); @@ -79,10 +68,37 @@ pub fn execute(_args: &ArgMatches) -> Result<()> { writeln!(index_file, "# Bookshelf")?; writeln!(index_file)?; - if let Some(local) = &shelf.book.local { - for sb in local { + + for sb in &shelf.book { + if let Some(url) = &sb.git_url { println!("{:?}", sb); - process_book(&sb.path, &mut index_file, &mut summary)? + let path = sb.path.clone().unwrap_or("root".to_owned()); + let repo_raw_name = url.split('/').last().unwrap_or(&path); + let repo_name = format!("{repo_raw_name}-{path}"); + let mut checkout_path = PathBuf::from("repositories"); + checkout_path.push(repo_name); + + let book_path = if let Some(path) = &sb.path { + let mut bp = checkout_path.clone(); + bp.push(path); + bp + } else { + checkout_path.clone() + }; + + let _repo = match git2::Repository::open(&checkout_path) { + Ok(repo) => repo, + Err(_) => match git2::Repository::clone(&url, &checkout_path) { + Ok(repo) => repo, + Err(e) => panic!("failed to clone: {}", e), + }, + }; + + process_book(&book_path.to_str().unwrap(), &mut index_file, &mut summary)? + } else if let Some(path) = &sb.path { + process_book(path, &mut index_file, &mut summary)? + } else { + warn!("Neither path or git specified. Invalid book"); } } diff --git a/src/config.rs b/src/config.rs index 76bf17e1dd..dd994b5890 100644 --- a/src/config.rs +++ b/src/config.rs @@ -640,33 +640,19 @@ impl HtmlConfig { #[derive(Deserialize, Debug)] /// Represents a book in a shelf pub struct ShelfBook { - /// local book - pub local: Option>, - /// git book - pub git: Option>, -} - -#[derive(Deserialize, Debug)] -/// Properties for defining a git based mdbook for a shelf -pub struct ShelfGitBook { - /// url to the git - pub url: String, - /// Optional path inside the git where to find the book + /// Path to filesystem local book + /// or if git_url is specified, the path inside the git + /// where the book is located pub path: Option, -} - -#[derive(Deserialize, Debug)] -/// Properties for a book found on disk -pub struct ShelfLocalBook { - /// Path to the book - pub path: String, + /// git url + pub git_url: Option, } #[derive(Deserialize, Debug)] /// Represents a shelf that contains a lot of books pub struct Shelf { /// The books in the shelf - pub book: ShelfBook, + pub book: Vec, } /// Configuration for how to render the print icon, print.html, and print.css.