@@ -12,6 +12,8 @@ clap.workspace = true
|
||||
dotenv.workspace = true
|
||||
serde_yaml.workspace = true
|
||||
serde.workspace = true
|
||||
reqwest = {workspace = true, features = ["blocking", "json"]}
|
||||
url.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
tracing-test = {workspace = true, features = ["no-env-filter"]}
|
@@ -11,6 +11,7 @@ use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
git_client::VcsClient,
|
||||
gitea_client::GiteaClient,
|
||||
ui::{ConsoleUi, DynUi},
|
||||
};
|
||||
|
||||
@@ -42,12 +43,20 @@ struct GlobalArgs {
|
||||
)]
|
||||
token: Option<String>,
|
||||
|
||||
/// Which repository to publish against. If not supplied remote url will be used.
|
||||
#[arg(long, global = true, group = "global", help_heading = "Global")]
|
||||
repo_url: Option<String>,
|
||||
/// Which repository to publish against. If not supplied remote url will be inferred from environment or fail if not present.
|
||||
#[arg(long, global = true, help_heading = "Global")]
|
||||
api_url: Option<String>,
|
||||
|
||||
/// repo is the name of repository you want to release for
|
||||
#[arg(long, global = true, help_heading = "Global")]
|
||||
repo: Option<String>,
|
||||
|
||||
/// owner is the name of user from which the repository belongs <user>/<repo>
|
||||
#[arg(long, global = true, help_heading = "Global")]
|
||||
owner: Option<String>,
|
||||
|
||||
/// which source directory to use, if not set `std::env::current_dir` is used instead.
|
||||
#[arg(long, global = true, group = "global", help_heading = "Global")]
|
||||
#[arg(long, global = true, help_heading = "Global")]
|
||||
source: Option<PathBuf>,
|
||||
|
||||
/// no version control system, forces please to allow no .git/ or friends
|
||||
@@ -151,6 +160,23 @@ impl Command {
|
||||
self.ui.write_str_ln(&format!("cuddle-config"));
|
||||
}
|
||||
},
|
||||
Some(Commands::Gitea { command }) => match command {
|
||||
GiteaCommand::Connect {} => {
|
||||
let git_url = url::Url::parse(&self.global.api_url.unwrap())?;
|
||||
|
||||
let mut url = String::new();
|
||||
url.push_str(git_url.scheme());
|
||||
url.push_str("://");
|
||||
url.push_str(&git_url.host().unwrap().to_string());
|
||||
if let Some(port) = git_url.port() {
|
||||
url.push_str(format!(":{port}").as_str());
|
||||
}
|
||||
|
||||
let client = GiteaClient::new(url, self.global.token);
|
||||
client.connect(self.global.owner.unwrap(), self.global.repo.unwrap())?;
|
||||
self.ui.write_str_ln("connected succesfully go gitea");
|
||||
}
|
||||
},
|
||||
None => {
|
||||
tracing::debug!("running bare command");
|
||||
// 2. Parse the cuddle.please.yaml let cuddle.please.yaml take precedence
|
||||
@@ -195,13 +221,24 @@ enum Commands {
|
||||
#[command(subcommand)]
|
||||
command: ConfigCommand,
|
||||
},
|
||||
|
||||
Gitea {
|
||||
#[command(subcommand)]
|
||||
command: GiteaCommand,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Subcommand, Debug, Clone)]
|
||||
enum ConfigCommand {
|
||||
/// List will list the final configuration
|
||||
List {},
|
||||
}
|
||||
|
||||
#[derive(Subcommand, Debug, Clone)]
|
||||
enum GiteaCommand {
|
||||
Connect {},
|
||||
}
|
||||
|
||||
fn get_current_path(
|
||||
optional_current_dir: Option<&Path>,
|
||||
optional_source_path: Option<PathBuf>,
|
||||
|
@@ -1 +1,82 @@
|
||||
use reqwest::header::{HeaderMap, HeaderValue};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub struct GiteaClient {
|
||||
url: String,
|
||||
token: Option<String>,
|
||||
pub allow_insecure: bool,
|
||||
}
|
||||
|
||||
const APP_USER_AGENT: &'static str =
|
||||
concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION"),);
|
||||
|
||||
impl GiteaClient {
|
||||
pub fn new(url: impl Into<String>, token: Option<impl Into<String>>) -> Self {
|
||||
Self {
|
||||
url: url.into(),
|
||||
token: token.map(|t| t.into()),
|
||||
allow_insecure: false,
|
||||
}
|
||||
}
|
||||
|
||||
fn create_client(&self) -> anyhow::Result<reqwest::blocking::Client> {
|
||||
let cb = reqwest::blocking::ClientBuilder::new();
|
||||
let mut header_map = HeaderMap::new();
|
||||
if let Some(token) = &self.token {
|
||||
header_map.insert(
|
||||
"Authorization",
|
||||
HeaderValue::from_str(format!("token {}", token).as_str())?,
|
||||
);
|
||||
}
|
||||
|
||||
let client = cb
|
||||
.user_agent(APP_USER_AGENT)
|
||||
.default_headers(header_map)
|
||||
.danger_accept_invalid_certs(self.allow_insecure)
|
||||
.build()?;
|
||||
|
||||
Ok(client)
|
||||
}
|
||||
|
||||
pub fn connect(&self, owner: impl Into<String>, repo: impl Into<String>) -> anyhow::Result<()> {
|
||||
let client = self.create_client()?;
|
||||
|
||||
let request = client
|
||||
.get(format!(
|
||||
"{}/api/v1/repos/{}/{}",
|
||||
&self.url.trim_end_matches("/"),
|
||||
owner.into(),
|
||||
repo.into()
|
||||
))
|
||||
.build()?;
|
||||
|
||||
let resp = client.execute(request)?;
|
||||
|
||||
if !resp.status().is_success() {
|
||||
resp.error_for_status()?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_tags(
|
||||
&self,
|
||||
owner: impl Into<String>,
|
||||
repository: impl Into<String>,
|
||||
) -> anyhow::Result<Vec<Tag>> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn get_commits_since(
|
||||
&self,
|
||||
owner: impl Into<String>,
|
||||
repository: impl Into<String>,
|
||||
since_sha: impl Into<String>,
|
||||
) -> anyhow::Result<Vec<Tag>> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
pub struct Tag {}
|
||||
|
@@ -5,8 +5,7 @@ pub mod ui;
|
||||
|
||||
use command::Command;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> anyhow::Result<()> {
|
||||
fn main() -> anyhow::Result<()> {
|
||||
dotenv::dotenv().ok();
|
||||
tracing_subscriber::fmt::init();
|
||||
|
||||
|
@@ -16,6 +16,7 @@ impl Default for DynUi {
|
||||
|
||||
pub(crate) struct ConsoleUi {}
|
||||
|
||||
#[allow(dead_code)]
|
||||
impl ConsoleUi {
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
|
Reference in New Issue
Block a user