summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock755
-rw-r--r--Cargo.toml13
-rw-r--r--src/config.rs47
-rw-r--r--src/error.rs20
-rw-r--r--src/lib.rs2
-rw-r--r--src/main.rs28
-rw-r--r--src/project.rs82
-rw-r--r--src/project/git.rs105
-rw-r--r--src/project/path.rs57
-rw-r--r--src/search.rs77
-rw-r--r--src/search/entry.rs40
11 files changed, 214 insertions, 1012 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 465e909..fe69137 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -12,46 +12,22 @@ dependencies = [
]
[[package]]
-name = "android_system_properties"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
-dependencies = [
- "libc",
-]
-
-[[package]]
name = "anyhow"
version = "1.0.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6"
[[package]]
-name = "atomic"
-version = "0.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b88d82667eca772c4aa12f0f1348b3ae643424c8876448f3f7bd5787032e234c"
-dependencies = [
- "autocfg",
-]
-
-[[package]]
-name = "autocfg"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
-
-[[package]]
-name = "base64"
-version = "0.13.1"
+name = "bitflags"
+version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
-version = "1.3.2"
+version = "2.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+checksum = "24a6904aef64d73cf10ab17ebace7befb918b82164785cb89907993be7f83813"
[[package]]
name = "bstr"
@@ -63,18 +39,6 @@ dependencies = [
]
[[package]]
-name = "bumpalo"
-version = "3.11.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba"
-
-[[package]]
-name = "bytes"
-version = "1.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c"
-
-[[package]]
name = "cc"
version = "1.0.77"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -90,25 +54,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
-name = "chrono"
-version = "0.4.23"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f"
-dependencies = [
- "iana-time-zone",
- "num-integer",
- "num-traits",
- "serde",
- "winapi",
-]
-
-[[package]]
name = "clap"
-version = "4.0.27"
+version = "4.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0acbd8d28a0a60d7108d7ae850af6ba34cf2d1257fc646980e5f97ce14275966"
+checksum = "42dfd32784433290c51d92c438bb72ea5063797fc3cc9a21a8c4346bebbb2098"
dependencies = [
- "bitflags",
+ "bitflags 2.2.1",
"clap_derive",
"clap_lex",
"is-terminal",
@@ -119,9 +70,9 @@ dependencies = [
[[package]]
name = "clap_derive"
-version = "4.0.21"
+version = "4.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0177313f9f02afc995627906bbd8967e2be069f5261954222dac78290c2b9014"
+checksum = "fddf67631444a3a3e3e5ac51c36a5e01335302de677bd78759eaa90ab1f46644"
dependencies = [
"heck",
"proc-macro-error",
@@ -140,22 +91,6 @@ dependencies = [
]
[[package]]
-name = "codespan-reporting"
-version = "0.11.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e"
-dependencies = [
- "termcolor",
- "unicode-width",
-]
-
-[[package]]
-name = "core-foundation-sys"
-version = "0.8.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
-
-[[package]]
name = "crossbeam-utils"
version = "0.8.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -165,101 +100,6 @@ dependencies = [
]
[[package]]
-name = "ctor"
-version = "0.1.26"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096"
-dependencies = [
- "quote",
- "syn",
-]
-
-[[package]]
-name = "cxx"
-version = "1.0.82"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d4a41a86530d0fe7f5d9ea779916b7cadd2d4f9add748b99c2c029cbbdfaf453"
-dependencies = [
- "cc",
- "cxxbridge-flags",
- "cxxbridge-macro",
- "link-cplusplus",
-]
-
-[[package]]
-name = "cxx-build"
-version = "1.0.82"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "06416d667ff3e3ad2df1cd8cd8afae5da26cf9cec4d0825040f88b5ca659a2f0"
-dependencies = [
- "cc",
- "codespan-reporting",
- "once_cell",
- "proc-macro2",
- "quote",
- "scratch",
- "syn",
-]
-
-[[package]]
-name = "cxxbridge-flags"
-version = "1.0.82"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "820a9a2af1669deeef27cb271f476ffd196a2c4b6731336011e0ba63e2c7cf71"
-
-[[package]]
-name = "cxxbridge-macro"
-version = "1.0.82"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a08a6e2fcc370a089ad3b4aaf54db3b1b4cee38ddabce5896b33eb693275f470"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "darling"
-version = "0.14.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b0dd3cd20dc6b5a876612a6e5accfe7f3dd883db6d07acfbf14c128f61550dfa"
-dependencies = [
- "darling_core",
- "darling_macro",
-]
-
-[[package]]
-name = "darling_core"
-version = "0.14.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a784d2ccaf7c98501746bf0be29b2022ba41fd62a2e622af997a03e9f972859f"
-dependencies = [
- "fnv",
- "ident_case",
- "proc-macro2",
- "quote",
- "strsim",
- "syn",
-]
-
-[[package]]
-name = "darling_macro"
-version = "0.14.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7618812407e9402654622dd402b0a89dff9ba93badd6540781526117b92aab7e"
-dependencies = [
- "darling_core",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "diff"
-version = "0.1.13"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8"
-
-[[package]]
name = "errno"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -281,31 +121,6 @@ dependencies = [
]
[[package]]
-name = "fastrand"
-version = "1.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499"
-dependencies = [
- "instant",
-]
-
-[[package]]
-name = "figment"
-version = "0.10.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4e56602b469b2201400dec66a66aec5a9b8761ee97cd1b8c96ab2483fcc16cc9"
-dependencies = [
- "atomic",
- "parking_lot",
- "pear",
- "serde",
- "tempfile",
- "toml",
- "uncased",
- "version_check",
-]
-
-[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -326,7 +141,7 @@ version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2994bee4a3a6a51eb90c218523be382fd7ea09b16380b9312e9dbe955ff7c7d1"
dependencies = [
- "bitflags",
+ "bitflags 1.3.2",
"libc",
"libgit2-sys",
"log",
@@ -347,12 +162,6 @@ dependencies = [
]
[[package]]
-name = "hashbrown"
-version = "0.12.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
-
-[[package]]
name = "heck"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -360,15 +169,6 @@ checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
[[package]]
name = "hermit-abi"
-version = "0.1.19"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "hermit-abi"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
@@ -377,42 +177,6 @@ dependencies = [
]
[[package]]
-name = "hex"
-version = "0.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
-
-[[package]]
-name = "iana-time-zone"
-version = "0.1.53"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765"
-dependencies = [
- "android_system_properties",
- "core-foundation-sys",
- "iana-time-zone-haiku",
- "js-sys",
- "wasm-bindgen",
- "winapi",
-]
-
-[[package]]
-name = "iana-time-zone-haiku"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca"
-dependencies = [
- "cxx",
- "cxx-build",
-]
-
-[[package]]
-name = "ident_case"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
-
-[[package]]
name = "idna"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -441,32 +205,6 @@ dependencies = [
]
[[package]]
-name = "indexmap"
-version = "1.9.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
-dependencies = [
- "autocfg",
- "hashbrown",
- "serde",
-]
-
-[[package]]
-name = "inlinable_string"
-version = "0.1.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c8fae54786f62fb2918dcfae3d568594e50eb9b5c25bf04371af6fe7516452fb"
-
-[[package]]
-name = "instant"
-version = "0.1.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
-dependencies = [
- "cfg-if",
-]
-
-[[package]]
name = "io-lifetimes"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -478,23 +216,17 @@ dependencies = [
[[package]]
name = "is-terminal"
-version = "0.4.0"
+version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aae5bc6e2eb41c9def29a3e0f1306382807764b9b53112030eff57435667352d"
+checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189"
dependencies = [
- "hermit-abi 0.2.6",
+ "hermit-abi",
"io-lifetimes",
"rustix",
"windows-sys",
]
[[package]]
-name = "itoa"
-version = "1.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc"
-
-[[package]]
name = "jobserver"
version = "0.1.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -504,15 +236,6 @@ dependencies = [
]
[[package]]
-name = "js-sys"
-version = "0.3.60"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47"
-dependencies = [
- "wasm-bindgen",
-]
-
-[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -549,31 +272,12 @@ dependencies = [
]
[[package]]
-name = "link-cplusplus"
-version = "1.0.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9272ab7b96c9046fbc5bc56c06c117cb639fe2d509df0c421cad82d2915cf369"
-dependencies = [
- "cc",
-]
-
-[[package]]
name = "linux-raw-sys"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f9f08d8963a6c613f4b1a78f4f4a4dbfadf8e6545b2d72861731e4858b8b47f"
[[package]]
-name = "lock_api"
-version = "0.4.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df"
-dependencies = [
- "autocfg",
- "scopeguard",
-]
-
-[[package]]
name = "log"
version = "0.4.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -598,18 +302,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
-name = "mio"
-version = "0.8.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de"
-dependencies = [
- "libc",
- "log",
- "wasi",
- "windows-sys",
-]
-
-[[package]]
name = "nu-ansi-term"
version = "0.46.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -620,35 +312,6 @@ dependencies = [
]
[[package]]
-name = "num-integer"
-version = "0.1.45"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
-dependencies = [
- "autocfg",
- "num-traits",
-]
-
-[[package]]
-name = "num-traits"
-version = "0.2.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
-dependencies = [
- "autocfg",
-]
-
-[[package]]
-name = "num_cpus"
-version = "1.14.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5"
-dependencies = [
- "hermit-abi 0.1.19",
- "libc",
-]
-
-[[package]]
name = "once_cell"
version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -661,67 +324,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3baf96e39c5359d2eb0dd6ccb42c62b91d9678aa68160d261b9e0ccbf9e9dea9"
[[package]]
-name = "output_vt100"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "628223faebab4e3e40667ee0b2336d34a5b960ff60ea743ddfdbcf7770bcfb66"
-dependencies = [
- "winapi",
-]
-
-[[package]]
name = "overload"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
[[package]]
-name = "parking_lot"
-version = "0.12.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
-dependencies = [
- "lock_api",
- "parking_lot_core",
-]
-
-[[package]]
-name = "parking_lot_core"
-version = "0.9.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4dc9e0dc2adc1c69d09143aff38d3d30c5c3f0df0dad82e6d25547af174ebec0"
-dependencies = [
- "cfg-if",
- "libc",
- "redox_syscall",
- "smallvec",
- "windows-sys",
-]
-
-[[package]]
-name = "pear"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "15e44241c5e4c868e3eaa78b7c1848cadd6344ed4f54d029832d32b415a58702"
-dependencies = [
- "inlinable_string",
- "pear_codegen",
- "yansi",
-]
-
-[[package]]
-name = "pear_codegen"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "82a5ca643c2303ecb740d506539deba189e16f2754040a42901cd8105d0282d0"
-dependencies = [
- "proc-macro2",
- "proc-macro2-diagnostics",
- "quote",
- "syn",
-]
-
-[[package]]
name = "percent-encoding"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -740,18 +348,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160"
[[package]]
-name = "pretty_assertions"
-version = "1.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a25e9bcb20aa780fd0bb16b72403a9064d6b3f22f026946029acb941a50af755"
-dependencies = [
- "ctor",
- "diff",
- "output_vt100",
- "yansi",
-]
-
-[[package]]
name = "proc-macro-error"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -785,34 +381,13 @@ dependencies = [
]
[[package]]
-name = "proc-macro2-diagnostics"
-version = "0.9.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4bf29726d67464d49fa6224a1d07936a8c08bb3fba727c7493f6cf1616fdaada"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
- "version_check",
- "yansi",
-]
-
-[[package]]
name = "projectr"
version = "0.2.1"
dependencies = [
"anyhow",
"clap",
- "figment",
"git2",
"ignore",
- "pretty_assertions",
- "serde",
- "serde_with",
- "tempfile",
- "thiserror",
- "tokio",
- "toml",
"tracing",
"tracing-subscriber",
]
@@ -827,15 +402,6 @@ dependencies = [
]
[[package]]
-name = "redox_syscall"
-version = "0.2.16"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
-dependencies = [
- "bitflags",
-]
-
-[[package]]
name = "regex"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -862,21 +428,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
[[package]]
-name = "remove_dir_all"
-version = "0.5.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
-dependencies = [
- "winapi",
-]
-
-[[package]]
name = "rustix"
-version = "0.36.3"
+version = "0.36.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b1fbb4dfc4eb1d390c02df47760bb19a84bb80b301ecc947ab5406394d8223e"
+checksum = "d4fdebc4b395b7fbb9ab11e462e20ed9051e7b16e42d24042c776eca0ac81b03"
dependencies = [
- "bitflags",
+ "bitflags 1.3.2",
"errno",
"io-lifetimes",
"libc",
@@ -885,12 +442,6 @@ dependencies = [
]
[[package]]
-name = "ryu"
-version = "1.0.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
-
-[[package]]
name = "same-file"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -900,77 +451,6 @@ dependencies = [
]
[[package]]
-name = "scopeguard"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
-
-[[package]]
-name = "scratch"
-version = "1.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898"
-
-[[package]]
-name = "serde"
-version = "1.0.147"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965"
-dependencies = [
- "serde_derive",
-]
-
-[[package]]
-name = "serde_derive"
-version = "1.0.147"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "serde_json"
-version = "1.0.89"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db"
-dependencies = [
- "itoa",
- "ryu",
- "serde",
-]
-
-[[package]]
-name = "serde_with"
-version = "2.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "25bf4a5a814902cd1014dbccfa4d4560fb8432c779471e96e035602519f82eef"
-dependencies = [
- "base64",
- "chrono",
- "hex",
- "indexmap",
- "serde",
- "serde_json",
- "serde_with_macros",
- "time",
-]
-
-[[package]]
-name = "serde_with_macros"
-version = "2.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e3452b4c0f6c1e357f73fdb87cd1efabaa12acf328c7a528e252893baeb3f4aa"
-dependencies = [
- "darling",
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
name = "sharded-slab"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -980,31 +460,12 @@ dependencies = [
]
[[package]]
-name = "signal-hook-registry"
-version = "1.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0"
-dependencies = [
- "libc",
-]
-
-[[package]]
name = "smallvec"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
[[package]]
-name = "socket2"
-version = "0.4.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd"
-dependencies = [
- "libc",
- "winapi",
-]
-
-[[package]]
name = "strsim"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1022,20 +483,6 @@ dependencies = [
]
[[package]]
-name = "tempfile"
-version = "3.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4"
-dependencies = [
- "cfg-if",
- "fastrand",
- "libc",
- "redox_syscall",
- "remove_dir_all",
- "winapi",
-]
-
-[[package]]
name = "termcolor"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1045,26 +492,6 @@ dependencies = [
]
[[package]]
-name = "thiserror"
-version = "1.0.37"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e"
-dependencies = [
- "thiserror-impl",
-]
-
-[[package]]
-name = "thiserror-impl"
-version = "1.0.37"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
name = "thread_local"
version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1074,33 +501,6 @@ dependencies = [
]
[[package]]
-name = "time"
-version = "0.3.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376"
-dependencies = [
- "itoa",
- "serde",
- "time-core",
- "time-macros",
-]
-
-[[package]]
-name = "time-core"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd"
-
-[[package]]
-name = "time-macros"
-version = "0.2.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2"
-dependencies = [
- "time-core",
-]
-
-[[package]]
name = "tinyvec"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1116,46 +516,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]]
-name = "tokio"
-version = "1.23.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eab6d665857cc6ca78d6e80303a02cea7a7851e85dfbd77cbdc09bd129f1ef46"
-dependencies = [
- "autocfg",
- "bytes",
- "libc",
- "memchr",
- "mio",
- "num_cpus",
- "parking_lot",
- "pin-project-lite",
- "signal-hook-registry",
- "socket2",
- "tokio-macros",
- "windows-sys",
-]
-
-[[package]]
-name = "tokio-macros"
-version = "1.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "toml"
-version = "0.5.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7"
-dependencies = [
- "serde",
-]
-
-[[package]]
name = "tracing"
version = "0.1.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1218,15 +578,6 @@ dependencies = [
]
[[package]]
-name = "uncased"
-version = "0.9.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09b01702b0fd0b3fadcf98e098780badda8742d4f4a7676615cad90e8ac73622"
-dependencies = [
- "version_check",
-]
-
-[[package]]
name = "unicode-bidi"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1248,12 +599,6 @@ dependencies = [
]
[[package]]
-name = "unicode-width"
-version = "0.1.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
-
-[[package]]
name = "url"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1294,66 +639,6 @@ dependencies = [
]
[[package]]
-name = "wasi"
-version = "0.11.0+wasi-snapshot-preview1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
-
-[[package]]
-name = "wasm-bindgen"
-version = "0.2.83"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268"
-dependencies = [
- "cfg-if",
- "wasm-bindgen-macro",
-]
-
-[[package]]
-name = "wasm-bindgen-backend"
-version = "0.2.83"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142"
-dependencies = [
- "bumpalo",
- "log",
- "once_cell",
- "proc-macro2",
- "quote",
- "syn",
- "wasm-bindgen-shared",
-]
-
-[[package]]
-name = "wasm-bindgen-macro"
-version = "0.2.83"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810"
-dependencies = [
- "quote",
- "wasm-bindgen-macro-support",
-]
-
-[[package]]
-name = "wasm-bindgen-macro-support"
-version = "0.2.83"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
- "wasm-bindgen-backend",
- "wasm-bindgen-shared",
-]
-
-[[package]]
-name = "wasm-bindgen-shared"
-version = "0.2.83"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f"
-
-[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1440,9 +725,3 @@ name = "windows_x86_64_msvc"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5"
-
-[[package]]
-name = "yansi"
-version = "0.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec"
diff --git a/Cargo.toml b/Cargo.toml
index ae19f83..6aa170d 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -2,8 +2,9 @@
name = "projectr"
version = "0.2.1"
edition = "2021"
+description = "Outputs a MRU sorted list subdirectories matching specified criteria."
authors = ["Toby Vincent <tobyv13@gmail.com>"]
-homepage = "https://sr.ht/~tobyvin/tmuxr"
+homepage = "https://git.sr.ht/~tobyvin/projectr"
repository = "https://git.sr.ht/~tobyvin/projectr"
license = "MIT"
@@ -12,23 +13,13 @@ license = "MIT"
[dependencies]
anyhow = "1.0.66"
clap = { version = "4.0.18", features = ["derive", "env"] }
-figment = { version = "0.10.8", features = ["toml", "env", "test"] }
git2 = { version = "0.15.0", default-features = false, optional = true, features = [
"vendored-libgit2",
] }
ignore = "0.4.18"
-pretty_assertions = "1.3.0"
-serde = { version = "1.0.147", features = ["derive"] }
-serde_with = "2.1.0"
-thiserror = "1.0.37"
-tokio = { version = "1.23.0", features = ["full"] }
tracing = { version = "0.1.37", features = ["attributes"] }
tracing-subscriber = { version = "0.3.16", features = ["env-filter"] }
-[dev-dependencies]
-tempfile = "3.3.0"
-toml = "0.5.9"
-
[features]
default = ["git"]
git = ["dep:git2"]
diff --git a/src/config.rs b/src/config.rs
index 358a258..61a0778 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -1,20 +1,59 @@
+use std::path::PathBuf;
+
use clap::{Args, Parser};
use tracing::{metadata::LevelFilter, Level};
-use crate::search::Search;
-
-/// Tool for listing project directories.
#[derive(Debug, Clone, Default, Parser)]
#[command(author, version, about)]
pub struct Config {
+ /// Directories to search.
+ ///
+ /// Directories are searched recursively based on `--max-depth`.
+ pub paths: Vec<PathBuf>,
+
+ /// (UNIMPLEMENTED) Additional directories to add to the sorted output.
+ #[arg(long)]
+ pub add: Vec<PathBuf>,
+
#[command(flatten)]
- pub search: Search,
+ pub filters: Filters,
#[command(flatten)]
pub verbosity: Verbosity,
}
#[derive(Debug, Default, Clone, Args)]
+pub struct Filters {
+ /// Match all child directories.
+ #[arg(short, long)]
+ pub all: bool,
+
+ /// Max depth to recurse.
+ ///
+ /// MAX_DEPTH of 0 will only return the supplied PATHS.
+ #[arg(short = 'd', long, default_value = "1")]
+ pub max_depth: Option<usize>,
+
+ /// Recurse into hidden directories.
+ ///
+ /// Traverse into hidden directories while searching. A directory is considered hidden
+ /// if its name starts with a `.` sign (dot). If `--max-depth` is 0, this has no effect.
+ #[arg(long)]
+ pub hidden: bool,
+
+ /// Match directories containing <PATTERN>.
+ ///
+ /// PATTERN should be a path relative to the searched directory.
+ #[arg(long, short)]
+ pub pattern: Option<String>,
+
+ /// Match git repositories.
+ #[cfg(feature = "git")]
+ #[arg(long, short)]
+ pub git: bool,
+}
+
+#[derive(Debug, Default, Clone, Args)]
pub struct Verbosity {
/// Print additional information per occurrence.
///
diff --git a/src/error.rs b/src/error.rs
deleted file mode 100644
index c7b6448..0000000
--- a/src/error.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-pub type Result<T> = std::result::Result<T, Error>;
-
-#[derive(thiserror::Error, Debug)]
-pub enum Error {
- #[error(transparent)]
- Ignore(#[from] ignore::Error),
-
- #[error(transparent)]
- IO(#[from] std::io::Error),
-
- #[cfg(feature = "git")]
- #[error(transparent)]
- Git(#[from] git2::Error),
-
- #[error(transparent)]
- SystemTime(#[from] std::time::SystemTimeError),
-
- #[error(transparent)]
- Other(#[from] anyhow::Error),
-}
diff --git a/src/lib.rs b/src/lib.rs
index b54d897..8948cf0 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,8 +1,6 @@
pub use crate::config::Config;
-pub use crate::error::{Error, Result};
pub mod project;
pub mod search;
mod config;
-mod error;
diff --git a/src/main.rs b/src/main.rs
index 7f3b90d..7fbed15 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,34 +1,22 @@
-use anyhow::{Context, Result};
+use anyhow::Result;
use clap::Parser;
-use projectr::{project::ProjectItem, Config};
-use tokio::signal;
+use projectr::{project::Project, search::Search, Config};
-#[tokio::main]
-async fn main() -> Result<()> {
- let cli = Config::parse();
+fn main() -> Result<()> {
+ let config = Config::parse();
tracing_subscriber::fmt::fmt()
.pretty()
.with_writer(std::io::stderr)
- .with_max_level(&cli.verbosity)
+ .with_max_level(&config.verbosity)
.init();
- let res = tokio::select! {
- res = signal::ctrl_c() => res.map_err(Into::into),
- res = run(cli) => res.context("Failed to run projectr"),
- };
+ let mut projects: Vec<Project> = Search::new(config).into_iter().collect();
- res
-}
-
-#[tracing::instrument]
-pub async fn run(config: Config) -> Result<()> {
- let mut projects: Vec<ProjectItem> = config.search.into_iter().collect();
-
- projects.sort_unstable_by_key(|p| *p.timestamp());
+ projects.sort_unstable_by_key(|p| p.timestamp);
for project in projects {
- println!("{}", project.to_path_buf().to_string_lossy())
+ println!("{}", project.worktree.to_string_lossy())
}
Ok(())
diff --git a/src/project.rs b/src/project.rs
index 26f0a8b..2b3e028 100644
--- a/src/project.rs
+++ b/src/project.rs
@@ -1,47 +1,79 @@
-use std::{path::PathBuf, time::Duration};
+use std::{
+ ops::{Deref, DerefMut},
+ path::PathBuf,
+ time::{Duration, SystemTime},
+};
+
+use tracing::warn;
pub mod path;
#[cfg(feature = "git")]
pub mod git;
-pub type ProjectParserGroup = Vec<Box<dyn ProjectParser>>;
-
pub trait ProjectParser {
- fn parse(&self, path_buf: PathBuf) -> Option<ProjectItem>;
+ fn parse(&self, path_buf: PathBuf) -> Result<Project, Box<dyn std::error::Error>>;
}
-impl ProjectParser for ProjectParserGroup {
- fn parse(&self, path_buf: std::path::PathBuf) -> Option<ProjectItem> {
- self.iter().find_map(|p| p.parse(path_buf.to_owned()))
+#[derive(Default)]
+pub struct ProjectParserGroup {
+ pub parsers: Vec<Box<dyn ProjectParser>>,
+}
+
+impl ProjectParserGroup {
+ pub fn new() -> Self {
+ Self::default()
+ }
+
+ pub fn parse(&self, path_buf: std::path::PathBuf) -> Option<Project> {
+ if self.parsers.is_empty() {
+ return path_buf.try_into().ok();
+ }
+
+ self.iter()
+ .map(|p| p.parse(path_buf.to_owned()))
+ .inspect(|res| {
+ if let Err(err) = res {
+ warn!(%err, "Parser failed to match");
+ }
+ })
+ .flatten()
+ .reduce(|max, p| p.max(max))
}
}
-pub type ProjectItem = Box<dyn Project>;
+impl Deref for ProjectParserGroup {
+ type Target = Vec<Box<dyn ProjectParser>>;
-pub trait Project: Timestamp {
- fn to_path_buf(&self) -> &PathBuf;
+ fn deref(&self) -> &Self::Target {
+ &self.parsers
+ }
}
-impl<T> Project for T
-where
- T: Timestamp,
- T: AsRef<PathBuf>,
-{
- fn to_path_buf(&self) -> &PathBuf {
- self.as_ref()
+impl DerefMut for ProjectParserGroup {
+ fn deref_mut(&mut self) -> &mut Self::Target {
+ &mut self.parsers
}
}
-pub trait Timestamp {
- fn timestamp(&self) -> &Duration;
+#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
+pub struct Project {
+ pub timestamp: Duration,
+ pub worktree: PathBuf,
}
-impl<T> Timestamp for T
-where
- T: AsRef<Duration>,
-{
- fn timestamp(&self) -> &Duration {
- self.as_ref()
+impl TryFrom<PathBuf> for Project {
+ type Error = std::io::Error;
+
+ fn try_from(value: PathBuf) -> Result<Self, Self::Error> {
+ let timestamp = value
+ .metadata()?
+ .modified()?
+ .duration_since(SystemTime::UNIX_EPOCH)
+ .map_err(|err| std::io::Error::new(std::io::ErrorKind::Other, err.to_string()))?;
+ Ok(Self {
+ worktree: value,
+ timestamp,
+ })
}
}
diff --git a/src/project/git.rs b/src/project/git.rs
index 4584a7a..e2067ec 100644
--- a/src/project/git.rs
+++ b/src/project/git.rs
@@ -1,102 +1,39 @@
use git2::{BranchType, Repository};
-use ignore::DirEntry;
use std::{path::PathBuf, time::Duration};
-use tracing::{debug, warn};
-use crate::{Error, Result};
-
-use super::{ProjectParser, Timestamp};
+use super::{Project, ProjectParser};
#[derive(Debug, Clone)]
pub struct GitMatcher;
impl ProjectParser for GitMatcher {
#[tracing::instrument]
- fn parse(&self, path_buf: PathBuf) -> Option<super::ProjectItem> {
- match GitProject::new(path_buf) {
- Ok(g) => Some(Box::new(g)),
- Err(err) => {
- debug!(%err, "Failed to create git project");
- None
- }
- }
+ fn parse(&self, path_buf: PathBuf) -> Result<Project, Box<dyn std::error::Error>> {
+ Repository::open(&path_buf)?.parse(path_buf)
}
}
-#[derive(Debug, Clone)]
-pub struct GitProject {
- path_buf: PathBuf,
- latest_commit: Duration,
-}
+impl ProjectParser for Repository {
+ fn parse(&self, path_buf: PathBuf) -> Result<Project, Box<dyn std::error::Error>> {
+ let mut branches = self.branches(Some(BranchType::Local))?;
+ let timestamp = branches
+ .try_fold(0, |latest, branch| -> std::result::Result<u64, _> {
+ let (branch, _) = branch?;
-impl GitProject {
- fn new(path_buf: PathBuf) -> Result<Self> {
- let repo = Repository::open(&path_buf)?;
- let latest_commit = Self::get_timestamp(&repo);
- Ok(Self {
- path_buf,
- latest_commit,
- })
- }
-
- fn get_timestamp(repo: &Repository) -> Duration {
- match Self::latest_commit(repo) {
- Ok(s) => Duration::from_secs(s),
- Err(err) => {
- warn!(%err, "Failed to get latest commit from repository");
- Duration::default()
- }
- }
- }
+ let name = branch
+ .name()?
+ .ok_or_else(|| git2::Error::from_str("Failed to find branch"))?;
- fn latest_commit(repository: &Repository) -> Result<u64> {
- let mut branches = repository.branches(Some(BranchType::Local))?;
- branches.try_fold(0, |latest, branch| {
- let (branch, _) = branch?;
+ self.revparse_single(name)?
+ .peel_to_commit()
+ .map(|c| (c.time().seconds() as u64).max(latest))
+ })
+ .map(Duration::from_secs)
+ .unwrap_or_default();
- let name = branch
- .name()?
- .ok_or_else(|| git2::Error::from_str("Failed to find branch"))?;
-
- repository
- .revparse_single(name)?
- .peel_to_commit()
- .map(|c| (c.time().seconds() as u64).max(latest))
- .map_err(Into::into)
+ Ok(Project {
+ worktree: path_buf,
+ timestamp,
})
}
}
-
-impl Timestamp for GitProject {
- fn timestamp(&self) -> &Duration {
- &self.latest_commit
- }
-}
-
-impl AsRef<PathBuf> for GitProject {
- fn as_ref(&self) -> &PathBuf {
- &self.path_buf
- }
-}
-
-impl TryFrom<PathBuf> for GitProject {
- type Error = Error;
-
- fn try_from(value: PathBuf) -> Result<Self> {
- Self::new(value)
- }
-}
-
-impl TryFrom<DirEntry> for GitProject {
- type Error = Error;
-
- fn try_from(value: DirEntry) -> Result<Self> {
- Self::new(value.into_path())
- }
-}
-
-impl From<GitProject> for PathBuf {
- fn from(value: GitProject) -> Self {
- value.path_buf
- }
-}
diff --git a/src/project/path.rs b/src/project/path.rs
index 5954ff9..0e38990 100644
--- a/src/project/path.rs
+++ b/src/project/path.rs
@@ -1,57 +1,22 @@
-use std::path::{Path, PathBuf};
-use std::time::{Duration, SystemTime};
-use tracing::debug;
+use std::{io::ErrorKind, path::PathBuf};
-use super::{ProjectItem, ProjectParser};
+use super::{Project, ProjectParser};
#[derive(Debug, Clone)]
pub enum PathMatcher {
- All(PathBuf),
+ All,
Pattern(String),
}
impl ProjectParser for PathMatcher {
#[tracing::instrument]
- fn parse(&self, path_buf: PathBuf) -> Option<ProjectItem> {
- match self {
- PathMatcher::All(p) if &path_buf != p => Some(Box::new(PathProject::new(path_buf))),
- PathMatcher::Pattern(p) if path_buf.join(p).exists() => {
- Some(Box::new(PathProject::new(path_buf)))
- }
- _ => {
- debug!("Failed to match pattern in directory");
- None
- }
- }
- }
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Default)]
-pub struct PathProject(PathBuf, Duration);
-
-impl PathProject {
- pub fn new(path_buf: PathBuf) -> Self {
- let modified = Self::get_modified(&path_buf).unwrap_or_default();
- Self(path_buf, modified)
- }
-
- fn get_modified(path_buf: &Path) -> Result<Duration, std::io::Error> {
- path_buf
- .metadata()?
- .modified()?
- .duration_since(SystemTime::UNIX_EPOCH)
- .map_err(|err| std::io::Error::new(std::io::ErrorKind::Other, err.to_string()))
- }
-}
-
-impl AsRef<PathBuf> for PathProject {
- fn as_ref(&self) -> &PathBuf {
- &self.0
- }
-}
-
-impl AsRef<Duration> for PathProject {
- fn as_ref(&self) -> &Duration {
- &self.1
+ fn parse(&self, path_buf: PathBuf) -> Result<Project, Box<dyn std::error::Error>> {
+ let project = match self {
+ PathMatcher::All => path_buf.try_into()?,
+ PathMatcher::Pattern(p) if path_buf.join(p).exists() => path_buf.try_into()?,
+ _ => return Err(Box::new(std::io::Error::from(ErrorKind::NotFound))),
+ };
+
+ Ok(project)
}
}
diff --git a/src/search.rs b/src/search.rs
index 888179e..81049e9 100644
--- a/src/search.rs
+++ b/src/search.rs
@@ -1,92 +1,67 @@
use std::path::PathBuf;
-use clap::Args;
+use crate::{config::Filters, project::Project, Config};
-use crate::project::ProjectItem;
-
-use self::entry::SearchEntry;
+use self::entry::SearchPath;
pub mod entry;
type EntryIter = std::vec::IntoIter<PathBuf>;
-#[derive(Debug, Default, Clone, Args)]
+#[derive(Debug, Default, Clone)]
pub struct Search {
- /// Directory to search.
- ///
- /// Directories are searched recursively based on `--max-depth`.
pub paths: Vec<PathBuf>,
-
- #[command(flatten)]
- pub filter: Filters,
+ pub add: Vec<PathBuf>,
+ pub filters: Filters,
}
-#[derive(Debug, Default, Clone, Args)]
-pub struct Filters {
- /// Match all child directories
- #[arg(long, short, conflicts_with_all = ["pattern", "git"])]
- pub all: bool,
-
- /// Max depth to recurse.
- ///
- /// Setting to 0 will only use the supplied directory.
- #[arg(short = 'd', long, default_value = "1")]
- pub max_depth: Option<usize>,
-
- /// Recurse into hidden directories.
- ///
- /// Traverse into hidden directories while searching. A directory is considered hidden
- /// if its name starts with a `.` sign (dot). If `--max-depth` is 0, this has no effect.
- #[arg(long)]
- pub hidden: bool,
-
- /// Match directories containing item named <PATTERN>
- #[arg(long, short)]
- pub pattern: Option<String>,
-
- /// Match git repositories
- #[cfg(feature = "git")]
- #[arg(long, short, default_value_t = true)]
- pub git: bool,
+impl Search {
+ pub fn new(
+ Config {
+ paths,
+ add,
+ filters,
+ verbosity: _,
+ }: Config,
+ ) -> Self {
+ Self {
+ paths,
+ add,
+ filters,
+ }
+ }
}
impl IntoIterator for Search {
- type Item = ProjectItem;
+ type Item = Project;
type IntoIter = SearchIter;
fn into_iter(self) -> Self::IntoIter {
SearchIter {
iter: self.paths.into_iter(),
- config: self.filter,
+ config: self.filters,
curr: None,
}
}
}
+#[derive(Debug)]
pub struct SearchIter {
iter: EntryIter,
config: Filters,
- curr: Option<SearchEntry>,
-}
-
-impl std::fmt::Debug for SearchIter {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- f.debug_struct("Projects")
- .field("paths_iter", &self.iter)
- .finish_non_exhaustive()
- }
+ curr: Option<SearchPath>,
}
impl Iterator for SearchIter {
- type Item = ProjectItem;
+ type Item = Project;
#[tracing::instrument]
fn next(&mut self) -> Option<Self::Item> {
match self.curr.as_mut().and_then(|c| c.next()) {
Some(proj) => Some(proj),
None => {
- self.curr = Some(SearchEntry::new(self.iter.next()?, &self.config));
+ self.curr = Some(SearchPath::new(self.iter.next()?, &self.config));
self.next()
}
}
diff --git a/src/search/entry.rs b/src/search/entry.rs
index 16dcd8b..efd287b 100644
--- a/src/search/entry.rs
+++ b/src/search/entry.rs
@@ -1,23 +1,33 @@
use std::path::PathBuf;
use ignore::{Walk, WalkBuilder};
-use tracing::error;
+use tracing::{debug, error};
-use crate::project::{path::PathMatcher, ProjectItem, ProjectParser, ProjectParserGroup};
+use crate::{
+ config::Filters,
+ project::{path::PathMatcher, Project, ProjectParserGroup},
+};
-use super::Filters;
-
-pub struct SearchEntry {
+pub struct SearchPath {
+ path_buf: PathBuf,
parsers: ProjectParserGroup,
iter: Walk,
}
-impl SearchEntry {
+impl std::fmt::Debug for SearchPath {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ f.debug_struct("SearchPath")
+ .field("path_buf", &self.path_buf)
+ .finish()
+ }
+}
+
+impl SearchPath {
pub fn new(path_buf: PathBuf, config: &Filters) -> Self {
let mut parsers = ProjectParserGroup::new();
if config.all {
- parsers.push(Box::new(PathMatcher::All(path_buf.to_owned())))
+ parsers.push(Box::new(PathMatcher::All))
}
if let Some(s) = config.pattern.as_ref() {
@@ -29,21 +39,29 @@ impl SearchEntry {
parsers.push(Box::new(crate::project::git::GitMatcher));
};
- let iter = WalkBuilder::new(path_buf)
+ let iter = WalkBuilder::new(&path_buf)
.standard_filters(true)
.max_depth(config.max_depth)
.hidden(!config.hidden)
.build();
- Self { parsers, iter }
+ Self {
+ path_buf,
+ parsers,
+ iter,
+ }
}
}
-impl Iterator for SearchEntry {
- type Item = ProjectItem;
+impl Iterator for SearchPath {
+ type Item = Project;
fn next(&mut self) -> Option<Self::Item> {
match self.iter.next()? {
+ Ok(dir_entry) if dir_entry.path() == self.path_buf => {
+ debug!("Ignoring parent directory");
+ None
+ }
Ok(dir_entry) => self.parsers.parse(dir_entry.into_path()),
Err(err) => {
error!(%err, "Ignoring errored path");