From 625e45d9131cd0858cff40a67636566768bc994a Mon Sep 17 00:00:00 2001 From: Jordan Doyle Date: Tue, 31 Aug 2021 02:07:10 +0100 Subject: [PATCH] cargo successfully pulling index(!) --- README.md | 3 +-- src/main.rs | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------- test-using-chartered/.gitignore | 2 ++ test-using-chartered/Cargo.toml | 9 +++++++++ src/git/packfile.rs | 2 +- test-using-chartered/.cargo/config.toml | 2 ++ test-using-chartered/src/lib.rs | 7 +++++++ 7 files changed, 78 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index c054fea..e5c1b10 100644 --- a/README.md +++ a/README.md @@ -11,8 +11,7 @@ - ~reverse engineer & create tokio codec for the git protocol~ **now successfully generating a repo, tree & blob in memory git clients can understand!** - clean up all the hacked-together code and package it all up into a nice library for generating git commit objects etc -- serve an index -- serve cargo manifest over git (how does git handle 'force pushes' from server -> client? lets see how they like it for once, i'm sick of people picking on servers all the time) +- ~serve cargo manifest over git (how does git handle 'force pushes' from server -> client? lets see how they like it for once, i'm sick of people picking on servers all the time)~ **turns out, very well - they've helpfully included the --force flag in their `cargo fetch` call so we can serve a completely different commit on every pull if we wanted to and not have to worry about conflicts** - serve .crate files over http using auth tokens we generated while serving the manifest #### open q's diff --git a/src/main.rs b/src/main.rs index 31b7a0e..92529cc 100644 --- a/src/main.rs +++ a/src/main.rs @@ -1,6 +1,5 @@ #![deny(clippy::pedantic)] #[allow(clippy::missing_errors_doc)] - pub mod git; use crate::git::{ @@ -9,11 +8,12 @@ PktLine, }; -use bytes::{BytesMut}; +use bytes::BytesMut; use futures::future::Future; use std::{fmt::Write, pin::Pin, sync::Arc}; use thrussh::{ - ChannelId, CryptoVec, server::{self, Auth, Session}, + server::{self, Auth, Session}, + ChannelId, CryptoVec, }; use thrussh_keys::key; use tokio_util::codec::{Decoder, Encoder as TokioEncoder}; @@ -24,9 +24,7 @@ env_logger::init(); let mut config = thrussh::server::Config::default(); - config - .keys - .push(key::KeyPair::generate_ed25519().unwrap()); + config.keys.push(key::KeyPair::generate_ed25519().unwrap()); let config = Arc::new(config); thrussh::server::run(config, "127.0.0.1:2233", Server) .await @@ -64,7 +62,11 @@ } } -type AsyncHandlerFn = Pin::Error>> + Send>>; +type AsyncHandlerFn = Pin< + Box< + dyn Future::Error>> + Send, + >, +>; impl server::Handler for Handler { type Error = anyhow::Error; @@ -167,13 +169,42 @@ // echo -ne "0012command=fetch\n0001000ethin-pack\n0010include-tag\n000eofs-delta\n0032want d24d8020163b5fee57c9babfd0c595b8c90ba253\n0009done\n" - let file = PackFileEntry::Blob(b"this is some text inside my cool test file!"); + let test_crate_file = PackFileEntry::Blob(br#"{"name":"charteredtest","vers":"1.0.0","deps":[],"cksum":"7b821735f0211fd00032a9892d1bf2323c9d05d9c59b9303eb382f5ec1898bfc","features":{},"yanked":false,"links":null}"#); + let config_file = PackFileEntry::Blob( + br#"{ + "dl": "http://127.0.0.1:8888/api/v1/crates", + "api": "http://127.0.0.1:8888" + }"#, + ); - let tree = PackFileEntry::Tree(vec![TreeItem { - kind: TreeItemKind::File, - name: "test", - hash: file.hash()?, - }]); + let ch_ar_tree = PackFileEntry::Tree(vec![ + TreeItem { + kind: TreeItemKind::File, + name: "charteredtest", + hash: test_crate_file.hash()?, + } + ]); + + let ch_tree = PackFileEntry::Tree(vec![ + TreeItem { + kind: TreeItemKind::Directory, + name: "ar", + hash: ch_ar_tree.hash()?, + } + ]); + + let root_tree = PackFileEntry::Tree(vec![ + TreeItem { + kind: TreeItemKind::Directory, + name: "ch", + hash: ch_tree.hash()?, + }, + TreeItem { + kind: TreeItemKind::File, + name: "config.json", + hash: config_file.hash()?, + }, + ]); let commit_user = CommitUserInfo { name: "Jordan Doyle", @@ -182,32 +213,22 @@ }; let commit = PackFileEntry::Commit(Commit { - tree: tree.hash()?, + tree: root_tree.hash()?, author: commit_user, committer: commit_user, message: "cool commit", }); - - println!( - "commit hash: {} - tree hash: {} - file hash: {}", - hex::encode(&commit.hash()?), - hex::encode(&tree.hash()?), - hex::encode(&file.hash()?), - ); - // echo -ne "0014command=ls-refs\n0014agent=git/2.321\n00010008peel000bsymrefs000aunborn0014ref-prefix HEAD\n0000" + // echo -ne "0014command=ls-refs\n0014agent=git/2.321\n00010009peel\n000csymrefs\n000bunborn\n0014ref-prefix HEAD\n0019ref-prefix refs/HEAD\n001eref-prefix refs/tags/HEAD\n001fref-prefix refs/heads/HEAD\n0021ref-prefix refs/remotes/HEAD\n0026ref-prefix refs/remotes/HEAD/HEAD\n001aref-prefix refs/tags/\n0000" // GIT_PROTOCOL=version=2 ssh -o SendEnv=GIT_PROTOCOL git@github.com git-upload-pack '/w4/chartered.git' // ''.join([('{:04x}'.format(len(v) + 5)), v, "\n"]) // echo -ne "0012command=fetch\n0001000ethin-pack\n0010no-progress\n0010include-tag\n000eofs-delta\n0032want f6046cf6372e0d8ab845f6dec1602c303a66ee91\n" // sends a 000dpackfile back // https://shafiul.github.io/gitbook/7_the_packfile.html if ls_refs { + let commit_hash = hex::encode(&commit.hash()?); self.write(PktLine::Data( - format!( - "{} HEAD symref-target:refs/heads/master\n", - hex::encode(&commit.hash()?) - ) - .as_bytes(), + format!("{} HEAD symref-target:refs/heads/master\n", commit_hash).as_bytes(), ))?; self.write(PktLine::Flush)?; self.flush(&mut session, channel); @@ -228,7 +249,14 @@ self.write(PktLine::SidebandMsg(b"Hello from chartered!\n"))?; self.flush(&mut session, channel); - let packfile = git::packfile::PackFile::new(vec![commit, tree, file]); + let packfile = git::packfile::PackFile::new(vec![ + commit, + test_crate_file, + ch_tree, + ch_ar_tree, + config_file, + root_tree, + ]); self.write(PktLine::SidebandData(packfile))?; self.write(PktLine::Flush)?; self.flush(&mut session, channel); diff --git a/test-using-chartered/.gitignore b/test-using-chartered/.gitignore new file mode 100644 index 0000000..2c96eb1 100644 --- /dev/null +++ a/test-using-chartered/.gitignore @@ -1,0 +1,2 @@ +target/ +Cargo.lock diff --git a/test-using-chartered/Cargo.toml b/test-using-chartered/Cargo.toml new file mode 100644 index 0000000..471bf5c 100644 --- /dev/null +++ a/test-using-chartered/Cargo.toml @@ -1,0 +1,9 @@ +[package] +name = "test-using-chartered" +version = "0.1.0" +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +charteredtest = { version = "1", registry = "chartered" } diff --git a/src/git/packfile.rs b/src/git/packfile.rs index befdcfc..99fccd7 100644 --- a/src/git/packfile.rs +++ a/src/git/packfile.rs @@ -132,7 +132,7 @@ pub const fn mode(&self) -> &'static str { match self { Self::File => "100644", - Self::Directory => "0000", + Self::Directory => "40000", } } } diff --git a/test-using-chartered/.cargo/config.toml b/test-using-chartered/.cargo/config.toml new file mode 100644 index 0000000..37f88f8 100644 --- /dev/null +++ a/test-using-chartered/.cargo/config.toml @@ -1,0 +1,2 @@ +[registries] +chartered = { index = "ssh://127.0.0.1:2233/" } diff --git a/test-using-chartered/src/lib.rs b/test-using-chartered/src/lib.rs new file mode 100644 index 0000000..31e1bb2 100644 --- /dev/null +++ a/test-using-chartered/src/lib.rs @@ -1,0 +1,7 @@ +#[cfg(test)] +mod tests { + #[test] + fn it_works() { + assert_eq!(2 + 2, 4); + } +} -- rgit 0.1.3