Friendlier progress bars

[?]
Feb 28, 2021, 3:40 PM
BNPSVXIC72C3WT33YKCH766OBLLNCS7POX6U6JXZSQQPJF2M22MQC

Dependencies

  • [2] 3WO4H2MM Fixing async issues in downloads
  • [3] HDGRZISM Version updates
  • [4] G734WNM6 flake.nix: use crate2nix
  • [5] SZWBLWZ4 Reading ~/.ssh/config
  • [6] BT2ZHPY4 Version bumps
  • [7] WIORLB47 Version bump
  • [8] 5YDI33C4 Fixing pager on OSX
  • [9] FBXYP7QM Forgot to add remote::http
  • [10] JACZWIJ6 Version bump
  • [11] 76PCXGML Pushing to, and pulling from the local repository
  • [12] 5QTMRUXN Fixing a race condition between progress bars
  • [13] KTTKF3RW Locking stderr and the progress bar in SSH
  • [14] XAY4DYRR Version bump
  • [15] IQ4FCHPZ HTTP connections: pooling + retry on error
  • [16] UDHP4ZVB Fixing SSH asynchronicity issues
  • [17] YX3VCEOM Version bump
  • [18] FE5ES6Q4 Stop pushing/pulling if the remote returns an error
  • [19] WTZXEWY7 Flushing the futures pipeline when downloading over HTTP(S)
  • [20] 6DOXSHWG Cleanup, and version bump
  • [21] VYHHOEYH Versions and formatting
  • [22] AOK35FEX New Cargo.nix versions
  • [23] HSVGP2G4 Version bump + formatting
  • [24] LGEJSLTY Fixing output (including its uses in reset and pull)
  • [25] G65S7FAW Version bump and cleanup
  • [26] 3WIQYEIS Fixing conflicts in Cargo.lock
  • [27] QE64ATLZ Fixing asynchronicity problems in SSH
  • [28] HR3WK6A7 When lock times out, check that there are no more clients before quitting
  • [29] KUMJITTF Version bump in the lockfiles
  • [30] CUHXXBDZ Fixing a bug in replacements, recently introduced during a fix of a graph corruption bug
  • [31] TKEVOH7H Fixing a bug when downloading changes, and making change download more efficient (more async)
  • [32] SAGSYAPX Various version bumps
  • [33] Q7CAYX5N Fixing Windows compilation
  • [34] G6YZ7U65 Version bump
  • [35] CCLLB7OI Upgrading to Sanakirja 0.15 + version bump
  • [36] TPEH2XNB 1.0.0-alpha.28, with Tokio 1.0
  • [37] 3S4DR77Z Version updates
  • [38] OCBM7IFE New release: pijul-1.0.0-alpha.8
  • [39] ENKQ3QZG Forward the exit status messages from the SSH background loop to the client (solving hangs)
  • [40] G3A7KDTO Update edit to 0.1.3, fixing windows editing
  • [41] WLUID7NA Do not block when downloading more than 100 changes over SSH
  • [42] Q45QHPO4 Feedback on network stuff
  • [43] LYTVEPH3 Avoid cloning into an existing path
  • [44] XWETQ4DE Upgrading versions
  • [45] 5BRU2RRW Cleanup (debugging a crash related to trees/inodes)
  • [46] UFCZKKLX Upgrading to the latest Sanakirja/Rand
  • [47] N35L72XV Versions in Cargo.lock
  • [48] YN63NUZO Sanakirja 1.0
  • [49] VBMXB443 Retrying if the HTTP connection drops while reading the body
  • [50] SXEYMYF7 Fixing the bad changes in history (unfortunately, by rebooting).
  • [51] H62VFFJE Cargo.nix, and solving conflicts
  • [52] I52XSRUH Massive cleanup, and simplification
  • [53] WI5BS6BS New published versions
  • [54] PJ7T2VFL Do not hang on locked repositories
  • [55] 23LVKATN Use pager crate for log output
  • [56] JRENVH5D Reqwest 0.11
  • [57] L4JXJHWX pijul/*: reorganize imports and remove extern crate
  • [58] 7ZFRYVVQ Cargo.nix and formatting
  • [59] PCEJFKFX Progress bar for upload and apply
  • [60] H565UUPC Use correct pattern for workspace interdependencies
  • [61] K6GWUOD5 Styling progress bars
  • [62] X6YFD4WV Do not download changes if we already have them
  • [63] MU5GSJAW Partial push and pull (WARNING: breaks the existing protocol)
  • [64] ZQXP3HNA Version bump
  • [65] 2K7JLB4Z No pager on Windows
  • [66] 44BN7FWS Do not output files introduced by patches that were not applied during a push
  • [67] OUWD436A Version bump
  • [68] ZTVNGFNT Version bump
  • [69] ZRUPLBBT Colours in diff and change: separating concerns and dependencies
  • [70] Y6EVFMTA Don't output files if they aren't in the current channel
  • [71] BZSC7VMY address clippy lints
  • [72] 367UBQ6K Forwarding SSH stderr, and progress bar for push
  • [73] OJZWJUF2 MUCH faster `pijul add -r`
  • [74] FXT5FS5W Updating Cargo.nix
  • [75] 3VJB4ULD Updating Cargo.nix
  • [76] JL4WKA5P Implement the Sanakirja concurrency model in a cross-process way
  • [77] NX5I5H53 New published versions
  • [78] HXEIH4UQ Pulling more than 100 changes at once
  • [79] IIV3EL2X Cleanup, formatting, and fixing the Git feature
  • [80] MDADYULS Fix a panic when switching between channels that have different files
  • [81] SN7AGY6S Making `pijul lock` robust to kill signals
  • [82] B5Z4IMEU Generating Cargo.nix for pijul 1.0.0-alpha.6

Change contents

  • edit in pijul/src/remote/ssh.rs at line 10
    [4.126][4.0:28]()
    use indicatif::ProgressBar;
  • edit in pijul/src/remote/ssh.rs at line 37
    [4.19][4.19:107]()
    static ref PROGRESS: Arc<Mutex<Option<ProgressBar>>> = Arc::new(Mutex::new(None));
  • edit in pijul/src/remote/ssh.rs at line 381
    [4.399][4.147:194](),[4.194][4.564:617]()
    *PROGRESS.lock().await = None;
    *super::SPINNER.lock().await = None;
  • replacement in pijul/src/remote/ssh.rs at line 455
    [2.556][4.3913:3960](),[4.3913][4.3913:3960]()
    debug!("sending");
    [2.556]
    [4.3960]
    debug!("sending {:?}", hashes[*current]);
  • edit in pijul/src/remote/ssh.rs at line 750
    [4.44567][4.493:556](),[4.556][4.0:80](),[4.80][4.0:78](),[4.78][4.155:166](),[4.155][4.155:166](),[4.166][4.79:133](),[4.133][4.333:382](),[4.166][4.333:382]()
    let progress = ProgressBar::new(changes.len() as u64);
    progress.set_style(
    indicatif::ProgressStyle::default_bar()
    .template(" Uploading changes {wide_bar} {pos:>5}/{len}"),
    );
    let progress = super::PROGRESS.add(progress);
    *PROGRESS.lock().await = Some(progress);
  • edit in pijul/src/remote/ssh.rs at line 767
    [4.45306][4.383:499]()
    if let Some(ref mut progress) = *PROGRESS.lock().await {
    progress.inc(1);
    }
  • edit in pijul/src/remote/ssh.rs at line 768
    [4.45379][4.45379:45389](),[4.45389][4.500:653](),[4.653][4.134:205](),[4.205][4.734:780](),[4.734][4.734:780]()
    }
    if let Some(ref mut progress) = *PROGRESS.lock().await {
    progress.set_style(
    indicatif::ProgressStyle::default_bar()
    .template("✓ Uploading changes {pos:>5}/{len}"),
    );
    progress.finish();
  • replacement in pijul/src/remote/ssh.rs at line 774
    [4.45470][4.465:536]()
    c: &mut tokio::sync::mpsc::Receiver<libpijul::pristine::Hash>,
    [4.45470]
    [4.8746]
    progress: Arc<std::sync::Mutex<crate::progress::InnerCursors>>,
    c: &mut tokio::sync::mpsc::UnboundedReceiver<libpijul::pristine::Hash>,
  • replacement in pijul/src/remote/ssh.rs at line 780
    [4.45564][4.64:131]()
    self.download_changes_(c, Some(sender), changes_dir, full)
    [4.45564]
    [4.131]
    self.download_changes_(progress, c, Some(sender), changes_dir, full)
  • replacement in pijul/src/remote/ssh.rs at line 786
    [4.208][4.537:608](),[4.608][4.248:334](),[4.248][4.248:334]()
    c: &mut tokio::sync::mpsc::Receiver<libpijul::pristine::Hash>,
    mut sender: Option<&mut tokio::sync::mpsc::Sender<libpijul::pristine::Hash>>,
    [4.208]
    [4.334]
    progress: Arc<std::sync::Mutex<crate::progress::InnerCursors>>,
    c: &mut tokio::sync::mpsc::UnboundedReceiver<libpijul::pristine::Hash>,
    sender: Option<&mut tokio::sync::mpsc::Sender<libpijul::pristine::Hash>>,
  • replacement in pijul/src/remote/ssh.rs at line 806
    [4.9350][4.695:720](),[4.9753][4.922:975](),[4.975][4.0:80](),[4.86][4.0:80](),[4.80][4.206:284](),[4.284][4.155:166](),[4.155][4.155:166](),[4.166][4.791:840](),[4.840][2.810:1195](),[2.1195][4.958:1035](),[4.533][4.958:1035](),[4.1035][2.1196:1237](),[2.1237][4.1079:1101](),[4.1079][4.1079:1101](),[4.1101][2.1238:2832]()
    let mut len = 0;
    let progress = ProgressBar::new(len as u64);
    progress.set_style(
    indicatif::ProgressStyle::default_bar()
    .template(" Downloading changes {wide_bar} {pos:>5}/{len}"),
    );
    *PROGRESS.lock().await = Some(progress);
    let mut dropped = false;
    loop {
    tokio::select! {
    x = recv.recv() => {
    let hash = if let Some(hash) = x {
    debug!("received hash {:?}", hash);
    hash
    } else {
    debug!("finished");
    break
    };
    if let Some(ref mut progress) = *PROGRESS.lock().await {
    progress.inc(1);
    }
    if let Some(ref mut sender) = sender {
    if sender.send(hash).await.is_err() {
    if let Some(ref mut progress) = *PROGRESS.lock().await {
    progress.abandon();
    }
    break;
    }
    }
    }
    x = c.recv(), if !dropped => {
    let c = if let Some(c) = x {
    c
    } else {
    debug!("other end dropped");
    dropped = true;
    if len == 0 {
    break
    } else {
    continue
    }
    };
    if let State::Changes { ref mut hashes, .. } = *self.state.lock().await {
    hashes.push(c);
    }
    debug!("download_change {:?} {:?}", c, full);
    if full {
    self.c
    .data(format!("change {}\n", c.to_base32()).as_bytes())
    .await?;
    } else {
    self.c
    .data(format!("partial {}\n", c.to_base32()).as_bytes())
    .await?;
    }
    if let Some(ref mut p) = *PROGRESS.lock().await {
    p.inc_length(1)
    }
    len += 1;
    [4.9350]
    [4.600]
    let mut sender = sender.map(|x| x.clone());
    let t = tokio::spawn(async move {
    while let Some(hash) = recv.recv().await {
    debug!("received hash {:?}", hash);
    progress.lock().unwrap().cursors[0].incr();
    debug!("received");
    if let Some(ref mut sender) = sender {
    sender.send(hash).await.unwrap_or(());
  • edit in pijul/src/remote/ssh.rs at line 815
    [4.618]
    [4.49729]
    }
    });
    while let Some(h) = c.recv().await {
    if let State::Changes { ref mut hashes, .. } = *self.state.lock().await {
    hashes.push(h);
  • replacement in pijul/src/remote/ssh.rs at line 821
    [4.49743][4.203:213](),[4.213][4.1102:1304](),[4.1304][4.285:362](),[4.362][4.1389:1443](),[4.1389][4.1389:1443]()
    }
    if let Some(ref mut progress) = *PROGRESS.lock().await {
    if !progress.is_finished() {
    progress.set_style(
    indicatif::ProgressStyle::default_bar()
    .template("✓ Downloading changes {pos:>5}/{len}"),
    );
    progress.finish();
    [4.49743]
    [4.1443]
    debug!("download_change {:?} {:?}", h, full);
    if full {
    self.c
    .data(format!("change {}\n", h.to_base32()).as_bytes())
    .await?;
    } else {
    self.c
    .data(format!("partial {}\n", h.to_base32()).as_bytes())
    .await?;
  • edit in pijul/src/remote/ssh.rs at line 832
    [4.49753]
    [4.976]
    t.await?;
  • edit in pijul/src/remote/mod.rs at line 11
    [4.573][4.768:792]()
    use tokio::sync::Mutex;
  • edit in pijul/src/remote/mod.rs at line 29
    [4.52848][4.394:512](),[4.512][4.793:890]()
    }
    lazy_static! {
    static ref PROGRESS: Arc<indicatif::MultiProgress> = Arc::new(indicatif::MultiProgress::new());
    static ref SPINNER: Arc<Mutex<Option<indicatif::ProgressBar>>> = Arc::new(Mutex::new(None));
  • edit in pijul/src/remote/mod.rs at line 164
    [4.986][4.471:737](),[4.1508][4.471:737](),[4.737][4.891:939]()
    let progress = indicatif::ProgressBar::new_spinner();
    progress.set_style(
    indicatif::ProgressStyle::default_spinner()
    .template("{spinner} Updating remote changelist"),
    );
    progress.enable_steady_tick(100);
    *SPINNER.lock().await = Some(progress);
  • edit in pijul/src/remote/mod.rs at line 193
    [4.1067][4.940:1215](),[4.57497][4.940:1215]()
    if let Some(progress) = SPINNER.lock().await.take() {
    progress.set_style(
    indicatif::ProgressStyle::default_spinner()
    .template("✓ Updating remote changelist"),
    );
    progress.finish();
    }
  • replacement in pijul/src/remote/mod.rs at line 330
    [4.66710][4.1129:1205]()
    hashes: &mut tokio::sync::mpsc::Receiver<libpijul::pristine::Hash>,
    [4.66710]
    [4.10700]
    progress: Arc<std::sync::Mutex<crate::progress::InnerCursors>>,
    hashes: &mut tokio::sync::mpsc::UnboundedReceiver<libpijul::pristine::Hash>,
  • replacement in pijul/src/remote/mod.rs at line 338
    [4.67232][4.10810:11092]()
    RemoteRepo::Local(ref mut l) => l.download_changes(hashes, send, path).await?,
    RemoteRepo::Ssh(ref mut s) => s.download_changes(hashes, send, path, full).await?,
    RemoteRepo::Http(ref mut h) => h.download_changes(hashes, send, path, full).await?,
    [4.67232]
    [4.2760]
    RemoteRepo::Local(ref mut l) => {
    l.download_changes(progress, hashes, send, path).await?
    }
    RemoteRepo::Ssh(ref mut s) => {
    s.download_changes(progress, hashes, send, path, full)
    .await?
    }
    RemoteRepo::Http(ref mut h) => {
    h.download_changes(progress, hashes, send, path, full)
    .await?
    }
  • edit in pijul/src/remote/mod.rs at line 364
    [4.1407]
    [4.68985]
    let progress = crate::progress::Cursors::new();
    {
    let mut pro = progress.borrow_mut().unwrap();
    pro.cursors.push(crate::progress::Cursor::Bar {
    i: 0,
    n: to_apply.len(),
    pre: "Downloading changes".into(),
    });
    if do_apply {
    pro.cursors.push(crate::progress::Cursor::Bar {
    i: 0,
    n: to_apply.len(),
    pre: "Applying".into(),
    });
    }
    }
  • replacement in pijul/src/remote/mod.rs at line 384
    [4.1274][4.1274:1348]()
    let (hash_send, mut hash_recv) = tokio::sync::mpsc::channel(100);
    [4.1274]
    [4.1348]
    let (hash_send, mut hash_recv) = tokio::sync::mpsc::unbounded_channel();
  • edit in pijul/src/remote/mod.rs at line 388
    [4.1472]
    [4.1472]
    let progress_ = progress.inner.clone();
  • replacement in pijul/src/remote/mod.rs at line 391
    [4.1532][4.1532:1619]()
    .download_changes(&mut hash_recv, &mut send, &mut change_path_, false)
    [4.1532]
    [4.1619]
    .download_changes(
    progress_,
    &mut hash_recv,
    &mut send,
    &mut change_path_,
    false,
    )
  • replacement in pijul/src/remote/mod.rs at line 403
    [4.69111][4.1699:1724]()
    let mut len = 0;
    [4.69111]
    [4.231]
    let mut to_download = HashSet::with_capacity(to_apply.len());
  • replacement in pijul/src/remote/mod.rs at line 407
    [4.402][4.1725:1793]()
    hash_send.send(*h).await?;
    len += 1
    [4.402]
    [4.440]
    hash_send.send(*h)?;
    to_download.insert(*h);
  • edit in pijul/src/remote/mod.rs at line 415
    [4.69809][4.69809:69865](),[4.69865][4.574:611](),[4.611][4.1794:1848](),[4.1848][4.905:986](),[4.686][4.905:986](),[4.986][4.513:595](),[4.595][4.1065:1080](),[4.1065][4.1065:1080](),[4.1080][4.596:630](),[4.630][4.749:794](),[4.749][4.749:794](),[4.794][4.631:735]()
    let mut change_path = repo.changes_dir.clone();
    let progress = if do_apply {
    let p = indicatif::ProgressBar::new(len);
    p.set_style(
    indicatif::ProgressStyle::default_bar()
    .template(" Applying changes {wide_bar} {pos:>5}/{len}"),
    );
    Some(PROGRESS.add(p))
    } else {
    None
    };
    let t_progress = std::thread::spawn(|| {
    PROGRESS.join().unwrap_or(());
    });
  • replacement in pijul/src/remote/mod.rs at line 417
    [4.621][4.69903:70253](),[4.69903][4.69903:70253](),[4.70253][4.795:920]()
    libpijul::changestore::filesystem::push_filename(&mut change_path, &h);
    debug!("change_path = {:?}", change_path);
    while std::fs::metadata(&change_path).is_err() {
    debug!("waiting");
    let r = recv.recv().await;
    debug!("r = {:?}", r);
    if r.is_none() {
    if let Some(ref progress) = progress {
    progress.abandon();
    }
    [4.621]
    [4.70253]
    debug!("to_apply: {:?}", h);
    while to_download.contains(&h) {
    debug!("waiting for {:?}", h);
    if let Some(h) = recv.recv().await {
    debug!("recv {:?}", h);
    to_download.remove(&h);
    } else {
  • edit in pijul/src/remote/mod.rs at line 427
    [4.70312][4.70312:70391](),[4.70391][4.1455:1456]()
    libpijul::changestore::filesystem::pop_filename(&mut change_path);
  • replacement in pijul/src/remote/mod.rs at line 455
    [4.2529][4.921:972](),[4.70391][4.921:972]()
    if let Some(ref progress) = progress {
    [4.2529]
    [4.972]
    if do_apply {
  • replacement in pijul/src/remote/mod.rs at line 457
    [4.1015][4.1015:1048]()
    progress.inc(1);
    [4.1015]
    [4.7658]
    progress.inner.lock().unwrap().cursors[1].incr();
    debug!("apply");
  • edit in pijul/src/remote/mod.rs at line 460
    [4.7732]
    [4.70594]
    debug!("applied");
  • edit in pijul/src/remote/mod.rs at line 463
    [4.70662][4.70662:70686](),[4.70686][4.1049:1133](),[4.1133][4.1081:1177](),[4.1177][4.622:699](),[4.699][4.1262:1281](),[4.810][4.1262:1281](),[4.1262][4.1262:1281](),[4.1281][4.1133:1167](),[4.1133][4.1133:1167]()
    }
    }
    if let Some(progress) = progress {
    if !progress.is_finished() {
    progress.set_style(
    indicatif::ProgressStyle::default_bar()
    .template("✓ Applying changes {pos:>5}/{len}"),
    );
    progress.finish()
  • edit in pijul/src/remote/mod.rs at line 465
    [4.1191]
    [4.70686]
    debug!("finished");
  • replacement in pijul/src/remote/mod.rs at line 469
    [4.321][4.811:847]()
    t_progress.join().unwrap();
    [4.321]
    [4.2530]
    progress.join();
  • replacement in pijul/src/remote/mod.rs at line 481
    [4.71183][4.768:842]()
    let (send_hash, mut recv_hash) = tokio::sync::mpsc::channel(100);
    [4.71183]
    [4.71261]
    let (send_hash, mut recv_hash) = tokio::sync::mpsc::unbounded_channel();
  • edit in pijul/src/remote/mod.rs at line 485
    [4.71386]
    [4.71386]
    let progress = crate::progress::Cursors::new();
  • replacement in pijul/src/remote/mod.rs at line 488
    [4.1867][4.1867:1961]()
    .download_changes(&mut recv_hash, &mut send_signal, &mut change_path_, false)
    [4.1867]
    [4.1961]
    .download_changes(
    progress.inner.clone(),
    &mut recv_hash,
    &mut send_signal,
    &mut change_path_,
    false,
    )
  • replacement in pijul/src/remote/mod.rs at line 500
    [4.71974][4.71974:72012]()
    send_hash.send(h).await?;
    [4.71974]
    [4.72012]
    send_hash.send(h)?;
  • replacement in pijul/src/remote/mod.rs at line 512
    [4.72533][4.72533:72577]()
    send_hash.send(dep).await?;
    [4.72533]
    [4.72577]
    send_hash.send(dep)?;
  • replacement in pijul/src/remote/mod.rs at line 566
    [4.75086][4.843:917]()
    let (send_hash, mut recv_hash) = tokio::sync::mpsc::channel(100);
    [4.75086]
    [4.75164]
    let (send_hash, mut recv_hash) = tokio::sync::mpsc::unbounded_channel();
  • edit in pijul/src/remote/mod.rs at line 570
    [4.75363]
    [4.75363]
    let progress = crate::progress::Cursors::new();
  • replacement in pijul/src/remote/mod.rs at line 573
    [4.2126][4.2126:2215]()
    .download_changes(&mut recv_hash, &mut send_sig, &mut changes_dir, true)
    [4.2126]
    [4.2215]
    .download_changes(
    progress.inner.clone(),
    &mut recv_hash,
    &mut send_sig,
    &mut changes_dir,
    true,
    )
  • replacement in pijul/src/remote/mod.rs at line 595
    [4.76328][4.76328:76371]()
    send_hash.send(*c).await?;
    [4.76328]
    [4.76371]
    send_hash.send(*c)?;
  • replacement in pijul/src/remote/mod.rs at line 619
    [4.2672][4.2672:2719]()
    send_hash.send(*c).await?;
    [4.2672]
    [4.2719]
    send_hash.send(*c)?;
  • replacement in pijul/src/remote/local.rs at line 129
    [4.83512][4.2765:2841]()
    hashes: &mut tokio::sync::mpsc::Receiver<libpijul::pristine::Hash>,
    [4.83512]
    [4.11767]
    progress: Arc<std::sync::Mutex<crate::progress::InnerCursors>>,
    hashes: &mut tokio::sync::mpsc::UnboundedReceiver<libpijul::pristine::Hash>,
  • edit in pijul/src/remote/local.rs at line 137
    [4.3058]
    [4.12057]
    progress.lock().unwrap().cursors[0].incr();
  • edit in pijul/src/remote/http.rs at line 6
    [4.11135][4.1193:1221](),[4.1193][4.1193:1221]()
    use indicatif::ProgressBar;
  • replacement in pijul/src/remote/http.rs at line 73
    [4.1135][4.3093:3169]()
    hashes: &mut tokio::sync::mpsc::Receiver<libpijul::pristine::Hash>,
    [4.1135]
    [4.1180]
    progress: std::sync::Arc<std::sync::Mutex<crate::progress::InnerCursors>>,
    hashes: &mut tokio::sync::mpsc::UnboundedReceiver<libpijul::pristine::Hash>,
  • edit in pijul/src/remote/http.rs at line 79
    [4.1338][4.3170:3221](),[4.3221][4.1282:1362](),[4.1316][4.1282:1362](),[4.1362][4.848:926](),[4.926][4.1437:1448](),[4.1437][4.1437:1448](),[4.1448][4.927:981]()
    let progress = ProgressBar::new(0 as u64);
    progress.set_style(
    indicatif::ProgressStyle::default_bar()
    .template(" Downloading changes {wide_bar} {pos:>5}/{len}"),
    );
    let progress = super::PROGRESS.add(progress);
  • edit in pijul/src/remote/http.rs at line 82
    [4.3272][4.3272:3308]()
    progress.inc_length(1);
  • edit in pijul/src/remote/http.rs at line 83
    [4.643][4.1366:1395](),[4.1267][4.1366:1395]()
    progress.inc(1);
  • edit in pijul/src/remote/http.rs at line 93
    [4.1867]
    [4.867]
    debug!("waiting for process {:?}", cur);
  • edit in pijul/src/remote/http.rs at line 95
    [4.902]
    [4.902]
    debug!("sending {:?}", c);
    progress.lock().unwrap().cursors[0].incr();
  • edit in pijul/src/remote/http.rs at line 99
    [4.1991][4.1991:2031]()
    progress.abandon();
  • edit in pijul/src/remote/http.rs at line 101
    [4.2076]
    [4.1335]
    debug!("sent");
  • edit in pijul/src/remote/http.rs at line 108
    [4.239]
    [4.239]
    debug!("sending {:?}", c);
    progress.lock().unwrap().cursors[0].incr();
  • edit in pijul/src/remote/http.rs at line 112
    [4.335][4.335:375]()
    progress.abandon();
  • edit in pijul/src/remote/http.rs at line 114
    [4.420]
    [4.420]
    debug!("sent");
  • edit in pijul/src/remote/http.rs at line 116
    [4.434][4.1349:1359](),[4.2118][4.1349:1359](),[4.1349][4.1349:1359](),[4.1359][4.1433:1470](),[4.1470][4.1449:1537](),[4.1537][4.982:1055](),[4.1055][4.1618:1633](),[4.1618][4.1618:1633](),[4.1633][4.1470:1501](),[4.1470][4.1470:1501]()
    }
    if !progress.is_finished() {
    progress.set_style(
    indicatif::ProgressStyle::default_bar()
    .template("✓ Downloading changes {pos:>5}/{len}"),
    );
    progress.finish();
  • edit in pijul/src/remote/http.rs at line 126
    [4.1011][4.1011:1074](),[4.1074][4.1634:1714](),[4.1714][4.1056:1134](),[4.411][4.1787:1798](),[4.1134][4.1787:1798](),[4.1787][4.1787:1798]()
    let progress = ProgressBar::new(changes.len() as u64);
    progress.set_style(
    indicatif::ProgressStyle::default_bar()
    .template(" Uploading changes {wide_bar} {pos:>5}/{len}"),
    );
  • edit in pijul/src/remote/http.rs at line 153
    [4.1806][4.1806:1835]()
    progress.inc(1);
  • edit in pijul/src/remote/http.rs at line 155
    [4.1511][4.1799:1827](),[4.1827][4.1135:1237](),[4.489][4.1954:1965](),[4.1237][4.1954:1965](),[4.1954][4.1954:1965](),[4.1965][4.1909:1936](),[4.1511][4.1909:1936]()
    progress.set_style(
    indicatif::ProgressStyle::default_bar().template("✓ Uploading changes {pos:>5}/{len}"),
    );
    progress.finish();
  • file addition: progress.rs (----------)
    [4.21414]
    use std::borrow::Cow;
    use std::io::Write;
    use std::sync::{Arc, Mutex};
    pub struct Cursors {
    pub inner: Arc<Mutex<InnerCursors>>,
    t: std::thread::JoinHandle<()>,
    }
    pub struct InnerCursors {
    drawn: usize,
    pub cursors: Vec<Cursor>,
    n_post: usize,
    n_pre: usize,
    w: usize,
    stop: bool,
    }
    impl Cursors {
    pub fn new() -> Self {
    let inner = Arc::new(Mutex::new(InnerCursors {
    drawn: 0,
    cursors: Vec::new(),
    n_post: 0,
    n_pre: 0,
    stop: false,
    w: 0,
    }));
    let inner_ = inner.clone();
    let t = std::thread::spawn(move || loop {
    {
    let mut inner = if let Ok(inner) = inner_.lock() {
    inner
    } else {
    break;
    };
    if inner.stop {
    inner.render().unwrap();
    break;
    } else {
    inner.render().unwrap();
    }
    }
    std::thread::sleep(std::time::Duration::from_millis(100));
    });
    Cursors { inner, t }
    }
    pub fn stop(&self) {
    if let Ok(mut n) = self.inner.lock() {
    n.stop = true
    }
    }
    pub fn join(self) {
    self.stop();
    self.t.join().unwrap();
    }
    pub fn borrow_mut(
    &self,
    ) -> Result<
    std::sync::MutexGuard<InnerCursors>,
    std::sync::PoisonError<std::sync::MutexGuard<'_, InnerCursors>>,
    > {
    let mut m = self.inner.lock()?;
    m.n_pre = 0;
    Ok(m)
    }
    }
    #[allow(dead_code)]
    pub enum Cursor {
    Static {
    pre: Cow<'static, str>,
    },
    Bar {
    pre: Cow<'static, str>,
    n: usize,
    i: usize,
    },
    Spin {
    pre: Cow<'static, str>,
    i: usize,
    },
    }
    impl Cursor {
    fn pre(&self) -> &str {
    match self {
    Cursor::Static { pre } => pre,
    Cursor::Bar { pre, .. } => pre,
    Cursor::Spin { pre, .. } => pre,
    }
    }
    fn n(&self) -> usize {
    match self {
    Cursor::Bar { n, .. } => {
    let mut n = *n;
    let mut r = 6;
    while n > 0 {
    n /= 10;
    r += 2
    }
    r
    }
    _ => 0,
    }
    }
    pub fn incr(&mut self) {
    match self {
    Cursor::Bar { i, .. } => *i += 1,
    _ => {}
    }
    }
    fn render<W: std::io::Write>(
    &mut self,
    stdout: &mut W,
    npre: usize,
    npost: usize,
    w: usize,
    ) -> Result<(), std::io::Error> {
    match self {
    Cursor::Static { pre } => {
    for _ in 0..npre - pre.chars().count() {
    stdout.write_all(b" ")?;
    }
    stdout.write_all(pre.as_bytes())?;
    // Fil the rest of the line with spaces.
    for _ in 0..w - npre {
    stdout.write_all(b" ")?;
    }
    Ok(())
    }
    Cursor::Bar { pre, i, n } => {
    for _ in 0..npre - pre.chars().count() {
    stdout.write_all(b" ")?;
    }
    // Comupte the appropriate width for the bar.
    let w = w - npre - npost;
    // Output the bar.
    write!(stdout, "{} [", pre)?;
    let k = (w as usize * *i) / (*n - 1);
    for j in 0..w as usize {
    if j < k {
    write!(stdout, "=")?;
    } else if j == k {
    write!(stdout, ">")?;
    } else {
    write!(stdout, " ")?
    }
    }
    write!(stdout, "] {}/{}", *i, *n)?;
    let mut nw = npost - 6;
    {
    let mut n = *n;
    while n > 0 {
    n /= 10;
    nw -= 1
    }
    let mut n = *i;
    while n > 0 {
    n /= 10;
    nw -= 1
    }
    }
    for _ in 0..nw {
    stdout.write_all(b" ")?;
    }
    Ok(())
    }
    Cursor::Spin { pre, i } => {
    for _ in 0..npre - pre.chars().count() {
    stdout.write_all(b" ")?;
    }
    stdout.write_all(pre.as_bytes())?;
    stdout.write_all(b" ")?;
    const SYM: [&str; 8] = ["←", "↖", "↑", "↗", "→", "↘", "↓", "↙"];
    stdout.write_all(SYM[*i].as_bytes())?;
    *i = (*i + 1) % SYM.len();
    // Fill the rest of the line with spaces.
    for _ in 0..w - npre - 2 {
    stdout.write_all(b" ")?;
    }
    Ok(())
    }
    }
    }
    }
    impl InnerCursors {
    fn render(&mut self) -> Result<(), std::io::Error> {
    use terminal_size::*;
    let mut stdout = std::io::stdout();
    if let Some((Width(w), _)) = terminal_size() {
    if self.n_pre == 0 {
    self.n_post = 0;
    for c in self.cursors.iter() {
    let n_pre = c.pre().chars().count();
    self.n_pre = self.n_pre.max(n_pre);
    self.n_post = self.n_post.max(c.n());
    }
    }
    let n = (self.w + w as usize - 1) / w as usize;
    for _ in 0..self.drawn * n {
    stdout.write_all(b"\x1B[F")?;
    }
    self.w = w as usize;
    for c in self.cursors.iter_mut() {
    c.render(&mut stdout, self.n_pre, self.n_post, w as usize)?;
    // Clear the end of the line and move to the next one.
    stdout.write_all(b"\x1B[K\n")?;
    }
    self.drawn = self.cursors.len();
    // Erase the terminal after the cursor.
    stdout.write_all(b"\x1B[J")?;
    stdout.flush()?;
    }
    Ok(())
    }
    }
  • edit in pijul/src/main.rs at line 3
    [4.84234]
    [4.84234]
    mod progress;
  • edit in pijul/src/commands/pushpull.rs at line 408
    [4.11788][4.72:154](),[4.120449][4.72:154](),[4.154][4.562:749](),[4.562][4.562:749]()
    let progress = indicatif::ProgressBar::new(to_download.len() as u64);
    progress.set_style(
    indicatif::ProgressStyle::default_spinner()
    .template(" Applying changes {wide_bar} {pos}/{len}"),
    );
  • edit in pijul/src/commands/pushpull.rs at line 410
    [4.11872][4.750:783](),[4.120565][4.750:783]()
    progress.inc(1);
  • edit in pijul/src/commands/pushpull.rs at line 411
    [4.120579][4.784:999]()
    progress.set_style(
    indicatif::ProgressStyle::default_bar()
    .template("✓ Applying changes {wide_bar} {pos}/{len}"),
    );
    progress.finish();
  • edit in pijul/src/commands/pushpull.rs at line 418
    [4.120778][4.1966:2210]()
    let progress = indicatif::ProgressBar::new_spinner();
    progress.set_style(
    indicatif::ProgressStyle::default_spinner().template("{spinner} Outputting repository"),
    );
    progress.enable_steady_tick(100);
  • edit in pijul/src/commands/pushpull.rs at line 480
    [4.1293][4.2211:2372](),[4.11136][4.2211:2372](),[4.120955][4.2211:2372](),[4.2372][4.120955:120956](),[4.120955][4.120955:120956]()
    progress.set_style(
    indicatif::ProgressStyle::default_spinner().template("✓ Outputting repository"),
    );
    progress.finish();
  • edit in pijul/src/commands/clone.rs at line 82
    [4.185601][4.2318:2562]()
    let progress = indicatif::ProgressBar::new_spinner();
    progress.set_style(
    indicatif::ProgressStyle::default_spinner().template("{spinner} Outputting repository"),
    );
    progress.enable_steady_tick(100);
  • edit in pijul/src/commands/clone.rs at line 92
    [4.15909][4.2373:2507](),[4.185801][4.2373:2507](),[4.2507][4.2563:2590](),[4.185801][4.2563:2590]()
    progress.set_style(
    indicatif::ProgressStyle::default_spinner().template("✓ Outputting repository"),
    );
    progress.finish();
  • replacement in pijul/Cargo.toml at line 4
    [4.196462][3.74:101]()
    version = "1.0.0-alpha.43"
    [4.196462]
    [4.196488]
    version = "1.0.0-alpha.44"
  • replacement in pijul/Cargo.toml at line 82
    [4.198127][4.2840:2859]()
    indicatif = "0.15"
    [4.198110]
    [4.2482]
    terminal_size = "0.1"
  • replacement in Cargo.toml at line 2
    [4.1030201][4.1030201:1030251]()
    members = [ "pijul-macros", "pijul", "libpijul" ]
    [4.1030201]
    members = [ "pijul-macros", "pijul", "libpijul", "progress" ]
  • edit in Cargo.nix at line 66
    [4.1835]
    [4.1835]
    };
    # Debug support which might change between releases.
    # File a bug if you depend on any for non-debug work!
    debug = internal.debugCrate { inherit packageId; };
    };
    "progress" = rec {
    packageId = "progress";
    build = internal.buildRustCrateWithFeatures {
    packageId = "progress";
  • edit in Cargo.nix at line 726
    [4.28722][4.275:330](),[4.330][4.138789:138817](),[4.138817][4.358:384](),[4.358][4.358:384](),[4.384][4.138818:138891](),[4.390][4.28900:28920](),[4.457][4.28900:28920](),[4.138891][4.28900:28920](),[4.28900][4.28900:28920](),[4.28920][4.458:515](),[4.515][4.28970:29018](),[4.28970][4.28970:29018](),[4.29018][4.516:595](),[4.595][3.1585:1657](),[3.1657][4.656:1256](),[4.656][4.656:1256](),[4.1256][4.75031:75043](),[4.29073][4.75031:75043](),[4.75043][4.1257:1298](),[4.1298][4.70:104](),[4.104][3.1658:1730](),[3.1730][4.1399:1482](),[4.1399][4.1399:1482](),[4.1669][4.1669:1681](),[4.1681][4.75043:75054](),[4.75043][4.75043:75054](),[4.75054][4.1682:1743](),[4.1743][4.138892:138950](),[4.138950][4.1826:1908](),[4.1826][4.1826:1908](),[4.1908][4.138951:139039](),[4.2035][4.75063:75072](),[4.139039][4.75063:75072](),[4.75063][4.75063:75072]()
    "console" = rec {
    crateName = "console";
    version = "0.14.0";
    edition = "2018";
    sha256 = "1ajnr0rga4vya0fza12ighf3ffkm86w1rv8p5wf443s8nd30kj3w";
    authors = [
    "Armin Ronacher <armin.ronacher@active-4.com>"
    ];
    dependencies = [
    {
    name = "encode_unicode";
    packageId = "encode_unicode";
    target = { target, features }: (target."windows" or false);
    }
    {
    name = "lazy_static";
    packageId = "lazy_static";
    }
    {
    name = "libc";
    packageId = "libc";
    }
    {
    name = "regex";
    packageId = "regex";
    optional = true;
    usesDefaultFeatures = false;
    features = [ "std" ];
    }
    {
    name = "terminal_size";
    packageId = "terminal_size";
    }
    {
    name = "unicode-width";
    packageId = "unicode-width";
    optional = true;
    }
    {
    name = "winapi";
    packageId = "winapi";
    target = { target, features }: (target."windows" or false);
    features = [ "winbase" "winuser" "consoleapi" "processenv" "wincon" ];
    }
    ];
    features = {
    "ansi-parsing" = [ "regex" ];
    "default" = [ "unicode-width" "ansi-parsing" ];
    "windows-console-colors" = [ "ansi-parsing" "winapi-util" ];
    };
    resolvedDefaultFeatures = [ "ansi-parsing" "default" "regex" "unicode-width" ];
    };
  • edit in Cargo.nix at line 1117
    [4.39836][4.2036:2446]()
    "encode_unicode" = rec {
    crateName = "encode_unicode";
    version = "0.3.6";
    edition = "2015";
    sha256 = "07w3vzrhxh9lpjgsg2y5bwzfar2aq35mdznvcp3zjl0ssj7d4mx3";
    authors = [
    "Torbjørn Birch Moltu <t.b.moltu@lyse.net>"
    ];
    features = {
    "default" = [ "std" ];
    };
    resolvedDefaultFeatures = [ "default" "std" ];
    };
  • edit in Cargo.nix at line 2423
    [4.78124][4.2540:3524]()
    "indicatif" = rec {
    crateName = "indicatif";
    version = "0.15.0";
    edition = "2018";
    sha256 = "1r4n50mclyi4c7b9c9mlma1rhchjamw71r3z8vgqcmp24mhvbakv";
    authors = [
    "Armin Ronacher <armin.ronacher@active-4.com>"
    ];
    dependencies = [
    {
    name = "console";
    packageId = "console";
    }
    {
    name = "lazy_static";
    packageId = "lazy_static";
    }
    {
    name = "number_prefix";
    packageId = "number_prefix";
    }
    {
    name = "regex";
    packageId = "regex";
    usesDefaultFeatures = false;
    features = [ "std" ];
    }
    ];
    features = {
    "improved_unicode" = [ "unicode-segmentation" "unicode-width" "console/unicode-width" ];
    "with_rayon" = [ "rayon" ];
    };
    resolvedDefaultFeatures = [ "default" ];
    };
  • edit in Cargo.nix at line 3295
    [3.4489][4.3601:3997](),[4.107199][4.3601:3997]()
    };
    "number_prefix" = rec {
    crateName = "number_prefix";
    version = "0.3.0";
    edition = "2015";
    sha256 = "0slm4mqmpgs6hvz22ycny9lvyvl9ivs80a1lncslp7lszz02zc0p";
    authors = [
    "Benjamin Sago <ogham@bsago.me>"
    ];
    features = {
    "default" = [ "std" ];
    };
    resolvedDefaultFeatures = [ "default" "std" ];
  • replacement in Cargo.nix at line 3556
    [4.114701][3.4639:4675]()
    version = "1.0.0-alpha.43";
    [4.114701]
    [4.114736]
    version = "1.0.0-alpha.44";
  • edit in Cargo.nix at line 3634
    [4.116319][4.116319:116343](),[4.116343][4.4107:4176]()
    }
    {
    name = "indicatif";
    packageId = "indicatif";
  • edit in Cargo.nix at line 3696
    [4.117409]
    [4.117593]
    name = "terminal_size";
    packageId = "terminal_size";
    }
    {
  • edit in Cargo.nix at line 3958
    [4.125529]
    [4.125857]
    "progress" = rec {
    crateName = "progress";
    version = "0.1.0";
    edition = "2018";
    crateBin = [
    { name = "progress"; path = "src/main.rs"; }
    ];
    src = lib.cleanSourceWith { filter = sourceFilter; src = ./progress; };
    authors = [
    "Pierre-Étienne Meunier <pmeunier@mailbox.org>"
    ];
    dependencies = [
    {
    name = "terminal_size";
    packageId = "terminal_size";
    }
    ];
    };
  • replacement in Cargo.nix at line 4826
    [4.150408][3.5607:5635]()
    version = "1.0.63";
    [4.150408]
    [4.150436]
    version = "1.0.64";
  • replacement in Cargo.nix at line 4828
    [4.150462][3.5636:5709]()
    sha256 = "1xhbc83n1pwiw02ddqf98gwynihscg69h2nfq0wajjvsfjwmsls3";
    [4.150462]
    [4.150535]
    sha256 = "0y9gk3yikncrc0zajmwc0pidr7zfwafawb4gidf6mqyskzf9g7kr";
  • replacement in Cargo.nix at line 6766
    [4.221933][4.8310:8916]()
    resolvedDefaultFeatures = [ "basetsd" "cfg" "consoleapi" "errhandlingapi" "evntrace" "fileapi" "handleapi" "impl-debug" "impl-default" "in6addr" "inaddr" "ioapiset" "knownfolders" "lmcons" "memoryapi" "minschannel" "minwinbase" "minwindef" "mswsock" "namedpipeapi" "ntdef" "ntsecapi" "ntstatus" "objbase" "processenv" "processthreadsapi" "profileapi" "schannel" "securitybaseapi" "shlobj" "sspi" "std" "synchapi" "sysinfoapi" "threadpoollegacyapiset" "timezoneapi" "winbase" "wincon" "wincrypt" "windef" "winerror" "winioctl" "winnt" "winreg" "winsock2" "winuser" "ws2def" "ws2ipdef" "ws2tcpip" ];
    [4.221933]
    [4.222405]
    resolvedDefaultFeatures = [ "basetsd" "cfg" "consoleapi" "errhandlingapi" "evntrace" "fileapi" "handleapi" "impl-debug" "impl-default" "in6addr" "inaddr" "ioapiset" "knownfolders" "lmcons" "memoryapi" "minschannel" "minwinbase" "minwindef" "mswsock" "namedpipeapi" "ntdef" "ntsecapi" "ntstatus" "objbase" "processenv" "processthreadsapi" "profileapi" "schannel" "securitybaseapi" "shlobj" "sspi" "std" "synchapi" "sysinfoapi" "threadpoollegacyapiset" "timezoneapi" "winbase" "wincon" "wincrypt" "windef" "winerror" "winioctl" "winnt" "winreg" "winsock2" "ws2def" "ws2ipdef" "ws2tcpip" ];
  • edit in Cargo.lock at line 231
    [4.4466][4.4466:4483](),[4.4483][4.141614:141633](),[4.141633][4.4502:4567](),[4.4502][4.4502:4567](),[4.4567][4.141634:141712](),[4.141712][4.4645:4752](),[4.4645][4.4645:4752](),[4.4752][4.755:766](),[4.652][4.1038025:1038027](),[4.766][4.1038025:1038027](),[4.1038025][4.1038025:1038027](),[4.832][4.832:845]()
    name = "console"
    version = "0.14.0"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "7cc80946b3480f421c2f17ed1cb841753a371c7c5104f51d507e13f532c856aa"
    dependencies = [
    "encode_unicode",
    "lazy_static",
    "libc",
    "regex",
    "terminal_size",
    "unicode-width",
    "winapi",
    ]
    [[package]]
  • edit in Cargo.lock at line 389
    [4.1042002][4.4786:4984]()
    name = "encode_unicode"
    version = "0.3.6"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
    [[package]]
  • edit in Cargo.lock at line 831
    [4.1052812][4.1052812:1052827](),[4.1052827][4.4985:5239]()
    ]
    [[package]]
    name = "indicatif"
    version = "0.15.0"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "7baab56125e25686df467fe470785512329883aab42696d661247aca2a2896e4"
    dependencies = [
    "console",
    "lazy_static",
    "number_prefix",
    "regex",
  • edit in Cargo.lock at line 1141
    [4.1061494][4.1061494:1061507](),[4.1061507][4.5255:5439]()
    [[package]]
    name = "number_prefix"
    version = "0.3.0"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "17b02fc0ff9a9e4b35b3342880f48e896ebf69f2967921fe8646bf5b7125956a"
  • replacement in Cargo.lock at line 1245
    [4.1064071][3.18343:18370]()
    version = "1.0.0-alpha.43"
    [4.1064071]
    [4.1064097]
    version = "1.0.0-alpha.44"
  • edit in Cargo.lock at line 1264
    [4.1064313][4.5453:5467]()
    "indicatif",
  • edit in Cargo.lock at line 1278
    [4.2083]
    [4.1064478]
    "terminal_size",
  • edit in Cargo.lock at line 1388
    [4.1067656]
    [4.1067851]
    name = "progress"
    version = "0.1.0"
    dependencies = [
    "terminal_size",
    ]
    [[package]]
  • replacement in Cargo.lock at line 1678
    [4.1073896][3.18586:18605]()
    version = "1.0.63"
    [4.1073896]
    [4.1073915]
    version = "1.0.64"
  • replacement in Cargo.lock at line 1680
    [4.1073980][3.18606:18684]()
    checksum = "43535db9747a4ba938c0ce0a98cc631a46ebf943c9e1d604e091df6007620bf6"
    [4.1073980]
    [4.1074058]
    checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79"