pseek 3.7.0__tar.gz → 3.7.1__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.
- {pseek-3.7.0 → pseek-3.7.1}/PKG-INFO +11 -9
- {pseek-3.7.0 → pseek-3.7.1}/README.md +10 -8
- {pseek-3.7.0 → pseek-3.7.1}/pseek/cli.py +2 -2
- {pseek-3.7.0 → pseek-3.7.1}/pseek/searcher.py +65 -25
- {pseek-3.7.0 → pseek-3.7.1}/pseek/utils.py +1 -1
- {pseek-3.7.0 → pseek-3.7.1}/pyproject.toml +1 -1
- {pseek-3.7.0 → pseek-3.7.1}/.gitattributes +0 -0
- {pseek-3.7.0 → pseek-3.7.1}/.github/workflows/publish.yml +0 -0
- {pseek-3.7.0 → pseek-3.7.1}/.gitignore +0 -0
- {pseek-3.7.0 → pseek-3.7.1}/Cargo.lock +0 -0
- {pseek-3.7.0 → pseek-3.7.1}/Cargo.toml +0 -0
- {pseek-3.7.0 → pseek-3.7.1}/LICENSE +0 -0
- {pseek-3.7.0 → pseek-3.7.1}/pseek/__init__.py +0 -0
- {pseek-3.7.0 → pseek-3.7.1}/pseek/archive.py +0 -0
- {pseek-3.7.0 → pseek-3.7.1}/pseek/compound_extensions +0 -0
- {pseek-3.7.0 → pseek-3.7.1}/pseek/parser.py +0 -0
- {pseek-3.7.0 → pseek-3.7.1}/pseek/structs.py +0 -0
- {pseek-3.7.0 → pseek-3.7.1}/scripts/check_version.py +0 -0
- {pseek-3.7.0 → pseek-3.7.1}/src/lib.rs +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pseek
|
|
3
|
-
Version: 3.7.
|
|
3
|
+
Version: 3.7.1
|
|
4
4
|
Classifier: Development Status :: 5 - Production/Stable
|
|
5
5
|
Classifier: Environment :: Console
|
|
6
6
|
Classifier: Intended Audience :: Developers
|
|
@@ -273,6 +273,8 @@ psk backup --directory
|
|
|
273
273
|
psk TODO --content
|
|
274
274
|
```
|
|
275
275
|
|
|
276
|
+
> **Note:** When searching through file contents, binary files are automatically ignored, and this behavior cannot be changed. If null bytes are present within the first 8 KiB of a file, it is identified as a binary file (The entire file is not examined, in order to increase speed).
|
|
277
|
+
|
|
276
278
|
### Search Everywhere
|
|
277
279
|
|
|
278
280
|
```bash
|
|
@@ -757,12 +759,12 @@ Controls how deep the search goes inside directories.
|
|
|
757
759
|
A depth of `0` means that only base path's immediate contents are searched; subdirectories are not entered.
|
|
758
760
|
|
|
759
761
|
```text
|
|
760
|
-
project/
|
|
761
|
-
├── file.txt
|
|
762
|
-
├── folder1/
|
|
763
|
-
│ ├── file.txt
|
|
764
|
-
│ └── folder2/
|
|
765
|
-
│ └── file.txt
|
|
762
|
+
project/ <- base directory
|
|
763
|
+
├── file.txt <- depth 0
|
|
764
|
+
├── folder1/ <- depth 0
|
|
765
|
+
│ ├── file.txt <- depth 1
|
|
766
|
+
│ └── folder2/ <- depth 1
|
|
767
|
+
│ └── file.txt <- depth 2
|
|
766
768
|
```
|
|
767
769
|
|
|
768
770
|
`--depth` can be specified multiple times to search non-contiguous depth ranges:
|
|
@@ -965,7 +967,7 @@ If the search exceeds the limit, it will be terminated. Results found before the
|
|
|
965
967
|
Display a summary of the search, including result counts, scanned paths, archive information, and search time.
|
|
966
968
|
|
|
967
969
|
```bash
|
|
968
|
-
pseek config --stats
|
|
970
|
+
pseek config --archive --stats
|
|
969
971
|
```
|
|
970
972
|
|
|
971
973
|
Example output:
|
|
@@ -974,7 +976,7 @@ Example output:
|
|
|
974
976
|
Statistics
|
|
975
977
|
────────────────
|
|
976
978
|
Results
|
|
977
|
-
Files: 12
|
|
979
|
+
Files matched: 12
|
|
978
980
|
Directories matched: 3
|
|
979
981
|
Files with matched content: 8
|
|
980
982
|
Lines matched: 24
|
|
@@ -245,6 +245,8 @@ psk backup --directory
|
|
|
245
245
|
psk TODO --content
|
|
246
246
|
```
|
|
247
247
|
|
|
248
|
+
> **Note:** When searching through file contents, binary files are automatically ignored, and this behavior cannot be changed. If null bytes are present within the first 8 KiB of a file, it is identified as a binary file (The entire file is not examined, in order to increase speed).
|
|
249
|
+
|
|
248
250
|
### Search Everywhere
|
|
249
251
|
|
|
250
252
|
```bash
|
|
@@ -729,12 +731,12 @@ Controls how deep the search goes inside directories.
|
|
|
729
731
|
A depth of `0` means that only base path's immediate contents are searched; subdirectories are not entered.
|
|
730
732
|
|
|
731
733
|
```text
|
|
732
|
-
project/
|
|
733
|
-
├── file.txt
|
|
734
|
-
├── folder1/
|
|
735
|
-
│ ├── file.txt
|
|
736
|
-
│ └── folder2/
|
|
737
|
-
│ └── file.txt
|
|
734
|
+
project/ <- base directory
|
|
735
|
+
├── file.txt <- depth 0
|
|
736
|
+
├── folder1/ <- depth 0
|
|
737
|
+
│ ├── file.txt <- depth 1
|
|
738
|
+
│ └── folder2/ <- depth 1
|
|
739
|
+
│ └── file.txt <- depth 2
|
|
738
740
|
```
|
|
739
741
|
|
|
740
742
|
`--depth` can be specified multiple times to search non-contiguous depth ranges:
|
|
@@ -937,7 +939,7 @@ If the search exceeds the limit, it will be terminated. Results found before the
|
|
|
937
939
|
Display a summary of the search, including result counts, scanned paths, archive information, and search time.
|
|
938
940
|
|
|
939
941
|
```bash
|
|
940
|
-
pseek config --stats
|
|
942
|
+
pseek config --archive --stats
|
|
941
943
|
```
|
|
942
944
|
|
|
943
945
|
Example output:
|
|
@@ -946,7 +948,7 @@ Example output:
|
|
|
946
948
|
Statistics
|
|
947
949
|
────────────────
|
|
948
950
|
Results
|
|
949
|
-
Files: 12
|
|
951
|
+
Files matched: 12
|
|
950
952
|
Directories matched: 3
|
|
951
953
|
Files with matched content: 8
|
|
952
954
|
Lines matched: 24
|
|
@@ -49,7 +49,7 @@ def build_highlight(text, matches):
|
|
|
49
49
|
return ''.join(parts)
|
|
50
50
|
|
|
51
51
|
|
|
52
|
-
def echo(results: dict, context:
|
|
52
|
+
def echo(results: dict, context: tuple[int, int]):
|
|
53
53
|
"""Display results with a specific format and color scheme"""
|
|
54
54
|
for match_type, datas in results.items():
|
|
55
55
|
if datas:
|
|
@@ -258,7 +258,7 @@ def search_with_timeout(config):
|
|
|
258
258
|
time.sleep(0.0005)
|
|
259
259
|
|
|
260
260
|
|
|
261
|
-
def check_rar_backend(archive_enabled: bool, tool_path: str, backend: str):
|
|
261
|
+
def check_rar_backend(archive_enabled: bool, tool_path: str | None, backend: str):
|
|
262
262
|
"""Check for the existence of rar backend or save and set it for rarfile"""
|
|
263
263
|
|
|
264
264
|
# Save backend path for later executions
|
|
@@ -7,6 +7,8 @@ from itertools import islice
|
|
|
7
7
|
from pathlib import Path
|
|
8
8
|
from threading import RLock
|
|
9
9
|
|
|
10
|
+
import click
|
|
11
|
+
|
|
10
12
|
from pseek import _pignore
|
|
11
13
|
|
|
12
14
|
from .archive import ARCHIVE_EXTS, extract_names_from_archive, extract_text_from_archive
|
|
@@ -378,6 +380,20 @@ def is_symlink_valid(entry):
|
|
|
378
380
|
return True
|
|
379
381
|
|
|
380
382
|
|
|
383
|
+
def needs_ignore_matcher(config) -> bool:
|
|
384
|
+
# In cases where all paths must be searched and
|
|
385
|
+
# there are no filtering rules,
|
|
386
|
+
# there is no need to create matcher.
|
|
387
|
+
return (
|
|
388
|
+
not config.hidden
|
|
389
|
+
or not config.no_git_ignore
|
|
390
|
+
or not config.no_ignore_dot
|
|
391
|
+
or not config.no_ignore_exclude
|
|
392
|
+
or not config.no_ignore_global
|
|
393
|
+
or bool(config.glob)
|
|
394
|
+
)
|
|
395
|
+
|
|
396
|
+
|
|
381
397
|
def walk_logic(path: Path, config, depth: int, matcher, ancestors: set):
|
|
382
398
|
"""Recursively walk a directory while pruning excluded subtrees"""
|
|
383
399
|
|
|
@@ -411,18 +427,27 @@ def walk_logic(path: Path, config, depth: int, matcher, ancestors: set):
|
|
|
411
427
|
continue
|
|
412
428
|
is_dir = False
|
|
413
429
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
430
|
+
if matcher is None:
|
|
431
|
+
ignored = False
|
|
432
|
+
whitelisted = False
|
|
433
|
+
should_descend = is_dir
|
|
434
|
+
else:
|
|
435
|
+
# Ignore rules / hidden filtering / glob logic
|
|
436
|
+
|
|
437
|
+
absolute_entry = (
|
|
438
|
+
Path(os.path.abspath(entry_path))
|
|
439
|
+
if not config.absolute_path
|
|
440
|
+
else entry_path
|
|
441
|
+
).as_posix()
|
|
442
|
+
|
|
443
|
+
try:
|
|
444
|
+
ignored, whitelisted, should_descend = matcher.match_path(
|
|
445
|
+
absolute_entry,
|
|
446
|
+
# We don't need target of symlink; symlink itself is always a file
|
|
447
|
+
is_dir if not entry.is_symlink() else False,
|
|
448
|
+
)
|
|
449
|
+
except RuntimeError:
|
|
450
|
+
continue
|
|
426
451
|
|
|
427
452
|
if ignored:
|
|
428
453
|
continue
|
|
@@ -433,7 +458,12 @@ def walk_logic(path: Path, config, depth: int, matcher, ancestors: set):
|
|
|
433
458
|
# This flag is used in seek func to indicate that this dir
|
|
434
459
|
# doesn't need to be displayed, even though it must still
|
|
435
460
|
# be included in metric calculation.
|
|
436
|
-
metric_only =
|
|
461
|
+
metric_only = (
|
|
462
|
+
is_dir
|
|
463
|
+
and matcher is not None
|
|
464
|
+
and matcher.has_positive_globs
|
|
465
|
+
and not whitelisted
|
|
466
|
+
)
|
|
437
467
|
|
|
438
468
|
# A symlink may be a valid filename-search candidate even
|
|
439
469
|
# when its target is not followed or cannot be resolved.
|
|
@@ -462,6 +492,7 @@ def walk(config):
|
|
|
462
492
|
"""Include paths define traversal roots, avoiding unnecessary traversal
|
|
463
493
|
of unrelated parts of the tree"""
|
|
464
494
|
roots = config.include or {config.path}
|
|
495
|
+
needs_matcher = needs_ignore_matcher(config)
|
|
465
496
|
|
|
466
497
|
for root in roots:
|
|
467
498
|
depth = len(root.relative_to(config.path).parts) - 1
|
|
@@ -473,18 +504,27 @@ def walk(config):
|
|
|
473
504
|
yield root.resolve(), False
|
|
474
505
|
|
|
475
506
|
if root.is_dir() and any(depth < d[1] for d in config.depth):
|
|
476
|
-
matcher =
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
507
|
+
matcher = None
|
|
508
|
+
|
|
509
|
+
if needs_matcher:
|
|
510
|
+
try:
|
|
511
|
+
matcher = _pignore.IgnoreMatcher(
|
|
512
|
+
Path(os.path.abspath(root)).as_posix(),
|
|
513
|
+
git_ignore=not config.no_git_ignore,
|
|
514
|
+
ignore=not config.no_ignore_dot,
|
|
515
|
+
git_exclude=not config.no_ignore_exclude,
|
|
516
|
+
git_global=not config.no_ignore_global,
|
|
517
|
+
parents=not config.no_ignore_parent,
|
|
518
|
+
require_git=not config.no_require_git,
|
|
519
|
+
hidden=not config.hidden,
|
|
520
|
+
globs=list(config.glob) or None,
|
|
521
|
+
glob_root=config.path.as_posix()
|
|
522
|
+
)
|
|
523
|
+
except ValueError as e:
|
|
524
|
+
raise click.BadParameter(e, param_hint='--glob')
|
|
525
|
+
except RuntimeError as e:
|
|
526
|
+
click.secho(e, fg='red')
|
|
527
|
+
raise click.exceptions.Exit(1)
|
|
488
528
|
|
|
489
529
|
yield from walk_logic(root, config, depth, matcher, set())
|
|
490
530
|
|
|
@@ -24,7 +24,7 @@ def compile_regex(txt, flags=0) -> re.Pattern | None:
|
|
|
24
24
|
raise click.exceptions.Exit(1)
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
def get_path_suffix(path: Path | str, is_dir: bool | None = None) -> str:
|
|
27
|
+
def get_path_suffix(path: Path | str, is_dir: bool | None = None) -> str | None:
|
|
28
28
|
""" If multiple file suffixes are valid, return them, otherwise return only the last suffix """
|
|
29
29
|
if isinstance(path, str):
|
|
30
30
|
path = Path(path)
|
|
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
|