~ knotless Search/
↑↓ move↵ open⇧↵ all results

chadtmiller.com/knotless

git that lives in your Atmosphere account

knotless.dev
1 collaborator

knotless 0.13.0 Latest 2 packages, 1 image

1
10

Searching repositories finds those named as searched first, and your own

Merged
Merged chadtmiller.com asked to merge into main from chadtmiller.com/knotless:serve/own-repos-first

What changes

A search for repositories puts first the ones named as searched, ignoring case, originals before forks: search knotless and chadtmiller.com/knotless comes first, before the newer forks of it and the repositories that only mention it, for anyone, signed in or not. Asked as an account, its own come first among those, and its other public repositories that match follow them. The rest are newest first, as before. Both the header's search and the results page ask dev.knotless.listRepos, so both change.

Why

Results were newest first and nothing else, so every fork made since, and every newer repository naming the project in its description, outranked the one meant. Ranking originals over forks alone would not fix that, as the newer originals that mention it would still lead; ranking every page by it would need a new cursor and a sort of every match. The name, looked up by a new index (repo_name, name COLLATE NOCASE), finds the few meant, which go first on the first page, as a viewer's readable private repositories already did.

Each kind put first is left out of the newest-first rest when all of it fits on the first page, so none shows twice. When more match than limit, the first page shows limit of them and the rest list them all again in their place, so none is lost.

How it was checked

forks_pulls_reviews_and_merges in tests/forge.rs: forkable and its newer fork, searched as no one, the original first; a page of one at a time, the original, the fork, then the original again in its place, then nothing; asked as the fork's owner, the fork first; asked as the original's owner a page at a time, theirs, the fork, then nothing. just lex and just docs pass. Left to CI: check, test and the query plans (the name by repo_name, the viewer's by repo_key, each sorting the few it finds).

Shortcomings

A name only ranks first when it is the whole query: knotless cli finds no repository named so, and lists newest first.

Changeset: none

🤖 Generated with Claude Code

Approved

When a viewer searches, list_repos now puts their own matching public repositories after the private ones and before the newest-first rest. It leaves them out of the rest only when all of them fit within limit. The docs, lexicon description and test are updated. I found no bug in the case the test covers: everything fits, and the first page is correct.

One flaw in the overflow case, which the body doesn't mention: when the viewer has more than limit matching public repositories, the first page hoists their newest limit. Later pages hoist nothing (theirs is truncated to 0) and the rest query no longer excludes the owner. A hoisted repository that is older than the first rest page therefore shows again on a later page. The body says "none shows twice" only for the fits case, but the code comment and docs suggest more than they deliver. This is a small duplication, not a loss. If you want to fix it, make the rest query skip the owner's repositories newer than the oldest one hoisted. Otherwise say in the docs that duplicates can occur past the first page.

The overflow path has no test, since the test only has one matching repository per owner at limit=1.

crates/knotless-serve/src/appview.rsline 203Outdated
let marked = private.len();
let hoisted: std::collections::HashSet<_> = theirs.iter().map(|r| r.uri.clone()).collect();
let rest = repos.into_iter().filter(|r| !hoisted.contains(&r.uri));
let repos: Vec<_> = private.into_iter().chain(theirs).chain(rest).collect();
review.knotless.dev

With more than limit own matches, later pages have an empty theirs and not_owner is unset, so own repositories hoisted on page one can reappear on a later page.

Approved

The pull makes the first page of a repository search put the repositories named exactly as searched first, ignoring case and with originals before forks. When signed in, the asker's own come first among those, and their other matching public repositories follow. Each kind put first is left out of the newest-first rest only when all of it fits within limit.

I found nothing that must change. I traced the new test's cases through the code by hand and did not run them. The pull body says CI is left to run check, test and the query plans, and I read no results for them.

My earlier concern was that an overflowing set of the viewer's own repositories could show again on later pages. The docs and lexicon now state this: when more match than limit, the rest lists them all again in their place. That is deliberate, nothing is lost, and the test covers the name case at limit=1.

The docs, the lexicon description and the code comments agree with the behaviour.

Approved

The pull makes the first page of a repository search put the repositories named exactly as searched first, ignoring case and with originals before forks. When signed in, the asker's own come first among those, and their other matching public repositories follow. A kind put first is left out of the newest-first rest only when all of it fits within limit. Otherwise the rest lists it again in its place, which the docs and lexicon now say.

I found nothing that must change. I read the full pull diff (the repo_diff from my last approved commit returned the base's changes too, so I didn't use it) and traced the new test's cases by hand. I did not run them or read any check results.

  • first_of runs on every page, so the exclusions apply consistently to later pages. Later pages also drop exact and own from the output, so there is no duplication.
  • Dedup by URI on the first page covers the overlap between the named and own sets.
  • The test checks the original-first order for anonymous askers, the fork-first order for the fork's owner, and the paging at limit=1.
Approved

Since my approval, the only change is in a test in index.rs. The fake repo table gains a name column, and the index.name(...) error assertion is removed. I only read this diff and ran nothing. I can't tell whether the removed assertion is dropped because that method is gone or because it no longer errors on this schema. Either way it is test-only and doesn't affect what I approved.

Merged as d73bbf9