cargo successfully pulling index(!)
Diff
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(-)
@@ -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
@@ -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<Box<dyn Future<Output = Result<(Handler, Session), <Handler as server::Handler>::Error>> + Send>>;
type AsyncHandlerFn = Pin<
Box<
dyn Future<Output = Result<(Handler, Session), <Handler as server::Handler>::Error>> + Send,
>,
>;
impl server::Handler for Handler {
type Error = anyhow::Error;
@@ -167,13 +169,42 @@
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()?),
);
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);
@@ -1,0 +1,2 @@
target/
Cargo.lock
@@ -1,0 +1,9 @@
[package]
name = "test-using-chartered"
version = "0.1.0"
edition = "2018"
[dependencies]
charteredtest = { version = "1", registry = "chartered" }
@@ -132,7 +132,7 @@
pub const fn mode(&self) -> &'static str {
match self {
Self::File => "100644",
Self::Directory => "0000",
Self::Directory => "40000",
}
}
}
@@ -1,0 +1,2 @@
[registries]
chartered = { index = "ssh://127.0.0.1:2233/" }
@@ -1,0 +1,7 @@
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
}