pull repos
This commit is contained in:
@@ -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"
|
||||
|
@@ -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(())
|
||||
}
|
||||
|
@@ -1,2 +1,3 @@
|
||||
pub mod git;
|
||||
pub mod storage;
|
||||
pub mod schema;
|
||||
|
2
crates/octopush_core/src/schema/mod.rs
Normal file
2
crates/octopush_core/src/schema/mod.rs
Normal file
@@ -0,0 +1,2 @@
|
||||
pub mod models;
|
||||
pub mod parser;
|
26
crates/octopush_core/src/schema/models.rs
Normal file
26
crates/octopush_core/src/schema/models.rs
Normal 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>,
|
||||
},
|
||||
}
|
69
crates/octopush_core/src/schema/parser.rs
Normal file
69
crates/octopush_core/src/schema/parser.rs
Normal 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()
|
||||
}]
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
@@ -12,6 +12,7 @@ pub trait StorageEngine {
|
||||
|
||||
pub type DynStorageEngine = Arc<dyn StorageEngine + Send + Sync>;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct TemporaryDir {
|
||||
path: PathBuf,
|
||||
}
|
||||
|
Reference in New Issue
Block a user