New config for HTTP remotes
Dependencies
- [2]
DO2Y5TY5Tag synchronisation - [3]
FVQYZQFLCreate dialoguer themes based on global config - [4]
TI7PCK7JUpdate `pijul/src/main.rs` to use new identity management - [5]
FBXYP7QMForgot to add remote::http - [6]
C5XGFNKISimplify return type for remote get_id - [7]
MU5GSJAWPartial push and pull (WARNING: breaks the existing protocol) - [8]
SNZ3OAMCuse native external subcommand support instead of hand-rolled one - [9]
IQ4FCHPZHTTP connections: pooling + retry on error - [10]
CCLLB7OIUpgrading to Sanakirja 0.15 + version bump - [11]
TPEH2XNB1.0.0-alpha.28, with Tokio 1.0 - [12]
X243Z3Y5Recording only the required metadata (can even be changed later!) - [13]
Q45QHPO4Feedback on network stuff - [14]
SXEYMYF7Fixing the bad changes in history (unfortunately, by rebooting). - [15]
367UBQ6KForwarding SSH stderr, and progress bar for push - [16]
GYXIF25TProper parsing of URLs - [17]
5BB266P6Optional colours in the global config file - [18]
I52XSRUHMassive cleanup, and simplification - [19]
BVVMTOYWProper renaming of changes downloaded over HTTP - [20]
VBMXB443Retrying if the HTTP connection drops while reading the body - [21]
KWAGWB73Adding extra dependencies from the config file - [22]
BNPSVXICFriendlier progress bars - [23]
AI73GKAOAdding a UserAgent header to the http downloader - [24]
JRENVH5DReqwest 0.11 - [25]
OIOMXESDBetter error handling in HTTP - [26]
ZSFJT4SFAllow remotes to have a different push and pull address - [27]
R245EVN3Do not print anything on broken pipe errors - [28]
GFED4ORAImprove error handling for nonexistent channels - [29]
4OJWMSOWFully replace crate::Identity - [30]
76PCXGMLPushing to, and pulling from the local repository - [31]
SEWGHUHQ.pijul/config: simplify remotes and hooks - [32]
7Z3KZV6GRetry HTTP downloads if we don't get a full patch - [33]
JZADJIA3Handling HTTP errors - [34]
27RZYCM3Pushing/pulling from/to Nest discussions again - [35]
KI2AFWOSFixing a panic in pull - [36]
A3RM526YIntegrating identity malleability - [*]
VL7ZYKHBRunning hooks through shell on Windows and Unix
Change contents
- replacement in pijul/src/remote/mod.rs at line 53
if let Some(name) = self.config.remotes.get(name) {unknown_remote(if let Some(name) = self.config.remotes.iter().find(|e| e.name() == name) {name.to_remote(channel, no_cert_check, with_path).await/*unknown_remote( - replacement in pijul/src/remote/mod.rs at line 62
.await.await*/ - edit in pijul/src/remote/mod.rs at line 69
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(),}));}}}} - edit in pijul/src/remote/mod.rs at line 133
headers: Vec::new(), - edit in pijul/src/remote/http.rs at line 1[5.10]→[5.4982:5013](∅→∅),[5.1080]→[5.11:55](∅→∅),[5.5013]→[5.11:55](∅→∅),[5.10]→[5.11:55](∅→∅),[5.55]→[5.1192:1193](∅→∅)
use std::collections::HashSet;use std::io::Write;use std::path::PathBuf; - edit in pijul/src/remote/http.rs at line 5
use std::collections::HashSet;use std::io::Write;use std::path::PathBuf; - edit in pijul/src/remote/http.rs at line 18
pub headers: Vec<(String, String)>, - edit in pijul/src/remote/http.rs at line 24
headers: Vec<(String, String)>, - edit in pijul/src/remote/http.rs at line 64
- replacement in pijul/src/remote/http.rs at line 67
let mut res = if let Ok(res) = clientlet mut req = client - replacement in pijul/src/remote/http.rs at line 70
.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 { - edit in pijul/src/remote/http.rs at line 156
self.headers.clone(), - replacement in pijul/src/remote/http.rs at line 233
let resp = selflet mut req = self - replacement in pijul/src/remote/http.rs at line 237[5.1727]→[5.290:355](∅→∅),[5.355]→[2.25772:25800](∅→∅),[2.25800]→[5.1757:1781](∅→∅),[5.1757]→[5.1757:1781](∅→∅),[5.1378]→[5.1781:1806](∅→∅),[5.1781]→[5.1781:1806](∅→∅)
.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?; - replacement in pijul/src/remote/http.rs at line 285
let res = selflet mut req = self - replacement in pijul/src/remote/http.rs at line 289
.header(reqwest::header::USER_AGENT, USER_AGENT).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 res = req.send().await?; - replacement in pijul/src/remote/http.rs at line 341
let res = selflet mut req = self - replacement in pijul/src/remote/http.rs at line 345
.header(reqwest::header::USER_AGENT, USER_AGENT).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 res = req.send().await?; - replacement in pijul/src/remote/http.rs at line 374
let res = selflet mut req = self - replacement in pijul/src/remote/http.rs at line 378
.header(reqwest::header::USER_AGENT, USER_AGENT).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 res = req.send().await?; - replacement in pijul/src/remote/http.rs at line 459
let res = selflet mut req = self - replacement in pijul/src/remote/http.rs at line 470
.header(reqwest::header::USER_AGENT, USER_AGENT).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 res = req.send().await?; - replacement in pijul/src/main.rs at line 153
log::error!("Error backtrace: {:#?}", e.backtrace());log::error!("Error: {:#?}", e); - replacement in pijul/src/config.rs at line 134
pub remotes: HashMap<String, RemoteName>,pub remotes: Vec<RemoteConfig>, - replacement in pijul/src/config.rs at line 142
#[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>,}, - replacement in pijul/src/config.rs at line 157
#[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, - edit in pijul/src/config.rs at line 165
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()))} - replacement in pijul/src/config.rs at line 166
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), - replacement in pijul/src/config.rs at line 174
pub struct SplitRemote {pub pull: String,pub push: String,pub struct Shell {pub shell: String,}#[derive(Clone, Copy, Debug)]pub enum Direction {Push,Pull, - edit in pijul/src/config.rs at line 199[38.217][38.217]
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)?)}