pull repos

This commit is contained in:
2022-11-21 21:27:36 +01:00
parent 5fc7d7caf9
commit 1879ad00ee
15 changed files with 231 additions and 16 deletions

View File

@@ -9,7 +9,10 @@ edition = "2021"
async-trait = { workspace = true }
eyre = { workspace = true }
tokio = { workspace = true }
tracing = { workspace = true }
rand = "0.8.5"
hex = "0.4.3"
git2 = "0.15.0"
serde = { version = "1.0.147", features = ["derive"] }
serde_yaml = "0.9.14"

View File

@@ -1,3 +1,5 @@
use git2::{Cred, RemoteCallbacks};
use crate::storage::DynStorageEngine;
use super::GitProvider;
@@ -15,10 +17,32 @@ impl GitHubGitProvider {
#[async_trait::async_trait]
impl GitProvider for GitHubGitProvider {
async fn clone_from_url(&self, url: String) -> eyre::Result<()> {
tracing::debug!(url, "allocating dir");
let dir = self.storage_engine.allocate_dir().await?;
tokio::task::spawn_blocking(move || git2::Repository::clone(url.as_str(), dir.path()))
.await??;
tokio::task::spawn_blocking(move || {
let mut callbacks = RemoteCallbacks::new();
callbacks.credentials(|url, username_from_url, _allowed_types| {
tracing::debug!(username_from_url, url, "pulling key from ssh-agent");
Cred::ssh_key_from_agent(username_from_url.unwrap())
});
let mut fo = git2::FetchOptions::new();
fo.remote_callbacks(callbacks);
let mut builder = git2::build::RepoBuilder::new();
builder.fetch_options(fo);
let path = dir.path();
tracing::debug!(
url,
path = path.as_os_str().to_string_lossy().to_string(),
"clone git repo"
);
builder.clone(url.as_str(), path.as_path())
})
.await??;
Ok(())
}

View File

@@ -1,2 +1,3 @@
pub mod git;
pub mod storage;
pub mod schema;

View File

@@ -0,0 +1,2 @@
pub mod models;
pub mod parser;

View File

@@ -0,0 +1,26 @@
use serde::{Deserialize, Serialize};
pub type Repository = String;
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
pub struct SelectAction {
pub repositories: Vec<Repository>,
}
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
#[serde(tag = "type")]
pub enum Action {
#[serde(rename = "go")]
Go { entry: String },
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
#[serde(tag = "apiVersion")]
pub enum Schema {
#[serde(rename = "action")]
Action {
name: String,
select: SelectAction,
actions: Vec<Action>,
},
}

View File

@@ -0,0 +1,69 @@
use std::{path::PathBuf, sync::Arc};
use async_trait::async_trait;
use super::models::Schema;
#[async_trait]
pub trait SchemaParser {
async fn parse_file(&self, file: PathBuf) -> eyre::Result<Schema>;
}
pub type DynSchemaParser = Arc<dyn SchemaParser + Send + Sync>;
#[derive(Debug)]
pub struct DefaultSchemaParser {}
#[async_trait]
impl SchemaParser for DefaultSchemaParser {
async fn parse_file(&self, file: PathBuf) -> eyre::Result<Schema> {
let file = tokio::fs::read(file).await?;
self.parse(file)
}
}
impl DefaultSchemaParser {
pub fn new() -> Self {
Self {}
}
pub fn parse(&self, contents: Vec<u8>) -> eyre::Result<Schema> {
let schema = serde_yaml::from_slice(contents.as_slice())?;
Ok(schema)
}
}
mod test {
use super::DefaultSchemaParser;
use crate::schema::models::{Action, Schema, SelectAction};
#[test]
fn can_parse_action() {
let content = r#"apiVersion: action
name: write-a-readme
select:
repositories:
- git@git.front.kjuulh.io:kjuulh/octopush-test.git
actions:
- type: go
entry: "main.go"
"#;
let res = DefaultSchemaParser::new().parse(content.trim().into());
assert_eq!(
res.unwrap(),
Schema::Action {
name: "write-a-readme".into(),
select: SelectAction {
repositories: vec!["git@git.front.kjuulh.io:kjuulh/octopush-test.git".into()]
},
actions: vec![Action::Go {
entry: "main.go".into()
}]
}
)
}
}

View File

@@ -12,6 +12,7 @@ pub trait StorageEngine {
pub type DynStorageEngine = Arc<dyn StorageEngine + Send + Sync>;
#[derive(Clone, Debug)]
pub struct TemporaryDir {
path: PathBuf,
}