H4AU6QRPRDRFW3V7NN5CJ6DHLEUBYGNLRZ5GYV6ULBGRMOPCJQXQC DO2Y5TY5JQISUHCVNPI2FXO7WWZVJQ3LGPWF4DNADMGZRIO6PT2QC FVQYZQFL7WHSC3UUPJ4IWTP7SKTDQ4K6K5HY4EDK3JKXG3CQNZEAC TI7PCK7JLPU4KYE65XIMBUPPY7DRPVDAETPDFMG3VAQGGDRGQHPQC SXEYMYF7P4RZMZ46WPL4IZUTSQ2ATBWYZX7QNVMS3SGOYXYOHAGQC ZSFJT4SFIAS7WBODRZOFKKG4SVYBC5PC6XY75WYN7CCQ3SMV7IUQC GYXIF25T2BCTCWCQI5DQOF3F4HBWDJUDJUMZ2WLHVBIOYATJTFAQC FBXYP7QM7SG6P2JDJVQPPCRKJE3GVYXNQ5GVV4GRDUNG6Q4ZRDJQC MU5GSJAW65PEG3BRYUKZ7O37BPHW3MOX3S5E2RFOXKGUOJEEDQ5AC I52XSRUH5RVHQBFWVMAQPTUSPAJ4KNVID2RMI3UGCVKFLYUO6WZAC Q45QHPO4HDTEZF2W4UDZSYYQ46BPEIWSW4GJILZR5HTJNLKXJABQC OIOMXESDNMLOTMNYCZZBYSBAQTYPAXXMUHTLA2AYCMNHZMPSLX2AC IQ4FCHPZYGTZHCQHUIRCMUI5LCHIDSJCM2AZXGRJARWLCPPLXZOQC AI73GKAO5QBPR6YGW7H5UNZYAEGYGIHAFO6DM2DWCPMVYLHE547QC BVVMTOYWG4WSVWEYNW2XIG3D34Y7V54ACSSJPQ2AREOO7NGPMLDQC VBMXB443FGZL6DLT6KAP2ICFCCQNXCUMDEUL67HB4CNKFMBBNSSAC 367UBQ6KNAKUEWG32R4QRJ6H7IE7NAZFOPTC3ZOE4Z6E44RV3ISQC JZADJIA3P3EOKPBGEKEXJVGWHNF2SIHYNNMB3XFNPBU4BTVGM3YQC TPEH2XNBS5RO4IEVKENVF6P65AH7IX64KK2JAYMSJT3J5GXO67EAC GFED4ORASDTMUQUCOXXZMOXSR6JJGCP3IEM3SMDG52GX2NMXC4GQC KI2AFWOSN3PTGBGYQ7UKHFOZERZWEUWQ4AQNADG5S4QDJ53ESXFAC A3RM526Y7LUXNYW4TL56YKQ5GVOK2R5D7JJVTSQ6TT5MEXIR6YAAC R245EVN36J34PTG3I2RMX5LIOT76LCPL5RZ2H22BCIXFBGJYJ25QC SEWGHUHQEEBJR7UPG3PSU7DSM376R43QEYENAZK325W46DCFMXKAC VL7ZYKHBPKLNY5SA5QBW56SJ7LBBCKCGV5UAYLVF75KY6PPBOD4AC impl RemoteConfig {async fn to_remote(&self,channel: &str,no_cert_check: bool,with_path: bool,) -> Result<RemoteRepo, anyhow::Error> {match self {RemoteConfig::Ssh { ssh, .. } => {if let Some(mut sshr) = ssh_remote(ssh, with_path) {debug!("unknown_remote, ssh = {:?}", ssh);if let Some(c) = sshr.connect(ssh, channel).await? {return Ok(RemoteRepo::Ssh(c));}}bail!("Remote not found: {:?}", ssh)}RemoteConfig::Http {http,headers,name,} => {let mut h = Vec::new();for (k, v) in headers.iter() {match v {RemoteHttpHeader::String(s) => {h.push((k.clone(), s.clone()));}RemoteHttpHeader::Shell(shell) => {h.push((k.clone(), shell_cmd(&shell.shell)?));}}}return Ok(RemoteRepo::Http(Http {url: http.parse().unwrap(),channel: channel.to_string(),client: reqwest::ClientBuilder::new().danger_accept_invalid_certs(no_cert_check).build()?,headers: h,name: name.to_string(),}));}}}}
.header(reqwest::header::USER_AGENT, USER_AGENT).send().await{
.header(reqwest::header::USER_AGENT, USER_AGENT);for (k, v) in headers.iter() {req = req.header(k.as_str(), v.as_str());}let mut res = if let Ok(res) = req.send().await {
.header(reqwest::header::USER_AGENT, USER_AGENT).body(body).send().await?;
.header(reqwest::header::USER_AGENT, USER_AGENT);for (k, v) in self.headers.iter() {req = req.header(k.as_str(), v.as_str());}let resp = req.body(body).send().await?;
#[derive(Debug, Serialize)]pub enum RemoteName {Name(String),Split(SplitRemote),
#[derive(Debug, Serialize, Deserialize)]#[serde(untagged)]pub enum RemoteConfig {Ssh {name: String,ssh: String,},Http {name: String,http: String,#[serde(default)]headers: HashMap<String, RemoteHttpHeader>,},
#[derive(Clone, Copy, Debug)]pub enum Direction {Push,Pull,}impl RemoteName {pub fn with_dir(&self, d: Direction) -> &str {match (self, d) {(RemoteName::Name(ref s), _) => s,(RemoteName::Split(ref s), Direction::Pull) => &s.pull,(RemoteName::Split(ref s), Direction::Push) => &s.push,
impl RemoteConfig {pub fn name(&self) -> &str {match self {RemoteConfig::Ssh { name, .. } => name,RemoteConfig::Http { name, .. } => name,
use serde::de::{self, MapAccess, Visitor};use serde::de::{Deserialize, Deserializer};use std::fmt;use std::marker::PhantomData;impl<'de> Deserialize<'de> for RemoteName {fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>whereD: Deserializer<'de>,{struct StringOrStruct(PhantomData<fn() -> RemoteName>);impl<'de> Visitor<'de> for StringOrStruct {type Value = RemoteName;fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {formatter.write_str("string or map")}fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>whereE: de::Error,{Ok(RemoteName::Name(value.to_string()))}
fn visit_map<M>(self, map: M) -> Result<Self::Value, M::Error>whereM: MapAccess<'de>,{// `MapAccessDeserializer` is a wrapper that turns a `MapAccess`// into a `Deserializer`, allowing it to be used as the input to T's// `Deserialize` implementation. T then deserializes itself using// the entries from the map visitor.Ok(RemoteName::Split(Deserialize::deserialize(de::value::MapAccessDeserializer::new(map),)?))}}deserializer.deserialize_any(StringOrStruct(PhantomData))}
#[derive(Debug, Serialize, Deserialize)]#[serde(untagged)]pub enum RemoteHttpHeader {String(String),Shell(Shell),
pub fn shell_cmd(s: &str) -> Result<String, anyhow::Error> {let out = if cfg!(target_os = "windows") {std::process::Command::new("cmd").args(&["/C", s]).output().expect("failed to execute process")} else {std::process::Command::new(std::env::var("SHELL").unwrap_or("sh".to_string())).arg("-c").arg(s).output().expect("failed to execute process")};Ok(String::from_utf8(out.stdout)?)}