🏡 index : ~doyle/chartered.git

author Jordan Doyle <jordan@doyle.la> 2021-08-31 2:07:10.0 +01:00:00
committer Jordan Doyle <jordan@doyle.la> 2021-08-31 2:10:32.0 +01:00:00
commit
625e45d9131cd0858cff40a67636566768bc994a [patch]
tree
598d0604a41b2116d91eb298c2b0637973e3e94d
parent
39329a3fc67f11814a1277f842bf7b07d728bd7d
download
625e45d9131cd0858cff40a67636566768bc994a.tar.gz

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(-)

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<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 @@

            // 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);
    }
}