mirror of
https://github.com/narrrl/proton-drive-linux.git
synced 2026-11-03 16:41:26 +01:00
Merge pull request #76 from narrrl/chore/release-3.7.0
chore(release): 3.7.0
This commit is contained in:
9 files changed
+59
-19
No files matched your search
Generated
+4
-4
@@ -3520,7 +3520,7 @@ checksum = "2ee67f1008b1ba2321834326597b8e186293b049a023cdef258527550b9935b4"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pdfs-cli"
|
name = "pdfs-cli"
|
||||||
version = "3.6.0"
|
version = "3.7.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"clap",
|
"clap",
|
||||||
@@ -3536,7 +3536,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pdfs-core"
|
name = "pdfs-core"
|
||||||
version = "3.6.0"
|
version = "3.7.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"base64 0.23.1",
|
"base64 0.23.1",
|
||||||
@@ -3563,7 +3563,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pdfs-fuse"
|
name = "pdfs-fuse"
|
||||||
version = "3.6.0"
|
version = "3.7.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"base64 0.23.1",
|
"base64 0.23.1",
|
||||||
@@ -3585,7 +3585,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pdfs-gui"
|
name = "pdfs-gui"
|
||||||
version = "3.6.0"
|
version = "3.7.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-channel",
|
"async-channel",
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@ resolver = "2"
|
|||||||
members = ["crates/pdfs-core", "crates/pdfs-fuse", "crates/pdfs-cli", "crates/pdfs-gui"]
|
members = ["crates/pdfs-core", "crates/pdfs-fuse", "crates/pdfs-cli", "crates/pdfs-gui"]
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
version = "3.6.0"
|
version = "3.7.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
authors = ["Nils Pukropp <contact@narl.io>"]
|
authors = ["Nils Pukropp <contact@narl.io>"]
|
||||||
|
|||||||
@@ -1036,10 +1036,7 @@ fn cmd_devices(action: DeviceCmd) -> Result<()> {
|
|||||||
CtlResponse::Devices { items } if items.is_empty() => println!("No devices."),
|
CtlResponse::Devices { items } if items.is_empty() => println!("No devices."),
|
||||||
CtlResponse::Devices { items } => {
|
CtlResponse::Devices { items } => {
|
||||||
for d in items {
|
for d in items {
|
||||||
let sync = d
|
let sync = last_synced(d.last_sync);
|
||||||
.last_sync
|
|
||||||
.map(|t| t.to_string())
|
|
||||||
.unwrap_or_else(|| "never".to_string());
|
|
||||||
let tag = match (d.adopted, d.this_device) {
|
let tag = match (d.adopted, d.this_device) {
|
||||||
(true, _) => " *adopted*",
|
(true, _) => " *adopted*",
|
||||||
(false, true) => " *this machine*",
|
(false, true) => " *this machine*",
|
||||||
@@ -1130,11 +1127,7 @@ fn cmd_sync(action: SyncCmd) -> Result<()> {
|
|||||||
}
|
}
|
||||||
CtlResponse::SyncFolders { items } => {
|
CtlResponse::SyncFolders { items } => {
|
||||||
for f in items {
|
for f in items {
|
||||||
let sync = if f.last_sync == 0 {
|
let sync = last_synced(Some(f.last_sync));
|
||||||
"never".to_string()
|
|
||||||
} else {
|
|
||||||
f.last_sync.to_string()
|
|
||||||
};
|
|
||||||
// A queued switch is reported as the mode the folder is moving
|
// A queued switch is reported as the mode the folder is moving
|
||||||
// to, so `sync list` never reads as if the request was dropped.
|
// to, so `sync list` never reads as if the request was dropped.
|
||||||
let mode = match &f.pending_mode {
|
let mode = match &f.pending_mode {
|
||||||
@@ -1915,6 +1908,15 @@ fn format_epoch(secs: i64) -> String {
|
|||||||
format!("{m:02}-{d:02} {h:02}:{mi:02}")
|
format!("{m:02}-{d:02} {h:02}:{mi:02}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The `synced:` column of `sync list` and `devices list`: when the last pass
|
||||||
|
/// finished, or `never`. The daemon reports 0 for a folder that never synced.
|
||||||
|
fn last_synced(secs: Option<i64>) -> String {
|
||||||
|
match secs {
|
||||||
|
Some(secs) if secs > 0 => format_epoch(secs),
|
||||||
|
_ => "never".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn cmd_leave(uid: String) -> Result<()> {
|
fn cmd_leave(uid: String) -> Result<()> {
|
||||||
ok_or_bail(control_request(CtlRequest::LeaveShared { uid })?)
|
ok_or_bail(control_request(CtlRequest::LeaveShared { uid })?)
|
||||||
}
|
}
|
||||||
@@ -4452,6 +4454,14 @@ mod login_wait_tests {
|
|||||||
assert_eq!(format_epoch_utc(-86_400), "1969-12-31");
|
assert_eq!(format_epoch_utc(-86_400), "1969-12-31");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn last_synced_shows_a_time_not_epoch_seconds() {
|
||||||
|
// B278: issue #46 showed `synced: 1793570850`.
|
||||||
|
assert_eq!(last_synced(Some(1_793_570_850)), "11-01 22:07");
|
||||||
|
assert_eq!(last_synced(Some(0)), "never");
|
||||||
|
assert_eq!(last_synced(None), "never");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn a_forged_looking_invitation_is_flagged_not_stated() {
|
fn a_forged_looking_invitation_is_flagged_not_stated() {
|
||||||
let mut entry = pdfs_core::control::DirEntry {
|
let mut entry = pdfs_core::control::DirEntry {
|
||||||
|
|||||||
+24
-1
@@ -109,6 +109,7 @@ a live account since.
|
|||||||
|
|
||||||
| Entry | Title |
|
| Entry | Title |
|
||||||
|---|---|
|
|---|---|
|
||||||
|
| [B278](#b278--sync-list-and-devices-list-show-the-last-sync-as-epoch-seconds) | `sync list` and `devices list` show the last sync as epoch seconds |
|
||||||
| [B277](#b277--my-files-mounted-over-a-folder-with-files-in-it-and-hid-them) | My files mounted over a folder with files in it, and hid them |
|
| [B277](#b277--my-files-mounted-over-a-folder-with-files-in-it-and-hid-them) | My files mounted over a folder with files in it, and hid them |
|
||||||
| [B274](#b274--opening-a-file-for-writing-fails-with-eio-while-its-queued-revision-lands) | Opening a file for writing fails with EIO while its queued revision lands |
|
| [B274](#b274--opening-a-file-for-writing-fails-with-eio-while-its-queued-revision-lands) | Opening a file for writing fails with EIO while its queued revision lands |
|
||||||
| [B272](#b272--after-a-folder-is-removed-and-added-again-its-file-events-go-to-the-old-id) | After a folder is removed and added again, its file events go to the old id |
|
| [B272](#b272--after-a-folder-is-removed-and-added-again-its-file-events-go-to-the-old-id) | After a folder is removed and added again, its file events go to the old id |
|
||||||
@@ -380,6 +381,26 @@ a live account since.
|
|||||||
|
|
||||||
Newest first.
|
Newest first.
|
||||||
|
|
||||||
|
### B278 — `sync list` and `devices list` show the last sync as epoch seconds
|
||||||
|
|
||||||
|
**Status:** Fixed, not verified live
|
||||||
|
**Found:** 2026-11-02, issue #46. The reporter's `pdfs sync list` on 3.6.0 read
|
||||||
|
`synced: 1793570850`, a pass that finished at 2026-11-01 22:07 UTC.
|
||||||
|
**Where:** `cmd_sync` and `cmd_devices` in `crates/pdfs-cli/src/main.rs`
|
||||||
|
|
||||||
|
**Repro:** Let a synced folder finish one pass and run `pdfs sync list`, or `pdfs devices list`
|
||||||
|
on an account with a device that synced.
|
||||||
|
|
||||||
|
**Cause.** Both commands printed `last_sync` with `to_string()`. The activity feed already
|
||||||
|
formats the same epoch seconds with `format_epoch`.
|
||||||
|
|
||||||
|
**Fix.** Both columns go through `last_synced`, which prints `MM-DD HH:MM` in UTC like
|
||||||
|
`pdfs activity`, and `never` for 0 or no value. `--json` output is unchanged.
|
||||||
|
|
||||||
|
**Test:** `last_synced_shows_a_time_not_epoch_seconds` in `crates/pdfs-cli/src/main.rs`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
### B277 — My files mounted over a folder with files in it, and hid them
|
### B277 — My files mounted over a folder with files in it, and hid them
|
||||||
|
|
||||||
**Status:** Fixed, not verified live
|
**Status:** Fixed, not verified live
|
||||||
@@ -575,7 +596,9 @@ folder list has now.
|
|||||||
**Status:** Fixed, not verified live
|
**Status:** Fixed, not verified live
|
||||||
**Found:** 2026-10-31, code audit after issue #46: a folder of about 19,900 items restored on a
|
**Found:** 2026-10-31, code audit after issue #46: a folder of about 19,900 items restored on a
|
||||||
second computer sat at `scanning…` with nothing downloaded, and the journal showed
|
second computer sat at `scanning…` with nothing downloaded, and the journal showed
|
||||||
`RequestTimeout (http 408)`.
|
`RequestTimeout (http 408)`. On 2026-11-01 the reporter's 3.6.0 journal showed the same pass
|
||||||
|
failing four times in four minutes with `reconcile failed id=1 error=enumerate …: HTTP transport
|
||||||
|
error`, after the laptop woke from sleep; a later pass finished.
|
||||||
**Where:** `walk_remote` in `crates/pdfs-fuse/src/sync.rs`
|
**Where:** `walk_remote` in `crates/pdfs-fuse/src/sync.rs`
|
||||||
|
|
||||||
**Repro:** Restore or add a mirror folder with tens of thousands of items on Drive, on a link
|
**Repro:** Restore or add a mirror folder with tens of thousands of items on Drive, on a link
|
||||||
|
|||||||
@@ -11,6 +11,10 @@ scratch (user data in `staging/` and `recovery/` is never touched by this).
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [3.7.0] — 2026-11-02
|
||||||
|
|
||||||
|
Schema: **44**, unchanged.
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- **The app and the tray say why your Drive does not open** (B263, #40). When the service runs
|
- **The app and the tray say why your Drive does not open** (B263, #40). When the service runs
|
||||||
@@ -78,6 +82,9 @@ scratch (user data in `staging/` and `recovery/` is never touched by this).
|
|||||||
- **A restore that skipped folders is reported as failed**, with the reason for each, instead of
|
- **A restore that skipped folders is reported as failed**, with the reason for each, instead of
|
||||||
"restored 0 folder(s)" as a success (B269).
|
"restored 0 folder(s)" as a success (B269).
|
||||||
|
|
||||||
|
- **`pdfs sync list` and `pdfs devices list` show when a folder last synced as a time**, such as
|
||||||
|
`synced: 11-01 22:07` in UTC like `pdfs activity`, instead of seconds since 1970 (B278, #46).
|
||||||
|
|
||||||
- **"You're offline" no longer appears for a cache or database error** when pinning, unpinning,
|
- **"You're offline" no longer appears for a cache or database error** when pinning, unpinning,
|
||||||
searching or loading a folder (B266, #38). The app shows the actual error.
|
searching or loading a folder (B266, #38). The app shows the actual error.
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -102,7 +102,7 @@ That URL follows `main`. To stay on releases, pin the input to a release tag ins
|
|||||||
the tag to update:
|
the tag to update:
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
inputs.proton-drive-linux.url = "github:narrrl/proton-drive-linux/v3.6.0";
|
inputs.proton-drive-linux.url = "github:narrrl/proton-drive-linux/v3.7.0";
|
||||||
```
|
```
|
||||||
|
|
||||||
Each release tag is built with Nix before the release is published.
|
Each release tag is built with Nix before the release is published.
|
||||||
|
|||||||
+1
-1
@@ -9,7 +9,7 @@
|
|||||||
# Build + install: cd packaging && makepkg -fi
|
# Build + install: cd packaging && makepkg -fi
|
||||||
|
|
||||||
pkgname=proton-drive-linux
|
pkgname=proton-drive-linux
|
||||||
pkgver=3.6.0
|
pkgver=3.7.0
|
||||||
pkgrel=1
|
pkgrel=1
|
||||||
pkgdesc="Unofficial Proton Drive client for Linux: files-on-demand FUSE mount, CLI, GTK4 app + tray"
|
pkgdesc="Unofficial Proton Drive client for Linux: files-on-demand FUSE mount, CLI, GTK4 app + tray"
|
||||||
arch=('x86_64')
|
arch=('x86_64')
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
# Match Arch PKGBUILD `!lto` — LTO has broken some GTK/Rust links in practice.
|
# Match Arch PKGBUILD `!lto` — LTO has broken some GTK/Rust links in practice.
|
||||||
%global _lto_cflags %{nil}
|
%global _lto_cflags %{nil}
|
||||||
|
|
||||||
%{!?version: %global version 3.6.0}
|
%{!?version: %global version 3.7.0}
|
||||||
%global forge https://github.com/narrrl/proton-drive-linux
|
%global forge https://github.com/narrrl/proton-drive-linux
|
||||||
# Files come from the checkout, or from the unpacked tag archive.
|
# Files come from the checkout, or from the unpacked tag archive.
|
||||||
%global src %{?git_dir}%{!?git_dir:.}
|
%global src %{?git_dir}%{!?git_dir:.}
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@
|
|||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: proton-drive-linux 3.6.0\n"
|
"Project-Id-Version: proton-drive-linux 3.7.0\n"
|
||||||
"Report-Msgid-Bugs-To: https://github.com/narrrl/proton-drive-linux/issues\n"
|
"Report-Msgid-Bugs-To: https://github.com/narrrl/proton-drive-linux/issues\n"
|
||||||
"POT-Creation-Date: 2026-11-01 17:51+0100\n"
|
"POT-Creation-Date: 2026-11-01 17:51+0100\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
|
|||||||
Reference in new issue
Block a user