aboutsummaryrefslogtreecommitdiff
path: root/src/forge
diff options
context:
space:
mode:
Diffstat (limited to 'src/forge')
-rw-r--r--src/forge/gitlab/config.rs26
-rw-r--r--src/forge/gitlab/mod.rs73
-rw-r--r--src/forge/mod.rs48
3 files changed, 147 insertions, 0 deletions
diff --git a/src/forge/gitlab/config.rs b/src/forge/gitlab/config.rs
new file mode 100644
index 0000000..37186e8
--- /dev/null
+++ b/src/forge/gitlab/config.rs
@@ -0,0 +1,26 @@
+use serde::{Deserialize, Serialize};
+use std::path::PathBuf;
+
+use crate::config::ForgeConfigTrait;
+
+#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Deserialize, Serialize)]
+pub struct Gitlab {
+ // pub url: url::Url,
+ pub host: String,
+ pub token: String,
+ pub directory: PathBuf,
+ #[serde(default = "default_tls")]
+ pub tls: bool,
+ #[serde(default)]
+ pub auto_create_branches: bool,
+}
+
+const fn default_tls() -> bool {
+ true
+}
+
+impl ForgeConfigTrait for Gitlab {
+ fn root(&self) -> &str {
+ self.directory.to_str().unwrap()
+ }
+}
diff --git a/src/forge/gitlab/mod.rs b/src/forge/gitlab/mod.rs
new file mode 100644
index 0000000..a32c367
--- /dev/null
+++ b/src/forge/gitlab/mod.rs
@@ -0,0 +1,73 @@
+use anyhow::{bail, Context, Result};
+use gitlab::AsyncGitlab;
+
+use graphql_client::GraphQLQuery;
+use tracing::{debug, trace};
+
+pub mod config;
+
+#[derive(Clone, Debug)]
+pub struct Gitlab {
+ client: AsyncGitlab,
+}
+
+impl Gitlab {
+ pub async fn new(host: &str, token: &str, tls: bool) -> Result<Gitlab> {
+ let mut gitlab = gitlab::GitlabBuilder::new(host, token);
+
+ if !tls {
+ gitlab.insecure();
+ }
+
+ let gitlab = gitlab.build_async().await?;
+
+ Ok(Gitlab { client: gitlab })
+ }
+
+ pub async fn from_config(forge: &config::Gitlab) -> Result<Gitlab> {
+ Gitlab::new(&forge.host, &forge.token, forge.tls).await
+ }
+}
+
+#[async_trait::async_trait]
+impl super::ForgeTrait for Gitlab {
+ async fn projects(&self, scope: &str) -> Result<Vec<super::Project>> {
+ let query = Projects::build_query(projects::Variables {
+ scope: scope.to_owned(),
+ });
+ debug!("query: {:#?}", query);
+ let res = self.client.graphql::<Projects>(&query).await?;
+
+ let res = res
+ .projects
+ .unwrap()
+ .nodes
+ .unwrap()
+ .into_iter()
+ .filter(|x| x.is_some())
+ .map(|x| x.unwrap().into())
+ .collect();
+
+ Ok(res)
+ }
+}
+
+#[derive(GraphQLQuery)]
+#[graphql(
+ query_path = "graphql/projects_query.graphql",
+ schema_path = "graphql/schema.graphql",
+ response_derives = "Clone, Debug"
+)]
+pub struct Projects;
+
+impl Into<super::Project> for projects::ProjectsProjectsNodes {
+ fn into(self) -> super::Project {
+ super::Project {
+ id: self.id,
+ name: self.name,
+ path: self.full_path,
+ ssh_clone_url: self.ssh_url_to_repo,
+ http_clone_url: self.http_url_to_repo,
+ }
+ }
+}
diff --git a/src/forge/mod.rs b/src/forge/mod.rs
new file mode 100644
index 0000000..3e94812
--- /dev/null
+++ b/src/forge/mod.rs
@@ -0,0 +1,48 @@
+use std::ops::Deref;
+
+use anyhow::{Result, bail};
+use serde::{Deserialize, Serialize};
+
+use crate::config::ForgeConfig;
+
+pub mod gitlab;
+
+#[derive(Clone, Debug)]
+pub enum Forge {
+ Gitlab(self::gitlab::Gitlab),
+}
+
+impl Forge {
+ pub async fn new(config: &ForgeConfig) -> Result<Forge> {
+ match config {
+ ForgeConfig::Gitlab(config) => {
+ Ok(Forge::Gitlab(gitlab::Gitlab::from_config(config).await?))
+ }
+ _ => bail!("wrong forge type found"),
+ }
+ }
+}
+
+#[async_trait::async_trait]
+pub trait ForgeTrait {
+ async fn projects(&self, scope: &str) -> Result<Vec<Project>>;
+}
+
+impl Deref for Forge {
+ type Target = dyn ForgeTrait;
+
+ fn deref(&self) -> &Self::Target {
+ match self {
+ Forge::Gitlab(forge) => forge,
+ }
+ }
+}
+
+#[derive(Clone, Debug, Deserialize, Serialize)]
+pub struct Project {
+ pub id: String,
+ pub name: String,
+ pub path: String,
+ pub ssh_clone_url: Option<String>,
+ pub http_clone_url: Option<String>,
+}