rgapi 0.1.27__tar.gz → 0.1.28__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {rgapi-0.1.27 → rgapi-0.1.28}/Cargo.lock +3 -3
- {rgapi-0.1.27 → rgapi-0.1.28}/Cargo.toml +1 -1
- {rgapi-0.1.27 → rgapi-0.1.28}/DEV.md +1 -1
- {rgapi-0.1.27 → rgapi-0.1.28}/PKG-INFO +3 -3
- {rgapi-0.1.27 → rgapi-0.1.28}/README.md +1 -1
- {rgapi-0.1.27 → rgapi-0.1.28}/pyproject.toml +1 -1
- {rgapi-0.1.27 → rgapi-0.1.28}/src/search.rs +5 -3
- {rgapi-0.1.27 → rgapi-0.1.28}/tests/test_rgapi.py +6 -6
- {rgapi-0.1.27 → rgapi-0.1.28}/.github/workflows/ci.yml +0 -0
- {rgapi-0.1.27 → rgapi-0.1.28}/.gitignore +0 -0
- {rgapi-0.1.27 → rgapi-0.1.28}/LICENSE +0 -0
- {rgapi-0.1.27 → rgapi-0.1.28}/_config.yml +0 -0
- {rgapi-0.1.27 → rgapi-0.1.28}/_layouts/default.html +0 -0
- {rgapi-0.1.27 → rgapi-0.1.28}/python/rgapi/__init__.py +0 -0
- {rgapi-0.1.27 → rgapi-0.1.28}/python/rgapi/_cli.py +0 -0
- {rgapi-0.1.27 → rgapi-0.1.28}/python/rgapi/block.py +0 -0
- {rgapi-0.1.27 → rgapi-0.1.28}/python/rgapi/nb.py +0 -0
- {rgapi-0.1.27 → rgapi-0.1.28}/python/rgapi/skill.py +0 -0
- {rgapi-0.1.27 → rgapi-0.1.28}/rustfmt.toml +0 -0
- {rgapi-0.1.27 → rgapi-0.1.28}/src/block.rs +0 -0
- {rgapi-0.1.27 → rgapi-0.1.28}/src/lib.rs +0 -0
- {rgapi-0.1.27 → rgapi-0.1.28}/src/nb.rs +0 -0
- {rgapi-0.1.27 → rgapi-0.1.28}/src/python.rs +0 -0
- {rgapi-0.1.27 → rgapi-0.1.28}/src/walk.rs +0 -0
- {rgapi-0.1.27 → rgapi-0.1.28}/tests/test_async.py +0 -0
- {rgapi-0.1.27 → rgapi-0.1.28}/tools/bench.py +0 -0
|
@@ -330,7 +330,7 @@ checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4"
|
|
|
330
330
|
|
|
331
331
|
[[package]]
|
|
332
332
|
name = "rgapi"
|
|
333
|
-
version = "0.1.
|
|
333
|
+
version = "0.1.28"
|
|
334
334
|
dependencies = [
|
|
335
335
|
"crc32fast",
|
|
336
336
|
"globset",
|
|
@@ -443,9 +443,9 @@ checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca"
|
|
|
443
443
|
|
|
444
444
|
[[package]]
|
|
445
445
|
name = "unicode-ident"
|
|
446
|
-
version = "1.0.
|
|
446
|
+
version = "1.0.26"
|
|
447
447
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
448
|
-
checksum = "
|
|
448
|
+
checksum = "d245f478577f809a851594d02313b640fb437e0bb33866753cff937863096954"
|
|
449
449
|
|
|
450
450
|
[[package]]
|
|
451
451
|
name = "walkdir"
|
|
@@ -38,7 +38,7 @@ The GitHub workflow builds wheels for Python 3.10-3.13 on Linux and macOS and pu
|
|
|
38
38
|
|
|
39
39
|
## Design notes
|
|
40
40
|
|
|
41
|
-
Python discovery and `paths=True` results contain absolute `pathlib.Path` objects. Structured search rows retain root-relative string labels with `/` separators. Traversal uses `ignore::WalkParallel`, so result order is not part of the API contract. Search results are structured rows; collected result lists use rg-style `str()` and notebook display. `SearchLine.lnhash` is computed with the same CRC-32-based line-content hash format as exhash (`lineno|hash|`, low
|
|
41
|
+
Python discovery and `paths=True` results contain absolute `pathlib.Path` objects. Structured search rows retain root-relative string labels with `/` separators. Traversal uses `ignore::WalkParallel`, so result order is not part of the API contract. Search results are structured rows; collected result lists use rg-style `str()` and notebook display. `SearchLine.lnhash` is computed with the same CRC-32-based line-content hash format as exhash (`lineno|hash|`, low 12 bits of CRC-32 over the line's UTF-8 bytes, encoded as two Base64url characters); `lnhashs=True` only changes row display, not `line_number` or matching behavior. Path regexes filter returned/searched paths; `skip_dir` and `skip_dir_re` prune traversal through `ignore::WalkBuilder::filter_entry`. Depth, size, filesystem, hidden, and ignore options use `ignore::WalkBuilder` settings. Discovery checks root links with `symlink_metadata` and returns an unfollowed link through a ready stream without a worker. This also supports dangling roots, which the underlying walker would reject. Other discovery roots use absolute paths without canonicalizing. Content searches retain canonical root resolution. `rg_iter` exposes the same parallel search stream that `rg` collects by default; `paths=True` and `count=True` consume that stream with different reducers. Text search skips binary files and invalid UTF-8 content.
|
|
42
42
|
|
|
43
43
|
Streaming engine: `walk.rs` owns the generic machinery. `StreamIter<T>` is the worker-thread-plus-bounded-channel iterator (`sync_channel(8192)`, so producers block rather than buffer without limit when a consumer lags), and `spawn_walk` owns the shared scaffold: walker config, panic catching, cancel flag, and worker thread. `rg_iter` (`T = SearchLine`), `block_iter` (`T = SearchBlock`), `nb_iter` (`T = NbCell`), and `find_iter` (`T = PathBuf`, the path walk) plug entry closures into that engine. Block search reads each file once, searches it once, groups nonblank lines into blocks, maps matching lines to their blocks, and expands context by block index. Each `SearchBlock` carries numeric boundaries plus hashes for its first and last source lines. Python keeps both and chooses the displayed address without another file read.
|
|
44
44
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rgapi
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.28
|
|
4
4
|
Classifier: Programming Language :: Rust
|
|
5
5
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
6
|
-
Requires-Dist: fastcore>=
|
|
6
|
+
Requires-Dist: fastcore>=2.2.29
|
|
7
7
|
Requires-Dist: fastship>=0.0.12 ; extra == 'dev'
|
|
8
8
|
Requires-Dist: maturin>=1.0,<2.0 ; extra == 'dev'
|
|
9
9
|
Requires-Dist: pytest ; extra == 'dev'
|
|
@@ -168,7 +168,7 @@ rg("TODO", ".", summary=True, context=1, maxlen=120)
|
|
|
168
168
|
|
|
169
169
|
The result is `BlockResults`, a list of `SearchBlock` objects. Each block has `path`, `block_index`, `start_line`, `end_line`, `start_lnhash`, `end_lnhash`, `kind`, full `source`, and `matches`.
|
|
170
170
|
|
|
171
|
-
Matches display as `path:start-end:source`. Context displays as `path:start-end-source`. With `lnhashs=True`, the range uses copyable boundary addresses such as `path:4|
|
|
171
|
+
Matches display as `path:start-end:source`. Context displays as `path:start-end-source`. With `lnhashs=True`, the range uses copyable boundary addresses such as `path:4|Py|,6|HD|:source`. Newline runs display as `¶`. `maxlen` limits the displayed text without changing `source` or `asdict()`.
|
|
172
172
|
|
|
173
173
|
In summary mode, `before_context`, `after_context`, and `context` count neighbouring blocks. `max_results` counts matching blocks and retains their context. `summary=True` cannot be combined with `paths` or `count`. It can be combined with `lnhash` for copyable block boundaries.
|
|
174
174
|
|
|
@@ -147,7 +147,7 @@ rg("TODO", ".", summary=True, context=1, maxlen=120)
|
|
|
147
147
|
|
|
148
148
|
The result is `BlockResults`, a list of `SearchBlock` objects. Each block has `path`, `block_index`, `start_line`, `end_line`, `start_lnhash`, `end_lnhash`, `kind`, full `source`, and `matches`.
|
|
149
149
|
|
|
150
|
-
Matches display as `path:start-end:source`. Context displays as `path:start-end-source`. With `lnhashs=True`, the range uses copyable boundary addresses such as `path:4|
|
|
150
|
+
Matches display as `path:start-end:source`. Context displays as `path:start-end-source`. With `lnhashs=True`, the range uses copyable boundary addresses such as `path:4|Py|,6|HD|:source`. Newline runs display as `¶`. `maxlen` limits the displayed text without changing `source` or `asdict()`.
|
|
151
151
|
|
|
152
152
|
In summary mode, `before_context`, `after_context`, and `context` count neighbouring blocks. `max_results` counts matching blocks and retains their context. `summary=True` cannot be combined with `paths` or `count`. It can be combined with `lnhash` for copyable block boundaries.
|
|
153
153
|
|
|
@@ -14,7 +14,7 @@ classifiers = [
|
|
|
14
14
|
"Programming Language :: Rust",
|
|
15
15
|
"Programming Language :: Python :: Implementation :: CPython",
|
|
16
16
|
]
|
|
17
|
-
dependencies = ["fastcore>=
|
|
17
|
+
dependencies = ["fastcore>=2.2.29"]
|
|
18
18
|
|
|
19
19
|
[project.optional-dependencies]
|
|
20
20
|
dev = ["fastship>=0.0.12", "maturin>=1.0,<2.0", "pytest"]
|
|
@@ -185,9 +185,11 @@ pub fn compile_regex(pattern: &str, case_sensitive: Option<bool>, smart_case: bo
|
|
|
185
185
|
builder.build(pattern).map_err(|e| RgApiError::new(e.to_string()))
|
|
186
186
|
}
|
|
187
187
|
|
|
188
|
-
fn
|
|
189
|
-
|
|
190
|
-
|
|
188
|
+
pub(crate) fn format_lnhash(lineno: u64, line: &str) -> String {
|
|
189
|
+
const ALPHABET: &[u8; 64] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
|
190
|
+
let hash = crc32fast::hash(line.as_bytes()) as usize;
|
|
191
|
+
format!("{}|{}{}|", lineno, ALPHABET[(hash >> 6) & 63] as char, ALPHABET[hash & 63] as char)
|
|
192
|
+
}
|
|
191
193
|
|
|
192
194
|
pub fn search_path(
|
|
193
195
|
path: &Path,
|
|
@@ -185,11 +185,11 @@ def test_depth_size_and_filesystem_options(tmp_path):
|
|
|
185
185
|
assert [r.path for r in rg("TODO", str(tmp_path), min_depth=2, max_filesize=5)] == ["sub/small.txt"]
|
|
186
186
|
|
|
187
187
|
|
|
188
|
-
def
|
|
189
|
-
import
|
|
188
|
+
def test_lnhash_matches_fastcore(tmp_path):
|
|
189
|
+
from fastcore.tools import lnhash as py_hash
|
|
190
190
|
make_tree(tmp_path)
|
|
191
|
-
row
|
|
192
|
-
|
|
191
|
+
for row in rg(".", str(tmp_path)):
|
|
192
|
+
assert row.lnhash == py_hash(row.line_number, row.line)
|
|
193
193
|
|
|
194
194
|
|
|
195
195
|
def test_rg_returns_structured_matches_context_and_relative_paths(tmp_path):
|
|
@@ -214,8 +214,8 @@ def test_rg_returns_structured_matches_context_and_relative_paths(tmp_path):
|
|
|
214
214
|
except AssertionError as e: assert "mutually exclusive" in str(e)
|
|
215
215
|
else: assert False
|
|
216
216
|
addr = res[1].lnhash.split("|")
|
|
217
|
-
assert addr[0] == "2" and len(addr[1]) ==
|
|
218
|
-
assert
|
|
217
|
+
assert addr[0] == "2" and len(addr[1]) == 2 and addr[2:] == [""]
|
|
218
|
+
assert all(c in 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_' for c in addr[1])
|
|
219
219
|
expected = (f'SearchLine(kind="match", path="src/app.py", line_number=2, lnhash="{res[1].lnhash}", '
|
|
220
220
|
'line="TODO here", matches=[(0, 4)])')
|
|
221
221
|
assert repr(res[1]) == expected
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|