Core and desktop comments describe the code to a stranger (#6224)
Android / Build, or is the channel already serving this? (push) Successful in 2s
CI & Build / Build now, or wait for Android? (push) Successful in 2s
CI & Build / Python lint (push) Successful in 2s
CI & Build / Python tests (push) Successful in 12s
CI & Build / Web typecheck and unit tests (push) Successful in 8s
Desktop (Tauri) / Build, or is the channel already serving this? (push) Successful in 2s
Android / Core and FFI clippy and tests (push) Successful in 1m3s
CI & Build / integration (push) Successful in 1m37s
CI & Build / Build & push image (push) Skipped
Desktop (Tauri) / Web tests, clippy, Rust tests and rustfmt (push) Successful in 2m40s
Desktop (Tauri) / Windows installer (cross-compiled) (push) Successful in 3m14s
Desktop (Tauri) / Tauri desktop (Linux) (push) Successful in 4m3s
Desktop (Tauri) / Update manifest (push) Successful in 4s
Android / Kotlin + Rust (APK) (push) Successful in 8m42s
Android / Build the server image (push) Successful in 1s
Android / Build, or is the channel already serving this? (push) Successful in 2s
CI & Build / Build now, or wait for Android? (push) Successful in 2s
CI & Build / Python lint (push) Successful in 2s
CI & Build / Python tests (push) Successful in 12s
CI & Build / Web typecheck and unit tests (push) Successful in 8s
Desktop (Tauri) / Build, or is the channel already serving this? (push) Successful in 2s
Android / Core and FFI clippy and tests (push) Successful in 1m3s
CI & Build / integration (push) Successful in 1m37s
CI & Build / Build & push image (push) Skipped
Desktop (Tauri) / Web tests, clippy, Rust tests and rustfmt (push) Successful in 2m40s
Desktop (Tauri) / Windows installer (cross-compiled) (push) Successful in 3m14s
Desktop (Tauri) / Tauri desktop (Linux) (push) Successful in 4m3s
Desktop (Tauri) / Update manifest (push) Successful in 4s
Android / Kotlin + Rust (APK) (push) Successful in 8m42s
Android / Build the server image (push) Successful in 1s
Milestone 546 "Bring the repo to the comment standard (rule 32) and compose defaults (rule 198)", step #6224 "Comment standard sweep: Rust core and desktop client". Doc comments and comments across inkwell-core, the Tauri app and desktop/packaging now say what the code does and the non-obvious why in the present tense. Gone: milestone tags (M10.x, M11.3, M13, M304, M315, M314, milestone 325), issue and Scribe-note numbers, family-idea and family-rule citations, the run numbers and commit hashes behind past bugs, and the narration of what used to be (the stable channel before it held its own bundles, CARGO_PKG_VERSION as the shown version, the MANIFEST_TAG split, the store's missing tests, the old PKGBUILD). The schema's migration notes keep what each step does and why, without "until now". The forge is called the forge rather than Forgejo. Hazards stay as facts: the dev-rolling tag that must not shadow the branch, the manifest matched on this build's version, the APK's fixed name surviving the prune, the LIKE guard in v9, -wal/-shm moving with the renamed store, panic = abort ending the app. 34 files, comments only: a comment-stripping diff of every changed file against HEAD is identical. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+28
-37
@@ -48,11 +48,9 @@ fn load_labels(conn: &Connection, note_id: &str) -> rusqlite::Result<Vec<NoteLab
|
||||
|
||||
/// The note's checklist, read out of its body. No query, because there is no table.
|
||||
///
|
||||
/// A `- [ ] milk` line IS the item (M304). The id is the item's ORDINAL rather than a
|
||||
/// uuid — which is all it ever amounted to anyway, since `push.rs` sent text and
|
||||
/// checked and never an id, and both sides replaced the whole list on every sync. It
|
||||
/// is also exactly what the rewriters in `derive` take, so a UI holding an id can act
|
||||
/// on it directly.
|
||||
/// A `- [ ] milk` line IS the item. The id is the item's ORDINAL rather than a uuid:
|
||||
/// sync carries text and checked, never an id, and the ordinal is what the rewriters
|
||||
/// in `derive` take, so a UI holding an id can act on it directly.
|
||||
fn items_of(body: &str) -> Vec<ChecklistItem> {
|
||||
derive::extract_items(body)
|
||||
.into_iter()
|
||||
@@ -122,10 +120,9 @@ fn load_note(conn: &Connection, id: &str) -> rusqlite::Result<Note> {
|
||||
permission, shared, shared_by_id, shared_by_name
|
||||
FROM notes WHERE id = ?1",
|
||||
[id],
|
||||
// By NAME, not by position. Dropping `color` shifted every column after it
|
||||
// and the two timestamps were missed (fa89da1): created_at read updated_at
|
||||
// and updated_at read trashed_at, with nothing failing. A name either
|
||||
// resolves or errors.
|
||||
// By NAME, not by position: dropping a column shifts every one after it, and
|
||||
// a positional read would then load the wrong timestamps with nothing
|
||||
// failing. A name either resolves or errors.
|
||||
|r| {
|
||||
Ok(Note {
|
||||
id: r.get("id")?,
|
||||
@@ -166,11 +163,11 @@ fn load_note(conn: &Connection, id: &str) -> rusqlite::Result<Note> {
|
||||
Ok(note)
|
||||
}
|
||||
|
||||
// ---- notes shared with this account (#5175) ---------------------------------
|
||||
// ---- notes shared with this account ------------------------------------------
|
||||
//
|
||||
// A note someone else owns arrives with `permission` `edit` (its text may change
|
||||
// here) or `view` (it may not). Its pin, archive and place on this board are this
|
||||
// account's own either way (#5176). Everything else about it — trash, reminders,
|
||||
// account's own either way. Everything else about it — trash, reminders,
|
||||
// labels, files — stays its owner's. The server enforces the same split;
|
||||
// refusing here as well tells the person at once, instead of letting an edit be made,
|
||||
// queued, and then thrown away by the next sync.
|
||||
@@ -268,21 +265,19 @@ fn find_or_create_label(conn: &Connection, name: &str) -> rusqlite::Result<Strin
|
||||
/// Attach the note's tag labels, LIFT its standalone tags out of the body, and write
|
||||
/// the shortened body back.
|
||||
///
|
||||
/// NAMED FOR THE MUTATION. It used to be `sync_tags` and only touched label rows; it
|
||||
/// now rewrites `notes.body`, and every caller writes the body just before calling —
|
||||
/// so this overwrites what they wrote, on purpose.
|
||||
/// NAMED FOR THE MUTATION: it rewrites `notes.body`, and every caller writes the body
|
||||
/// just before calling, so this overwrites what they wrote, on purpose.
|
||||
///
|
||||
/// `display_title` needs no attention here, unlike on the server: the core derives it
|
||||
/// on READ (`derive::display_title`, called from `load_note`) rather than storing
|
||||
/// it, so there is no persisted copy to go stale.
|
||||
///
|
||||
/// The two kinds of tag are handled differently, and that difference IS what `via_tag`
|
||||
/// means from here on — backed by text still in the body:
|
||||
/// means — backed by text still in the body:
|
||||
///
|
||||
/// standalone lifted out, attached as an ORDINARY label. Nothing derives it any
|
||||
/// more, and the way to remove it becomes the chip's ×.
|
||||
/// inline left in place, attached via_tag = 1, still detached when its text
|
||||
/// goes. Unchanged from before.
|
||||
/// standalone lifted out, attached as an ORDINARY label. Nothing derives it, and
|
||||
/// the way to remove it is the chip's ×.
|
||||
/// inline left in place, attached via_tag = 1, detached when its text goes.
|
||||
///
|
||||
/// Mirrors `_lift_and_reconcile_tags` in the server's `notes/tags.py`.
|
||||
fn lift_and_sync_tags(conn: &Connection, note_id: &str, body: &str) -> rusqlite::Result<()> {
|
||||
@@ -384,9 +379,8 @@ pub fn list_notes(conn: &Connection, q: &ListQuery) -> rusqlite::Result<Vec<Note
|
||||
|
||||
if let Some(f) = &q.facets {
|
||||
if let Some(text) = f.q.as_deref().filter(|s| !s.is_empty()) {
|
||||
// One placeholder, one bind. This pushed the pattern twice after the
|
||||
// title column went (95aa10c), and rusqlite refuses a count mismatch,
|
||||
// so every desktop search failed.
|
||||
// One placeholder, one bind: rusqlite refuses a count mismatch, which
|
||||
// would fail every desktop search.
|
||||
sql.push_str(" AND body LIKE ? ESCAPE '\\'");
|
||||
binds.push(format!("%{}%", escape_like(text)));
|
||||
}
|
||||
@@ -681,7 +675,7 @@ pub fn complete_reminder(conn: &Connection, id: &str) -> rusqlite::Result<Note>
|
||||
}
|
||||
|
||||
/// The longest snooze, in minutes: 30 days. The server's snooze route clamps to the
|
||||
/// same range (`notes.SNOOZE_MAX_MINUTES`), so a device and the web agree (#5386).
|
||||
/// same range (`notes.SNOOZE_MAX_MINUTES`), so a device and the web agree.
|
||||
pub const SNOOZE_MAX_MINUTES: i64 = 60 * 24 * 30;
|
||||
|
||||
pub fn snooze_reminder(conn: &Connection, id: &str, minutes: i64) -> rusqlite::Result<Note> {
|
||||
@@ -870,7 +864,7 @@ pub fn reorder(conn: &Connection, ordered_ids: &[String]) -> rusqlite::Result<()
|
||||
let total = ordered_ids.len() as i64;
|
||||
let at = now();
|
||||
for (i, id) in ordered_ids.iter().enumerate() {
|
||||
// A note someone shared with us moves on this account's board only (#5176),
|
||||
// A note someone shared with us moves on this account's board only,
|
||||
// stamped as its own state rather than as an edit.
|
||||
conn.execute(
|
||||
"UPDATE notes
|
||||
@@ -1024,11 +1018,10 @@ pub fn create_label(conn: &Connection, name: &str) -> rusqlite::Result<Label> {
|
||||
|
||||
/// Rename a label. Renaming ONTO a name another label already holds MERGES the two.
|
||||
///
|
||||
/// It cannot simply be an UPDATE: `idx_labels_name` is unique on `lower(name)`, so
|
||||
/// the bare statement failed with a raw SQLite "UNIQUE constraint failed" that
|
||||
/// reached the user as database internals. Merging is the operator's call, and it
|
||||
/// is the reading that matches what a person means — typing an existing tag's name
|
||||
/// onto this one says "these are the same thing."
|
||||
/// It cannot simply be an UPDATE: `idx_labels_name` is unique on `lower(name)`, so a
|
||||
/// bare statement fails with a raw SQLite "UNIQUE constraint failed". Merging is the
|
||||
/// reading that matches what a person means — typing an existing tag's name onto
|
||||
/// this one says "these are the same thing."
|
||||
///
|
||||
/// THE OLDER ROW SURVIVES, and takes the new spelling. Older rather than "the one
|
||||
/// that already held the name" because age is the property neither participant's
|
||||
@@ -1118,11 +1111,9 @@ pub fn merge_labels(
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
//! The store had no tests of its own until two bugs shipped in it unnoticed:
|
||||
//! `load_note` reading its timestamps from the wrong columns after one was
|
||||
//! dropped (fa89da1), and the board's text facet binding its pattern twice for
|
||||
//! one placeholder (95aa10c). Both are the kind of thing only a real query
|
||||
//! against a real schema catches, which is what every test here runs.
|
||||
//! Every test here runs a real query against a real schema: reading columns by
|
||||
//! the wrong position, or binding a pattern twice for one placeholder, is the
|
||||
//! kind of thing only that catches.
|
||||
|
||||
use super::*;
|
||||
|
||||
@@ -1158,7 +1149,7 @@ mod tests {
|
||||
notes.iter().map(|n| n.id.as_str()).collect()
|
||||
}
|
||||
|
||||
// ---- notes shared with this account (#5175) --------------------------------
|
||||
// ---- notes shared with this account ----------------------------------------
|
||||
|
||||
/// A note someone else owns, as the feed leaves it: clean, and held at `permission`.
|
||||
fn shared(conn: &Connection, id: &str, permission: &str) {
|
||||
@@ -1583,8 +1574,8 @@ mod tests {
|
||||
assert!(edited.labels.is_empty());
|
||||
}
|
||||
|
||||
/// Every letter folds, accented ones included, as on the server (#5385). With
|
||||
/// SQLite's lower() the second note minted a "CAFÉ" tag of its own.
|
||||
/// Every letter folds, accented ones included, as on the server; SQLite's lower()
|
||||
/// would mint a second "CAFÉ" tag.
|
||||
#[test]
|
||||
fn a_tag_spelled_with_different_accented_capitals_is_the_same_tag() {
|
||||
let conn = db();
|
||||
|
||||
Reference in New Issue
Block a user