diff --git a/Cargo.lock b/Cargo.lock index 7cf2fd4..932dea0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -36,6 +36,15 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" +[[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 = "anstream" version = "0.6.13" @@ -121,21 +130,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706" dependencies = [ "memchr", - "regex-automata 0.4.6", + "regex-automata", "serde", ] [[package]] name = "build-data" -version = "0.1.5" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aed3884e2cab7c973c8fd2d150314b6a932df7fdc830edcaf1e8e7c4ae9db3c0" +checksum = "eda20fcece9c23f3c3f4c2751a8a5ca9491c05fa7a69920af65953c3b39b7ce4" dependencies = [ "chrono", - "safe-lock", "safe-regex", ] +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "cc" +version = "1.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fb8dd288a69fc53a1996d7ecfbf4a20d59065bff137ce7e56bbd620de191189" +dependencies = [ + "jobserver", + "libc", + "shlex", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -179,7 +204,7 @@ version = "4.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90239a040c80f5e14809ca132ddc4176ab33d5e17e49691793296e3fcb34d72f" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro2", "quote", "syn", @@ -203,6 +228,38 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +[[package]] +name = "const_fn" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "373e9fafaa20882876db20562275ff58d50e0caa2590077fe7ce7bef90211d0d" + +[[package]] +name = "const_format" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a214c7af3d04997541b18d432afaff4c455e79e2029079647e72fc2bd27673" +dependencies = [ + "const_format_proc_macros", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7f6ff08fd20f4f299298a28e2dfa8a8ba1036e6cd2460ac1de7b425d76f2500" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + [[package]] name = "crc32fast" version = "1.4.0" @@ -274,12 +331,45 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "env_filter" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f2c92ceda6ceec50f43169f9ee8424fe2db276791afde7b2cd8bc084cb376ab" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_logger" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13fa619b91fb2381732789fc5de83b45675e882f66623b7d8cb4f643017018d" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "humantime", + "log", +] + [[package]] name = "equivalent" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "erased-serde" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24e2389d65ab4fab27dc2a5de7b191e1f6617d1f1c8855c0dc569c94a4cbb18d" +dependencies = [ + "serde", + "typeid", +] + [[package]] name = "errno" version = "0.3.8" @@ -350,11 +440,24 @@ dependencies = [ "wasi", ] +[[package]] +name = "git2" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b903b73e45dc0c6c596f2d37eccece7c1c8bb6e4407b001096387c63d0d93724" +dependencies = [ + "bitflags 2.5.0", + "libc", + "libgit2-sys", + "log", + "url", +] + [[package]] name = "gix" -version = "0.63.0" +version = "0.64.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "984c5018adfa7a4536ade67990b3ebc6e11ab57b3d6cd9968de0947ca99b4b06" +checksum = "d78414d29fcc82329080166077e0f7689f4016551fdb334d787c3d040fe2634f" dependencies = [ "gix-actor", "gix-attributes", @@ -393,16 +496,15 @@ dependencies = [ "gix-validate", "gix-worktree", "once_cell", - "parking_lot", "smallvec", "thiserror", ] [[package]] name = "gix-actor" -version = "0.31.2" +version = "0.31.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d69c59d392c7e6c94385b6fd6089d6df0fe945f32b4357687989f3aee253cd7f" +checksum = "a0e454357e34b833cc3a00b6efbbd3dd4d18b24b9fb0c023876ec2645e8aa3f2" dependencies = [ "bstr", "gix-date", @@ -414,9 +516,9 @@ dependencies = [ [[package]] name = "gix-attributes" -version = "0.22.2" +version = "0.22.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eefb48f42eac136a4a0023f49a54ec31be1c7a9589ed762c45dcb9b953f7ecc8" +checksum = "e37ce99c7e81288c28b703641b6d5d119aacc45c1a6b247156e6249afa486257" dependencies = [ "bstr", "gix-glob", @@ -449,9 +551,9 @@ dependencies = [ [[package]] name = "gix-command" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c22e086314095c43ffe5cdc5c0922d5439da4fd726f3b0438c56147c34dc225" +checksum = "0d76867867da891cbe32021ad454e8cae90242f6afb06762e4dd0d357afd1d7b" dependencies = [ "bstr", "gix-path", @@ -461,9 +563,9 @@ dependencies = [ [[package]] name = "gix-commitgraph" -version = "0.24.2" +version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7b102311085da4af18823413b5176d7c500fb2272eaf391cfa8635d8bcb12c4" +checksum = "133b06f67f565836ec0c473e2116a60fb74f80b6435e21d88013ac0e3c60fc78" dependencies = [ "bstr", "gix-chunk", @@ -475,9 +577,9 @@ dependencies = [ [[package]] name = "gix-config" -version = "0.37.0" +version = "0.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fafe42957e11d98e354a66b6bd70aeea00faf2f62dd11164188224a507c840" +checksum = "28f53fd03d1bf09ebcc2c8654f08969439c4556e644ca925f27cf033bc43e658" dependencies = [ "bstr", "gix-config-value", @@ -496,9 +598,9 @@ dependencies = [ [[package]] name = "gix-config-value" -version = "0.14.6" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbd06203b1a9b33a78c88252a625031b094d9e1b647260070c25b09910c0a804" +checksum = "b328997d74dd15dc71b2773b162cb4af9a25c424105e4876e6d0686ab41c383e" dependencies = [ "bitflags 2.5.0", "bstr", @@ -509,9 +611,9 @@ dependencies = [ [[package]] name = "gix-date" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "367ee9093b0c2b04fd04c5c7c8b6a1082713534eab537597ae343663a518fa99" +checksum = "9eed6931f21491ee0aeb922751bd7ec97b4b2fe8fbfedcb678e2a2dce5f3b8c0" dependencies = [ "bstr", "itoa", @@ -521,9 +623,9 @@ dependencies = [ [[package]] name = "gix-diff" -version = "0.44.0" +version = "0.44.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40b9bd8b2d07b6675a840b56a6c177d322d45fa082672b0dad8f063b25baf0a4" +checksum = "1996d5c8a305b59709467d80617c9fde48d9d75fd1f4179ea970912630886c9d" dependencies = [ "bstr", "gix-command", @@ -541,9 +643,9 @@ dependencies = [ [[package]] name = "gix-discover" -version = "0.32.0" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc27c699b63da66b50d50c00668bc0b7e90c3a382ef302865e891559935f3dbf" +checksum = "67662731cec3cb31ba3ed2463809493f76d8e5d6c6d245de8b0560438c13450e" dependencies = [ "bstr", "dunce", @@ -576,9 +678,9 @@ dependencies = [ [[package]] name = "gix-filter" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00ce6ea5ac8fca7adbc63c48a1b9e0492c222c386aa15f513405f1003f2f4ab2" +checksum = "e6547738da28275f4dff4e9f3a0f28509f53f94dd6bd822733c91cb306bca61a" dependencies = [ "bstr", "encoding_rs", @@ -597,9 +699,9 @@ dependencies = [ [[package]] name = "gix-fs" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3338ff92a2164f5209f185ec0cd316f571a72676bb01d27e22f2867ba69f77a" +checksum = "6adf99c27cdf17b1c4d77680c917e0d94d8783d4e1c73d3be0d1d63107163d7a" dependencies = [ "fastrand", "gix-features", @@ -608,9 +710,9 @@ dependencies = [ [[package]] name = "gix-glob" -version = "0.16.2" +version = "0.16.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "682bdc43cb3c00dbedfcc366de2a849b582efd8d886215dbad2ea662ec156bb5" +checksum = "fa7df15afa265cc8abe92813cd354d522f1ac06b29ec6dfa163ad320575cb447" dependencies = [ "bitflags 2.5.0", "bstr", @@ -641,9 +743,9 @@ dependencies = [ [[package]] name = "gix-ignore" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "640dbeb4f5829f9fc14d31f654a34a0350e43a24e32d551ad130d99bf01f63f1" +checksum = "5e6afb8f98e314d4e1adc822449389ada863c174b5707cedd327d67b84dba527" dependencies = [ "bstr", "gix-glob", @@ -654,9 +756,9 @@ dependencies = [ [[package]] name = "gix-index" -version = "0.33.0" +version = "0.33.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d8c5a5f1c58edcbc5692b174cda2703aba82ed17d7176ff4c1752eb48b1b167" +checksum = "9a9a44eb55bd84bb48f8a44980e951968ced21e171b22d115d1cdcef82a7d73f" dependencies = [ "bitflags 2.5.0", "bstr", @@ -704,9 +806,9 @@ dependencies = [ [[package]] name = "gix-object" -version = "0.42.2" +version = "0.42.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fe2dc4a41191c680c942e6ebd630c8107005983c4679214fdb1007dcf5ae1df" +checksum = "25da2f46b4e7c2fa7b413ce4dffb87f69eaf89c2057e386491f4c55cadbfe386" dependencies = [ "bstr", "gix-actor", @@ -723,9 +825,9 @@ dependencies = [ [[package]] name = "gix-odb" -version = "0.61.0" +version = "0.61.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e92b9790e2c919166865d0825b26cc440a387c175bed1b43a2fa99c0e9d45e98" +checksum = "20d384fe541d93d8a3bb7d5d5ef210780d6df4f50c4e684ccba32665a5e3bc9b" dependencies = [ "arc-swap", "gix-date", @@ -743,9 +845,9 @@ dependencies = [ [[package]] name = "gix-pack" -version = "0.51.0" +version = "0.51.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a8da51212dbff944713edb2141ed7e002eea326b8992070374ce13a6cb610b3" +checksum = "3e0594491fffe55df94ba1c111a6566b7f56b3f8d2e1efc750e77d572f5f5229" dependencies = [ "clru", "gix-chunk", @@ -754,9 +856,7 @@ dependencies = [ "gix-hashtable", "gix-object", "gix-path", - "gix-tempfile", "memmap2", - "parking_lot", "smallvec", "thiserror", ] @@ -775,9 +875,9 @@ dependencies = [ [[package]] name = "gix-path" -version = "0.10.7" +version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23623cf0f475691a6d943f898c4d0b89f5c1a2a64d0f92bce0e0322ee6528783" +checksum = "8d23d5bbda31344d8abc8de7c075b3cf26e5873feba7c4a15d916bce67382bd9" dependencies = [ "bstr", "gix-trace", @@ -788,9 +888,9 @@ dependencies = [ [[package]] name = "gix-pathspec" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a76cab098dc10ba2d89f634f66bf196dea4d7db4bf10b75c7a9c201c55a2ee19" +checksum = "d307d1b8f84dc8386c4aa20ce0cf09242033840e15469a3ecba92f10cfb5c046" dependencies = [ "bitflags 2.5.0", "bstr", @@ -814,12 +914,11 @@ dependencies = [ [[package]] name = "gix-ref" -version = "0.44.1" +version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3394a2997e5bc6b22ebc1e1a87b41eeefbcfcff3dbfa7c4bd73cb0ac8f1f3e2e" +checksum = "636e96a0a5562715153fee098c217110c33a6f8218f08f4687ff99afde159bb5" dependencies = [ "gix-actor", - "gix-date", "gix-features", "gix-fs", "gix-hash", @@ -836,9 +935,9 @@ dependencies = [ [[package]] name = "gix-refspec" -version = "0.23.0" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dde848865834a54fe4d9b4573f15d0e9a68eaf3d061b42d3ed52b4b8acf880b2" +checksum = "6868f8cd2e62555d1f7c78b784bece43ace40dd2a462daf3b588d5416e603f37" dependencies = [ "bstr", "gix-hash", @@ -850,25 +949,23 @@ dependencies = [ [[package]] name = "gix-revision" -version = "0.27.1" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63e08f8107ed1f93a83bcfbb4c38084c7cb3f6cd849793f1d5eec235f9b13b2b" +checksum = "01b13e43c2118c4b0537ddac7d0821ae0dfa90b7b8dbf20c711e153fb749adce" dependencies = [ "bstr", "gix-date", "gix-hash", - "gix-hashtable", "gix-object", "gix-revwalk", - "gix-trace", "thiserror", ] [[package]] name = "gix-revwalk" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4181db9cfcd6d1d0fd258e91569dbb61f94cb788b441b5294dd7f1167a3e788f" +checksum = "1b030ccaab71af141f537e0225f19b9e74f25fefdba0372246b844491cab43e0" dependencies = [ "gix-commitgraph", "gix-date", @@ -881,9 +978,9 @@ dependencies = [ [[package]] name = "gix-sec" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fddc27984a643b20dd03e97790555804f98cf07404e0e552c0ad8133266a79a1" +checksum = "1547d26fa5693a7f34f05b4a3b59a90890972922172653bcb891ab3f09f436df" dependencies = [ "bitflags 2.5.0", "gix-path", @@ -893,9 +990,9 @@ dependencies = [ [[package]] name = "gix-submodule" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "921cd49924ac14b6611b22e5fb7bbba74d8780dc7ad26153304b64d1272460ac" +checksum = "0f2e0f69aa00805e39d39ec80472a7e9da20ed5d73318b27925a2cc198e854fd" dependencies = [ "bstr", "gix-config", @@ -928,9 +1025,9 @@ checksum = "f924267408915fddcd558e3f37295cc7d6a3e50f8bd8b606cee0808c3915157e" [[package]] name = "gix-traverse" -version = "0.39.1" +version = "0.39.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f20cb69b63eb3e4827939f42c05b7756e3488ef49c25c412a876691d568ee2a0" +checksum = "e499a18c511e71cf4a20413b743b9f5bcf64b3d9e81e9c3c6cd399eae55a8840" dependencies = [ "bitflags 2.5.0", "gix-commitgraph", @@ -945,9 +1042,9 @@ dependencies = [ [[package]] name = "gix-url" -version = "0.27.3" +version = "0.27.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0db829ebdca6180fbe32be7aed393591df6db4a72dbbc0b8369162390954d1cf" +checksum = "e2eb9b35bba92ea8f0b5ab406fad3cf6b87f7929aa677ff10aa042c6da621156" dependencies = [ "bstr", "gix-features", @@ -979,9 +1076,9 @@ dependencies = [ [[package]] name = "gix-worktree" -version = "0.34.0" +version = "0.34.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53f6b7de83839274022aff92157d7505f23debf739d257984a300a35972ca94e" +checksum = "26f7326ebe0b9172220694ea69d344c536009a9b98fb0f9de092c440f3efe7a6" dependencies = [ "bstr", "gix-attributes", @@ -1005,8 +1102,8 @@ dependencies = [ "aho-corasick", "bstr", "log", - "regex-automata 0.4.6", - "regex-syntax 0.8.2", + "regex-automata", + "regex-syntax", ] [[package]] @@ -1027,38 +1124,33 @@ dependencies = [ [[package]] name = "hawkeye" -version = "5.7.0" +version = "5.8.0" dependencies = [ + "anyhow", "build-data", "clap", + "const_format", + "env_logger", "hawkeye-fmt", - "snafu", - "tracing", - "tracing-subscriber", + "log", + "shadow-rs", ] [[package]] name = "hawkeye-fmt" -version = "5.7.0" +version = "5.8.0" dependencies = [ "anyhow", "gix", "ignore", + "log", "regex", "serde", - "snafu", "time", "toml", - "tracing", "walkdir", ] -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - [[package]] name = "heck" version = "0.5.0" @@ -1074,6 +1166,35 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + [[package]] name = "idna" version = "0.5.0" @@ -1094,7 +1215,7 @@ dependencies = [ "globset", "log", "memchr", - "regex-automata 0.4.6", + "regex-automata", "same-file", "walkdir", "winapi-util", @@ -1120,12 +1241,36 @@ dependencies = [ "hashbrown 0.14.3", ] +[[package]] +name = "is_debug" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06d198e9919d9822d5f7083ba8530e04de87841eaf21ead9af8f2304efd57c89" + [[package]] name = "itoa" version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +[[package]] +name = "jobserver" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" +dependencies = [ + "wasm-bindgen", +] + [[package]] name = "kstring" version = "2.0.0" @@ -1135,18 +1280,36 @@ dependencies = [ "static_assertions", ] -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - [[package]] name = "libc" version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +[[package]] +name = "libgit2-sys" +version = "0.17.0+1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10472326a8a6477c3c20a64547b0059e4b0d086869eee31e6d7da728a8eb7224" +dependencies = [ + "cc", + "libc", + "libz-sys", + "pkg-config", +] + +[[package]] +name = "libz-sys" +version = "1.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc53a7799a7496ebc9fd29f31f7df80e83c9bda5299768af5f9e59eeea74647" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "linux-raw-sys" version = "0.4.13" @@ -1168,14 +1331,9 @@ name = "log" version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" - -[[package]] -name = "matchers" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" dependencies = [ - "regex-automata 0.1.10", + "serde", + "value-bag", ] [[package]] @@ -1202,16 +1360,6 @@ dependencies = [ "adler", ] -[[package]] -name = "nu-ansi-term" -version = "0.46.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" -dependencies = [ - "overload", - "winapi", -] - [[package]] name = "num-conv" version = "0.1.0" @@ -1242,12 +1390,6 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" -[[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" @@ -1278,10 +1420,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] -name = "pin-project-lite" -version = "0.2.13" +name = "pkg-config" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "powerfmt" @@ -1330,17 +1472,8 @@ checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.6", - "regex-syntax 0.8.2", -] - -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -dependencies = [ - "regex-syntax 0.6.29", + "regex-automata", + "regex-syntax", ] [[package]] @@ -1351,15 +1484,9 @@ checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.2", + "regex-syntax", ] -[[package]] -name = "regex-syntax" -version = "0.6.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" - [[package]] name = "regex-syntax" version = "0.8.2" @@ -1380,10 +1507,10 @@ dependencies = [ ] [[package]] -name = "safe-lock" -version = "0.1.3" +name = "ryu" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "077d73db7973cccf63eb4aff1e5a34dc2459baa867512088269ea5f2f4253c90" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "safe-proc-macro2" @@ -1405,18 +1532,18 @@ dependencies = [ [[package]] name = "safe-regex" -version = "0.2.5" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a15289bf322e0673d52756a18194167f2378ec1a15fe884af6e2d2cb934822b0" +checksum = "5194fafa3cb9da89e0cab6dffa1f3fdded586bd6396d12be11b4cae0c7ee45c2" dependencies = [ "safe-regex-macro", ] [[package]] name = "safe-regex-compiler" -version = "0.2.5" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fba76fae590a2aa665279deb1f57b5098cbace01a0c5e60e262fcf55f7c51542" +checksum = "e822ae1e61251bcfd698317c237cf83f7c57161a5dc24ee609a85697f1ed15b3" dependencies = [ "safe-proc-macro2", "safe-quote", @@ -1424,9 +1551,9 @@ dependencies = [ [[package]] name = "safe-regex-macro" -version = "0.2.5" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96c2e96b5c03f158d1b16ba79af515137795f4ad4e8de3f790518aae91f1d127" +checksum = "2768de7e6ef19f59c5fd3c3ac207ef12b68a49f95e3172d67e4a04cfd992ca06" dependencies = [ "safe-proc-macro2", "safe-regex-compiler", @@ -1467,6 +1594,15 @@ dependencies = [ "syn", ] +[[package]] +name = "serde_fmt" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d4ddca14104cd60529e8c7f7ba71a2c8acd8f7f5cfcdc2faf97eeb7c3010a4" +dependencies = [ + "serde", +] + [[package]] name = "serde_spanned" version = "0.6.5" @@ -1483,12 +1619,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" [[package]] -name = "sharded-slab" -version = "0.1.7" +name = "shadow-rs" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +checksum = "25d4535372eab969a98536e39dd272bca49fc338b09b25babea715968d15eeae" dependencies = [ - "lazy_static", + "const_format", + "git2", + "is_debug", + "time", + "tzdb", ] [[package]] @@ -1497,6 +1637,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "smallvec" version = "1.13.2" @@ -1504,37 +1650,94 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] -name = "snafu" -version = "0.8.2" +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strsim" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" + +[[package]] +name = "sval" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53eb957fbc79a55306d5d25d87daf3627bc3800681491cda0709eef36c748bfe" + +[[package]] +name = "sval_buffer" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75976f4748ab44f6e5332102be424e7c2dc18daeaf7e725f2040c3ebb133512e" +checksum = "96e860aef60e9cbf37888d4953a13445abf523c534640d1f6174d310917c410d" dependencies = [ - "snafu-derive", + "sval", + "sval_ref", ] [[package]] -name = "snafu-derive" -version = "0.8.2" +name = "sval_dynamic" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4b19911debfb8c2fb1107bc6cb2d61868aaf53a988449213959bb1b5b1ed95f" +checksum = "ea3f2b07929a1127d204ed7cb3905049381708245727680e9139dac317ed556f" dependencies = [ - "heck 0.4.1", - "proc-macro2", - "quote", - "syn", + "sval", ] [[package]] -name = "static_assertions" -version = "1.1.0" +name = "sval_fmt" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +checksum = "c4e188677497de274a1367c4bda15bd2296de4070d91729aac8f0a09c1abf64d" +dependencies = [ + "itoa", + "ryu", + "sval", +] [[package]] -name = "strsim" -version = "0.11.0" +name = "sval_json" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" +checksum = "32f456c07dae652744781f2245d5e3b78e6a9ebad70790ac11eb15dbdbce5282" +dependencies = [ + "itoa", + "ryu", + "sval", +] + +[[package]] +name = "sval_nested" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "886feb24709f0476baaebbf9ac10671a50163caa7e439d7a7beb7f6d81d0a6fb" +dependencies = [ + "sval", + "sval_buffer", + "sval_ref", +] + +[[package]] +name = "sval_ref" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be2e7fc517d778f44f8cb64140afa36010999565528d48985f55e64d45f369ce" +dependencies = [ + "sval", +] + +[[package]] +name = "sval_serde" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79bf66549a997ff35cd2114a27ac4b0c2843280f2cfa84b240d169ecaa0add46" +dependencies = [ + "serde", + "sval", + "sval_nested", +] [[package]] name = "syn" @@ -1579,21 +1782,11 @@ dependencies = [ "syn", ] -[[package]] -name = "thread_local" -version = "1.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" -dependencies = [ - "cfg-if", - "once_cell", -] - [[package]] name = "time" -version = "0.3.34" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "itoa", @@ -1614,9 +1807,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ "num-conv", "time-core", @@ -1672,64 +1865,38 @@ dependencies = [ ] [[package]] -name = "tracing" -version = "0.1.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" -dependencies = [ - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.27" +name = "typeid" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] +checksum = "059d83cc991e7a42fc37bd50941885db0888e34209f8cfd9aab07ddec03bc9cf" [[package]] -name = "tracing-core" -version = "0.1.32" +name = "tz-rs" +version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "33851b15c848fad2cf4b105c6bb66eb9512b6f6c44a4b13f57c53c73c707e2b4" dependencies = [ - "once_cell", - "valuable", + "const_fn", ] [[package]] -name = "tracing-log" -version = "0.2.0" +name = "tzdb" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +checksum = "1b580f6b365fa89f5767cdb619a55d534d04a4e14c2d7e5b9a31e94598687fb1" dependencies = [ - "log", - "once_cell", - "tracing-core", + "iana-time-zone", + "tz-rs", + "tzdb_data", ] [[package]] -name = "tracing-subscriber" -version = "0.3.18" +name = "tzdb_data" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +checksum = "d1889fdffac09d65c1d95c42d5202e9b21ad8c758f426e9fe09088817ea998d6" dependencies = [ - "matchers", - "nu-ansi-term", - "once_cell", - "regex", - "sharded-slab", - "smallvec", - "thread_local", - "tracing", - "tracing-core", - "tracing-log", + "tz-rs", ] [[package]] @@ -1759,11 +1926,17 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + [[package]] name = "url" -version = "2.5.0" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ "form_urlencoded", "idna", @@ -1777,10 +1950,46 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] -name = "valuable" -version = "0.1.0" +name = "value-bag" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a84c137d37ab0142f0f2ddfe332651fdbf252e7b7dbb4e67b6c1f1b2e925101" +dependencies = [ + "value-bag-serde1", + "value-bag-sval2", +] + +[[package]] +name = "value-bag-serde1" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccacf50c5cb077a9abb723c5bcb5e0754c1a433f1e1de89edc328e2760b6328b" +dependencies = [ + "erased-serde", + "serde", + "serde_fmt", +] + +[[package]] +name = "value-bag-sval2" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1785bae486022dfb9703915d42287dcb284c1ee37bd1080eeba78cc04721285b" +dependencies = [ + "sval", + "sval_buffer", + "sval_dynamic", + "sval_fmt", + "sval_json", + "sval_ref", + "sval_serde", +] + +[[package]] +name = "vcpkg" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "version_check" @@ -1804,6 +2013,61 @@ 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.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" +dependencies = [ + "cfg-if", + "once_cell", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" + [[package]] name = "winapi" version = "0.3.9" @@ -1835,6 +2099,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.4", +] + [[package]] name = "windows-sys" version = "0.52.0" diff --git a/Cargo.toml b/Cargo.toml index 89425fc..83b881e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ members = [ resolver = "2" [workspace.package] -version = "5.7.0" +version = "5.8.0" edition = "2021" authors = ["tison "] readme = "README.md" @@ -32,10 +32,14 @@ repository = "https://github.com/korandoru/hawkeye/" rust-version = "1.76.0" [workspace.dependencies] +anyhow = "1.0" +build-data = "0.2" +clap = { version = "4.5", features = ["derive", "string", "cargo"] } +const_format = { version = "0.2" } hawkeye-fmt = { version = "5.7.0", path = "fmt" } -snafu = "0.8.2" -toml = "0.8.12" -tracing = "0.1.40" +log = { version = "0.4", features = ["kv_unstable_serde", "serde"] } +shadow-rs = "0.32" +toml = "0.8" [workspace.metadata.release] sign-tag = true diff --git a/cli/Cargo.toml b/cli/Cargo.toml index c8f9b1a..f17345d 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -26,11 +26,14 @@ license.workspace = true repository.workspace = true [dependencies] -clap = { version = "4.5.3", features = ["derive", "string", "cargo"] } -hawkeye-fmt.workspace = true -snafu.workspace = true -tracing.workspace = true -tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } +anyhow = { workspace = true } +clap = { workspace = true } +const_format = { workspace = true } +hawkeye-fmt = { workspace = true } +log = { workspace = true } +env_logger = "0.11" +shadow-rs = { workspace = true } [build-dependencies] -build-data = "0.1.5" +build-data = { workspace = true } +shadow-rs = { workspace = true } diff --git a/cli/build.rs b/cli/build.rs index f8c16e4..3dae8ff 100644 --- a/cli/build.rs +++ b/cli/build.rs @@ -15,69 +15,36 @@ // Copyright 2024 - 2024, tison and the HawkEye contributors // SPDX-License-Identifier: Apache-2.0 -use std::{borrow::Cow, sync::OnceLock}; +use std::collections::BTreeSet; +use std::env; -const UNKNOWN: &str = "unknown"; +use build_data::format_timestamp; +use build_data::get_source_time; +use shadow_rs::CARGO_METADATA; +use shadow_rs::CARGO_TREE; -pub struct BuildInfo { - pub branch: Cow<'static, str>, - pub commit: Cow<'static, str>, - pub commit_short: Cow<'static, str>, - pub dirty: Cow<'static, str>, - pub timestamp: Cow<'static, str>, - - /// Rustc Version - pub rustc: Cow<'static, str>, - /// GreptimeDB Version - pub version: Cow<'static, str>, -} - -static BUILD: OnceLock = OnceLock::new(); - -pub fn build_info() -> &'static BuildInfo { - BUILD.get_or_init(|| { - let branch = build_data::get_git_branch() - .map(Cow::Owned) - .unwrap_or(Cow::Borrowed(UNKNOWN)); - let commit = build_data::get_git_commit() - .map(Cow::Owned) - .unwrap_or(Cow::Borrowed(UNKNOWN)); - let commit_short = build_data::get_git_commit_short() - .map(Cow::Owned) - .unwrap_or(Cow::Borrowed(UNKNOWN)); - let dirty = build_data::get_git_dirty() - .map(|b| Cow::Owned(b.to_string())) - .unwrap_or(Cow::Borrowed(UNKNOWN)); - let timestamp = build_data::get_source_time() - .map(|ts| Cow::Owned(build_data::format_timestamp(ts))) - .unwrap_or(Cow::Borrowed(UNKNOWN)); - let rustc = build_data::get_rustc_version() - .map(Cow::Owned) - .unwrap_or(Cow::Borrowed(UNKNOWN)); - let version = Cow::Borrowed(env!("CARGO_PKG_VERSION")); - - BuildInfo { - branch, - commit, - commit_short, - dirty, - timestamp, - rustc, - version, - } - }) -} - -fn main() { - let build_info = build_info(); - println!("cargo:rustc-env=GIT_COMMIT={}", build_info.commit); +fn main() -> shadow_rs::SdResult<()> { + println!("cargo:rerun-if-changed=.git/refs/heads"); println!( - "cargo:rustc-env=GIT_COMMIT_SHORT={}", - build_info.commit_short + "cargo:rustc-env=SOURCE_TIMESTAMP={}", + if let Ok(t) = get_source_time() { + format_timestamp(t) + } else { + "".to_string() + } ); - println!("cargo:rustc-env=GIT_BRANCH={}", build_info.branch); - println!("cargo:rustc-env=GIT_DIRTY={}", build_info.dirty); - println!("cargo:rustc-env=GIT_DIRTY={}", build_info.dirty); - println!("cargo:rustc-env=RUSTC_VERSION={}", build_info.rustc); - println!("cargo:rustc-env=SOURCE_TIMESTAMP={}", build_info.timestamp); + build_data::set_BUILD_TIMESTAMP(); + + // The "CARGO_WORKSPACE_DIR" is set manually (not by Rust itself) in Cargo config file, to + // solve the problem where the "CARGO_MANIFEST_DIR" is not what we want when this repo is + // made as a submodule in another repo. + let src_path = env::var("CARGO_WORKSPACE_DIR").or_else(|_| env::var("CARGO_MANIFEST_DIR"))?; + let out_path = env::var("OUT_DIR")?; + let _ = shadow_rs::Shadow::build_with( + src_path, + out_path, + // exclude these two large constants that we don't need + BTreeSet::from([CARGO_METADATA, CARGO_TREE]), + )?; + Ok(()) } diff --git a/cli/src/main.rs b/cli/src/main.rs index 4e1fd1f..114c634 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -15,47 +15,25 @@ // Copyright 2024 - 2024, tison and the HawkEye contributors // SPDX-License-Identifier: Apache-2.0 -use clap::{crate_description, FromArgMatches, Subcommand}; -use tracing::level_filters::LevelFilter; -use tracing_subscriber::{fmt, layer::SubscriberExt, util::SubscriberInitExt, EnvFilter}; +use clap::crate_description; +use clap::FromArgMatches; +use clap::Subcommand; +use env_logger::Env; -use crate::cli::SubCommand; +use crate::subcommand::SubCommand; -pub mod cli; +pub mod subcommand; +pub mod version; -fn version() -> &'static str { - concat!( - "\nbranch: ", - env!("GIT_BRANCH"), - "\ncommit: ", - env!("GIT_COMMIT"), - "\ndirty: ", - env!("GIT_DIRTY"), - "\nversion: v", - env!("CARGO_PKG_VERSION"), - "\ntoolchain: ", - env!("RUSTC_VERSION"), - "\nbuild: ", - env!("SOURCE_TIMESTAMP"), - ) -} - -fn main() -> hawkeye_fmt::Result<()> { - tracing_subscriber::registry() - .with(fmt::layer()) - .with( - EnvFilter::builder() - .with_default_directive(LevelFilter::INFO.into()) - .from_env_lossy(), - ) - .init(); +fn main() { + env_logger::init_from_env(Env::new().default_filter_or("info")); - let cli = clap::Command::new("hawkeye") + let command = clap::Command::new("hawkeye") .subcommand_required(true) - .version(version()) + .version(version::version()) .about(crate_description!()); - let cli = SubCommand::augment_subcommands(cli); - let args = cli.get_matches(); + let command = SubCommand::augment_subcommands(command); + let args = command.get_matches(); match SubCommand::from_arg_matches(&args) { Ok(cmd) => cmd.run(), Err(e) => e.exit(), diff --git a/cli/src/cli.rs b/cli/src/subcommand.rs similarity index 82% rename from cli/src/cli.rs rename to cli/src/subcommand.rs index 60cae41..b97fe7c 100644 --- a/cli/src/cli.rs +++ b/cli/src/subcommand.rs @@ -15,16 +15,15 @@ // Copyright 2024 - 2024, tison and the HawkEye contributors // SPDX-License-Identifier: Apache-2.0 -use std::path::{Path, PathBuf}; +use std::path::Path; +use std::path::PathBuf; -use clap::{Args, Parser}; -use hawkeye_fmt::{ - document::Document, - header::matcher::HeaderMatcher, - processor::{check_license_header, Callback}, - Result, -}; -use tracing::{error, info, warn}; +use clap::Args; +use clap::Parser; +use hawkeye_fmt::document::Document; +use hawkeye_fmt::header::matcher::HeaderMatcher; +use hawkeye_fmt::processor::check_license_header; +use hawkeye_fmt::processor::Callback; #[derive(Parser)] pub enum SubCommand { @@ -58,7 +57,7 @@ struct SharedEditOptions { } impl SubCommand { - pub fn run(self) -> Result<()> { + pub fn run(self) { match self { SubCommand::Check(cmd) => cmd.run(), SubCommand::Format(cmd) => cmd.run(), @@ -86,39 +85,38 @@ struct CheckContext { } impl Callback for CheckContext { - fn on_unknown(&mut self, path: &Path) -> Result<()> { + fn on_unknown(&mut self, path: &Path) { self.unknown.push(path.display().to_string()); - Ok(()) } - fn on_matched(&mut self, _: &HeaderMatcher, _: Document) -> Result<()> { + fn on_matched(&mut self, _: &HeaderMatcher, _: Document) -> anyhow::Result<()> { Ok(()) } - fn on_not_matched(&mut self, _: &HeaderMatcher, document: Document) -> Result<()> { + fn on_not_matched(&mut self, _: &HeaderMatcher, document: Document) -> anyhow::Result<()> { self.missing.push(document.filepath.display().to_string()); Ok(()) } } impl CommandCheck { - fn run(self) -> Result<()> { + fn run(self) { let config = self.shared.config.unwrap_or_else(default_config); let mut context = CheckContext { unknown: vec![], missing: vec![], }; - check_license_header(config, &mut context)?; + check_license_header(config, &mut context).unwrap(); + let mut failed = check_unknown_files(context.unknown, self.shared.fail_if_unknown); if !context.missing.is_empty() { - error!("Found missing header files: {:?}", context.missing); + log::error!("Found missing header files: {:?}", context.missing); failed |= self.fail_if_missing; } if failed { std::process::exit(1); } - info!("No missing header file has been found."); - Ok(()) + log::info!("No missing header file has been found."); } } @@ -137,16 +135,15 @@ struct FormatContext { } impl Callback for FormatContext { - fn on_unknown(&mut self, path: &Path) -> Result<()> { + fn on_unknown(&mut self, path: &Path) { self.unknown.push(path.display().to_string()); - Ok(()) } - fn on_matched(&mut self, _: &HeaderMatcher, _: Document) -> Result<()> { + fn on_matched(&mut self, _: &HeaderMatcher, _: Document) -> anyhow::Result<()> { Ok(()) } - fn on_not_matched(&mut self, header: &HeaderMatcher, mut doc: Document) -> Result<()> { + fn on_not_matched(&mut self, header: &HeaderMatcher, mut doc: Document) -> anyhow::Result<()> { if doc.header_detected() { doc.remove_header(); doc.update_header(header); @@ -157,6 +154,7 @@ impl Callback for FormatContext { self.updated .push(format!("{}=added", doc.filepath.display())); } + if self.dry_run { let mut extension = doc.filepath.extension().unwrap_or_default().to_os_string(); extension.push(".formatted"); @@ -169,27 +167,28 @@ impl Callback for FormatContext { } impl CommandFormat { - fn run(self) -> Result<()> { + fn run(self) { let config = self.shared.config.unwrap_or_else(default_config); let mut context = FormatContext { dry_run: self.shared_edit.dry_run, unknown: vec![], updated: vec![], }; - check_license_header(config, &mut context)?; + check_license_header(config, &mut context).unwrap(); + let mut failed = check_unknown_files(context.unknown, self.shared.fail_if_unknown); if !context.updated.is_empty() { - info!( + log::info!( "Updated header for files (dryRun={}): {:?}", - self.shared_edit.dry_run, context.updated + self.shared_edit.dry_run, + context.updated ); failed |= self.shared_edit.fail_if_updated; } if failed { std::process::exit(1); } - info!("All files have proper header."); - Ok(()) + log::info!("All files have proper header."); } } @@ -208,7 +207,7 @@ struct RemoveContext { } impl RemoveContext { - fn remove(&mut self, doc: &mut Document) -> Result<()> { + fn remove(&mut self, doc: &mut Document) -> anyhow::Result<()> { if !doc.header_detected() { return Ok(()); } @@ -227,52 +226,52 @@ impl RemoveContext { } impl Callback for RemoveContext { - fn on_unknown(&mut self, path: &Path) -> Result<()> { + fn on_unknown(&mut self, path: &Path) { self.unknown.push(path.display().to_string()); - Ok(()) } - fn on_matched(&mut self, _: &HeaderMatcher, mut doc: Document) -> Result<()> { + fn on_matched(&mut self, _: &HeaderMatcher, mut doc: Document) -> anyhow::Result<()> { self.remove(&mut doc) } - fn on_not_matched(&mut self, _: &HeaderMatcher, mut doc: Document) -> Result<()> { + fn on_not_matched(&mut self, _: &HeaderMatcher, mut doc: Document) -> anyhow::Result<()> { self.remove(&mut doc) } } impl CommandRemove { - fn run(self) -> Result<()> { + fn run(self) { let config = self.shared.config.unwrap_or_else(default_config); let mut context = RemoveContext { dry_run: self.shared_edit.dry_run, unknown: vec![], removed: vec![], }; - check_license_header(config, &mut context)?; + check_license_header(config, &mut context).unwrap(); + let mut failed = check_unknown_files(context.unknown, self.shared.fail_if_unknown); if !context.removed.is_empty() { - info!( + log::info!( "Removed header for files (dryRun={}): {:?}", - self.shared_edit.dry_run, context.removed + self.shared_edit.dry_run, + context.removed ); failed |= self.shared_edit.fail_if_updated; } if failed { std::process::exit(1); } - info!("No file has been removed header."); - Ok(()) + log::info!("No file has been removed header."); } } fn check_unknown_files(unknown: Vec, fail_if_unknown: bool) -> bool { if !unknown.is_empty() { if fail_if_unknown { - error!("Processing unknown files: {:?}", unknown); + log::error!("Processing unknown files: {:?}", unknown); return true; } else { - warn!("Processing unknown files: {:?}", unknown); + log::warn!("Processing unknown files: {:?}", unknown); } } false diff --git a/cli/src/version.rs b/cli/src/version.rs new file mode 100644 index 0000000..b7d6692 --- /dev/null +++ b/cli/src/version.rs @@ -0,0 +1,63 @@ +// Copyright 2024 tison +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Copyright 2024 - 2024, tison and the HawkEye contributors +// SPDX-License-Identifier: Apache-2.0 + +use shadow_rs::shadow; + +shadow!(build); + +#[derive(Clone, Debug, PartialEq)] +pub struct BuildInfo { + pub branch: &'static str, + pub commit: &'static str, + pub commit_short: &'static str, + pub clean: bool, + pub source_time: &'static str, + pub build_time: &'static str, + pub rustc: &'static str, + pub target: &'static str, + pub version: &'static str, +} + +pub const fn build_info() -> BuildInfo { + BuildInfo { + branch: build::BRANCH, + commit: build::COMMIT_HASH, + commit_short: build::SHORT_COMMIT, + clean: build::GIT_CLEAN, + source_time: env!("SOURCE_TIMESTAMP"), + build_time: env!("BUILD_TIMESTAMP"), + rustc: build::RUST_VERSION, + target: build::BUILD_TARGET, + version: build::PKG_VERSION, + } +} + +pub const fn version() -> &'static str { + const BUILD_INFO: BuildInfo = build_info(); + + const_format::formatcp!( + "\nversion: {}\nbranch: {}\ncommit: {}\nclean: {}\nsource_time: {}\nbuild_time: {}\nrustc: {}\ntarget: {}", + BUILD_INFO.version, + BUILD_INFO.branch, + BUILD_INFO.commit, + BUILD_INFO.clean, + BUILD_INFO.source_time, + BUILD_INFO.build_time, + BUILD_INFO.rustc, + BUILD_INFO.target, + ) +} diff --git a/fmt/Cargo.toml b/fmt/Cargo.toml index bf9b2ef..a0a61ef 100644 --- a/fmt/Cargo.toml +++ b/fmt/Cargo.toml @@ -26,16 +26,15 @@ license.workspace = true repository.workspace = true [dependencies] -anyhow = "1.0" -gix = { version = "0.63", default-features = false, features = [ +anyhow = { workspace = true } +gix = { version = "0.64", default-features = false, features = [ "blob-diff", "excludes", ] } -ignore = "0.4.22" -regex = "1.10.3" -serde = { version = "1.0.197", features = ["derive"] } -snafu.workspace = true +ignore = "0.4" +log = { workspace = true } +regex = "1.10" +serde = { version = "1.0", features = ["derive"] } time = "0.3" -toml.workspace = true -tracing.workspace = true -walkdir = "2.5.0" +toml = { workspace = true } +walkdir = "2.5" diff --git a/fmt/src/config/mod.rs b/fmt/src/config/mod.rs index 2062846..0651c31 100644 --- a/fmt/src/config/mod.rs +++ b/fmt/src/config/mod.rs @@ -15,13 +15,16 @@ // Copyright 2024 - 2024, tison and the HawkEye contributors // SPDX-License-Identifier: Apache-2.0 -use std::{ - collections::{HashMap, HashSet}, - hash::{Hash, Hasher}, - path::PathBuf, -}; - -use serde::{de::Error, Deserialize, Deserializer, Serialize}; +use std::collections::HashMap; +use std::collections::HashSet; +use std::hash::Hash; +use std::hash::Hasher; +use std::path::PathBuf; + +use serde::de::Error; +use serde::Deserialize; +use serde::Deserializer; +use serde::Serialize; use toml::Value; use crate::default_true; diff --git a/fmt/src/document/factory.rs b/fmt/src/document/factory.rs index de3fe65..fcbdc85 100644 --- a/fmt/src/document/factory.rs +++ b/fmt/src/document/factory.rs @@ -15,19 +15,20 @@ // Copyright 2024 - 2024, tison and the HawkEye contributors // SPDX-License-Identifier: Apache-2.0 -use std::{ - borrow::Cow, - collections::{HashMap, HashSet}, - path::{Path, PathBuf}, -}; +use std::borrow::Cow; +use std::collections::HashMap; +use std::collections::HashSet; +use std::path::Path; +use std::path::PathBuf; -use snafu::ResultExt; -use time::{format_description, format_description::FormatItem}; +use anyhow::Context; +use time::format_description; +use time::format_description::FormatItem; -use crate::{ - config::Mapping, document::Document, error::CreateDocumentSnafu, git::GitFileAttrs, - header::model::HeaderDef, Result, -}; +use crate::config::Mapping; +use crate::document::Document; +use crate::git::GitFileAttrs; +use crate::header::model::HeaderDef; pub struct DocumentFactory { mapping: HashSet, @@ -58,7 +59,7 @@ impl DocumentFactory { } } - pub fn create_document(&self, filepath: &Path) -> Result> { + pub fn create_document(&self, filepath: &Path) -> anyhow::Result> { let lower_file_name = filepath .file_name() .map(|n| n.to_string_lossy().to_lowercase()) @@ -73,9 +74,7 @@ impl DocumentFactory { .definitions .get(&header_type) .ok_or_else(|| std::io::Error::other(format!("header type {header_type} not found"))) - .context(CreateDocumentSnafu { - path: filepath.display().to_string(), - })?; + .with_context(|| format!("cannot to create document: {}", filepath.display()))?; let mut properties = self.properties.clone(); diff --git a/fmt/src/document/mod.rs b/fmt/src/document/mod.rs index 38270f9..aed7b3c 100644 --- a/fmt/src/document/mod.rs +++ b/fmt/src/document/mod.rs @@ -15,20 +15,19 @@ // Copyright 2024 - 2024, tison and the HawkEye contributors // SPDX-License-Identifier: Apache-2.0 -use std::{collections::HashMap, fs, fs::File, io::BufRead, path::PathBuf}; +use std::collections::HashMap; +use std::fs; +use std::fs::File; +use std::io::BufRead; +use std::path::PathBuf; -use snafu::ResultExt; -use tracing::debug; +use anyhow::Context; -use crate::{ - error::{CreateDocumentSnafu, SaveDocumentSnafu}, - header::{ - matcher::HeaderMatcher, - model::HeaderDef, - parser::{parse_header, FileContent, HeaderParser}, - }, - Result, -}; +use crate::header::matcher::HeaderMatcher; +use crate::header::model::HeaderDef; +use crate::header::parser::parse_header; +use crate::header::parser::FileContent; +use crate::header::parser::HeaderParser; pub mod factory; pub mod model; @@ -48,7 +47,7 @@ impl Document { header_def: HeaderDef, keywords: &[String], properties: HashMap, - ) -> Result> { + ) -> anyhow::Result> { match FileContent::new(&filepath) { Ok(content) => Ok(Some(Self { parser: parse_header(content, &header_def, keywords), @@ -58,11 +57,11 @@ impl Document { })), Err(e) => { if matches!(e.kind(), std::io::ErrorKind::InvalidData) { - debug!("skip non-textual file: {}", filepath.display()); + log::debug!("skip non-textual file: {}", filepath.display()); Ok(None) } else { - Err(e).context(CreateDocumentSnafu { - path: filepath.display().to_string(), + Err(e).with_context(|| { + format!("cannot to create document: {}", filepath.display()) }) } } @@ -142,11 +141,10 @@ impl Document { } } - pub fn save(&mut self, filepath: Option<&PathBuf>) -> Result<()> { + pub fn save(&mut self, filepath: Option<&PathBuf>) -> anyhow::Result<()> { let filepath = filepath.unwrap_or(&self.filepath); - fs::write(filepath, self.parser.file_content.content()).context(SaveDocumentSnafu { - path: filepath.display().to_string(), - }) + fs::write(filepath, self.parser.file_content.content()) + .context(format!("cannot save document {}", filepath.display())) } pub(crate) fn merge_properties(&self, s: &str) -> String { diff --git a/fmt/src/document/model.rs b/fmt/src/document/model.rs index 9721d8e..6cd1047 100644 --- a/fmt/src/document/model.rs +++ b/fmt/src/document/model.rs @@ -17,7 +17,8 @@ use std::collections::HashMap; -use serde::{Deserialize, Serialize}; +use serde::Deserialize; +use serde::Serialize; use crate::config::Mapping; diff --git a/fmt/src/git.rs b/fmt/src/git.rs index 5e2b099..9c66b6c 100644 --- a/fmt/src/git.rs +++ b/fmt/src/git.rs @@ -15,22 +15,18 @@ // Copyright 2024 - 2024, tison and the HawkEye contributors // SPDX-License-Identifier: Apache-2.0 -use std::{ - collections::{hash_map::Entry, HashMap}, - convert::Infallible, - path::{Path, PathBuf}, -}; - +use std::collections::hash_map::Entry; +use std::collections::HashMap; +use std::convert::Infallible; +use std::path::Path; +use std::path::PathBuf; + +use anyhow::bail; +use anyhow::Context; use gix::Repository; -use snafu::IntoError; -use tracing::info; -use crate::{ - config, - config::FeatureGate, - error::{GixDiscoverOpSnafu, InvalidConfigSnafu}, - Result, -}; +use crate::config; +use crate::config::FeatureGate; #[derive(Debug, Clone)] pub struct GitContext { @@ -38,7 +34,7 @@ pub struct GitContext { pub config: config::Git, } -pub fn discover(basedir: &Path, config: config::Git) -> Result { +pub fn discover(basedir: &Path, config: config::Git) -> anyhow::Result { let feature = resolve_features(&config); if feature.is_disable() { @@ -50,14 +46,14 @@ pub fn discover(basedir: &Path, config: config::Git) -> Result { None => { let message = "bare repository detected"; if feature.is_auto() { - info!(?config, "git config is resolved to disabled; {message}"); + log::info!(config:?; "git config is resolved to disabled; {message}"); Ok(GitContext { repo: None, config }) } else { - InvalidConfigSnafu { message }.fail() + bail!("invalid config: {}", message); } } Some(_) => { - info!("git config is resolved to enabled"); + log::info!("git config is resolved to enabled"); Ok(GitContext { repo: Some(repo), config, @@ -66,10 +62,10 @@ pub fn discover(basedir: &Path, config: config::Git) -> Result { }, Err(err) => { if feature.is_auto() { - info!(?err, ?config, "git config is resolved to disabled"); + log::info!(err:?, config:?; "git config is resolved to disabled"); Ok(GitContext { repo: None, config }) } else { - Err(GixDiscoverOpSnafu {}.into_error(Box::new(err))) + Err(err).context("cannot discover git repository with gix") } } } diff --git a/fmt/src/header/matcher.rs b/fmt/src/header/matcher.rs index cae8085..016e674 100644 --- a/fmt/src/header/matcher.rs +++ b/fmt/src/header/matcher.rs @@ -15,7 +15,8 @@ // Copyright 2024 - 2024, tison and the HawkEye contributors // SPDX-License-Identifier: Apache-2.0 -use std::fmt::{Display, Formatter}; +use std::fmt::Display; +use std::fmt::Formatter; use crate::header::model::HeaderDef; diff --git a/fmt/src/header/model.rs b/fmt/src/header/model.rs index 8b00369..701a9b3 100644 --- a/fmt/src/header/model.rs +++ b/fmt/src/header/model.rs @@ -17,15 +17,12 @@ use std::collections::HashMap; +use anyhow::Context; use regex::Regex; -use serde::{Deserialize, Serialize}; -use snafu::{OptionExt, ResultExt}; +use serde::Deserialize; +use serde::Serialize; -use crate::{ - default_true, - error::{DeserializeSnafu, EmptyRegexSnafu, MalformedRegexSnafu}, - Result, -}; +use crate::default_true; #[derive(Debug, Clone)] pub struct HeaderDef { @@ -67,17 +64,13 @@ impl HeaderDef { } } -pub fn default_headers() -> Result> { +pub fn default_headers() -> anyhow::Result> { let defaults = include_str!("defaults.toml"); deserialize_header_definitions(defaults.to_string()) } -pub fn deserialize_header_definitions(value: String) -> Result> { - let header_styles: HashMap = toml::from_str(&value) - .map_err(Box::new) - .context(DeserializeSnafu { - name: "default headers", - })?; +pub fn deserialize_header_definitions(value: String) -> anyhow::Result> { + let header_styles: HashMap = toml::from_str(&value).map_err(Box::new)?; let headers = header_styles .into_iter() @@ -100,24 +93,24 @@ pub fn deserialize_header_definitions(value: String) -> Result>>()?; + .collect::>>()?; Ok(headers) } diff --git a/fmt/src/header/parser.rs b/fmt/src/header/parser.rs index a81fb2b..72ff9ea 100644 --- a/fmt/src/header/parser.rs +++ b/fmt/src/header/parser.rs @@ -15,12 +15,12 @@ // Copyright 2024 - 2024, tison and the HawkEye contributors // SPDX-License-Identifier: Apache-2.0 -use std::{ - fmt::{Display, Formatter}, - fs::File, - io::{BufRead, BufReader}, - path::Path, -}; +use std::fmt::Display; +use std::fmt::Formatter; +use std::fs::File; +use std::io::BufRead; +use std::io::BufReader; +use std::path::Path; use crate::header::model::HeaderDef; diff --git a/fmt/src/lib.rs b/fmt/src/lib.rs index 3d1aa5d..791ca6b 100644 --- a/fmt/src/lib.rs +++ b/fmt/src/lib.rs @@ -15,19 +15,14 @@ // Copyright 2024 - 2024, tison and the HawkEye contributors // SPDX-License-Identifier: Apache-2.0 -use crate::error::Error; - pub mod config; pub mod document; -pub mod error; pub mod git; pub mod header; pub mod license; pub mod processor; pub mod selection; -pub type Result = std::result::Result; - const fn default_true() -> bool { true } diff --git a/fmt/src/license/mod.rs b/fmt/src/license/mod.rs index 0f3a780..b0758e5 100644 --- a/fmt/src/license/mod.rs +++ b/fmt/src/license/mod.rs @@ -15,9 +15,9 @@ // Copyright 2024 - 2024, tison and the HawkEye contributors // SPDX-License-Identifier: Apache-2.0 -use snafu::OptionExt; +use anyhow::Context; -use crate::{config::Config, error::InvalidConfigSnafu, Result}; +use crate::config::Config; #[derive(Debug, Clone)] pub struct HeaderSource { @@ -25,16 +25,17 @@ pub struct HeaderSource { } impl HeaderSource { - pub fn from_config(config: &Config) -> Result { + pub fn from_config(config: &Config) -> anyhow::Result { // 1. inline_header takes priority. if let Some(content) = config.inline_header.as_ref().cloned() { return Ok(HeaderSource { content }); } // 2. Then, header_path tries to load from base_dir. - let header_path = config.header_path.as_ref().context(InvalidConfigSnafu { - message: "no header source found (both inline_header and header_path are None)", - })?; + let header_path = config + .header_path + .as_ref() + .context("no header source found (both inline_header and header_path are None)")?; let path = { let mut path = config.base_dir.clone(); path.push(header_path); @@ -45,8 +46,8 @@ impl HeaderSource { } // 3. Finally, fallback to try bundled headers. - bundled_headers(header_path).context(InvalidConfigSnafu { - message: format!("no header source found (header_path is invalid: {header_path})"), + bundled_headers(header_path).with_context(|| { + format!("no header source found (header_path is invalid: {header_path})") }) } } diff --git a/fmt/src/processor.rs b/fmt/src/processor.rs index 4085d32..a41a0a0 100644 --- a/fmt/src/processor.rs +++ b/fmt/src/processor.rs @@ -15,62 +15,56 @@ // Copyright 2024 - 2024, tison and the HawkEye contributors // SPDX-License-Identifier: Apache-2.0 -use std::{ - fs, - path::{Path, PathBuf}, -}; - -use snafu::{ensure, ResultExt}; - -use crate::{ - config::Config, - document::{factory::DocumentFactory, model::default_mapping, Document}, - error::{ - DeserializeSnafu, GitFileAttrsSnafu, InvalidConfigSnafu, LoadConfigSnafu, - TryMatchHeaderSnafu, - }, - git, - header::{ - matcher::HeaderMatcher, - model::{default_headers, deserialize_header_definitions}, - }, - license::HeaderSource, - selection::Selection, - Result, -}; +use std::fs; +use std::path::Path; +use std::path::PathBuf; + +use anyhow::Context; + +use crate::config::Config; +use crate::document::factory::DocumentFactory; +use crate::document::model::default_mapping; +use crate::document::Document; +use crate::git; +use crate::header::matcher::HeaderMatcher; +use crate::header::model::default_headers; +use crate::header::model::deserialize_header_definitions; +use crate::license::HeaderSource; +use crate::selection::Selection; /// Callback for processing the result of checking license headers. pub trait Callback { /// Called when the header is unknown. - fn on_unknown(&mut self, path: &Path) -> Result<()>; + fn on_unknown(&mut self, path: &Path); /// Called when the header is matched. - fn on_matched(&mut self, header: &HeaderMatcher, document: Document) -> Result<()>; + fn on_matched(&mut self, header: &HeaderMatcher, document: Document) -> anyhow::Result<()>; /// Called when the header is not matched. - fn on_not_matched(&mut self, header: &HeaderMatcher, document: Document) -> Result<()>; + fn on_not_matched(&mut self, header: &HeaderMatcher, document: Document) -> anyhow::Result<()>; } #[allow(clippy::type_complexity)] -pub fn check_license_header(run_config: PathBuf, callback: &mut C) -> Result<()> { +pub fn check_license_header( + run_config: PathBuf, + callback: &mut C, +) -> anyhow::Result<()> { let config = { let name = run_config.display().to_string(); - let config = - fs::read_to_string(&run_config).context(LoadConfigSnafu { name: name.clone() })?; + let config = fs::read_to_string(&run_config) + .with_context(|| format!("cannot load config: {name}"))?; toml::from_str::(&config) .map_err(Box::new) - .context(DeserializeSnafu { name })? + .with_context(|| format!("cannot parse config file: {name}"))? }; let basedir = config.base_dir.clone(); - ensure!( + anyhow::ensure!( basedir.is_dir(), - InvalidConfigSnafu { - message: format!( - "{} does not exist or is not a directory.", - basedir.display() - ) - } + format!( + "{} does not exist or is not a directory.", + basedir.display() + ) ); let git_context = git::discover(&basedir, config.git)?; @@ -100,9 +94,7 @@ pub fn check_license_header(run_config: PathBuf, callback: &mut C) let mut defs = default_headers()?; for additional_header in &config.additional_headers { let additional_defs = fs::read_to_string(additional_header) - .context(LoadConfigSnafu { - name: additional_header.clone(), - }) + .with_context(|| format!("cannot load header definitions: {additional_header}")) .and_then(deserialize_header_definitions)?; defs.extend(additional_defs); } @@ -114,7 +106,7 @@ pub fn check_license_header(run_config: PathBuf, callback: &mut C) HeaderMatcher::new(header_source.content) }; - let git_file_attrs = git::resolve_file_attrs(git_context).context(GitFileAttrsSnafu)?; + let git_file_attrs = git::resolve_file_attrs(git_context)?; let document_factory = DocumentFactory::new( mapping, @@ -128,16 +120,16 @@ pub fn check_license_header(run_config: PathBuf, callback: &mut C) let document = match document_factory.create_document(&file)? { Some(document) => document, None => { - callback.on_unknown(&file)?; + callback.on_unknown(&file); continue; } }; if document.is_unsupported() { - callback.on_unknown(&file)?; + callback.on_unknown(&file); } else if document .header_matched(&header_matcher, config.strict_check) - .context(TryMatchHeaderSnafu)? + .context("failed to match header")? { callback.on_matched(&header_matcher, document)?; } else { diff --git a/fmt/src/selection.rs b/fmt/src/selection.rs index ba2fefd..b66cd10 100644 --- a/fmt/src/selection.rs +++ b/fmt/src/selection.rs @@ -15,21 +15,14 @@ // Copyright 2024 - 2024, tison and the HawkEye contributors // SPDX-License-Identifier: Apache-2.0 -use std::path::{Path, PathBuf}; +use std::path::Path; +use std::path::PathBuf; +use anyhow::Context; use ignore::overrides::OverrideBuilder; -use snafu::{ensure, ResultExt}; -use tracing::debug; use walkdir::WalkDir; -use crate::{ - error::{ - GixCheckExcludeOpSnafu, GixExcludeOpSnafu, ResolveAbsolutePathSnafu, SelectFilesSnafu, - SelectWithIgnoreSnafu, TraverseDirSnafu, - }, - git::GitContext, - Result, -}; +use crate::git::GitContext; pub struct Selection { basedir: PathBuf, @@ -71,9 +64,9 @@ impl Selection { } } - pub fn select(self) -> Result> { - debug!( - "Selecting files with baseDir: {}, included: {:?}, excluded: {:?}", + pub fn select(self) -> anyhow::Result> { + log::debug!( + "selecting files with baseDir: {}, included: {:?}, excluded: {:?}", self.basedir.display(), self.includes, self.excludes, @@ -82,7 +75,7 @@ impl Selection { let (excludes, reverse_excludes) = { let mut excludes = self.excludes; let mut reverse_excludes = vec![]; - // [TODO] can be simplified and no clone when extract_if stable + // TODO(tisonkun): can be simplified and no clone when extract_if stable excludes.retain_mut(|pat| { if pat.starts_with('!') { pat.remove(0); @@ -96,11 +89,9 @@ impl Selection { }; let includes = self.includes; - ensure!( + anyhow::ensure!( includes.iter().all(|pat| !pat.starts_with('!')), - SelectFilesSnafu { - message: format!("reverse pattern is not allowed for includes: {includes:?}"), - }, + "select files failed; reverse pattern is not allowed for includes: {includes:?}" ); let ignore = self.git_context.config.ignore.is_auto(); @@ -117,7 +108,7 @@ impl Selection { } }; - debug!("selected files: {:?} (count: {})", result, result.len()); + log::debug!("selected files: {:?} (count: {})", result, result.len()); Ok(result) } } @@ -128,8 +119,8 @@ fn select_files_with_ignore( excludes: &[String], reverse_excludes: &[String], turn_on_git_ignore: bool, -) -> Result> { - debug!(turn_on_git_ignore, "Selecting files with ignore crate"); +) -> anyhow::Result> { + log::debug!(turn_on_git_ignore; "Selecting files with ignore crate"); let mut result = vec![]; let walker = ignore::WalkBuilder::new(basedir) @@ -143,21 +134,21 @@ fn select_files_with_ignore( .overrides({ let mut builder = OverrideBuilder::new(basedir); for pat in includes.iter() { - builder.add(pat).context(SelectWithIgnoreSnafu)?; + builder.add(pat)?; } for pat in excludes.iter() { let pat = format!("!{pat}"); - builder.add(pat.as_str()).context(SelectWithIgnoreSnafu)?; + builder.add(pat.as_str())?; } for pat in reverse_excludes.iter() { - builder.add(pat).context(SelectWithIgnoreSnafu)?; + builder.add(pat)?; } - builder.build().context(SelectWithIgnoreSnafu)? + builder.build()? }) .build(); for mat in walker { - let mat = mat.context(SelectWithIgnoreSnafu)?; + let mat = mat?; if mat.file_type().map(|ft| ft.is_file()).unwrap_or(false) { result.push(mat.into_path()) } @@ -172,50 +163,48 @@ fn select_files_with_git( excludes: &[String], reverse_excludes: &[String], repo: gix::Repository, -) -> Result> { - debug!("Selecting files with git helper"); +) -> anyhow::Result> { + log::debug!("selecting files with git helper"); let mut result = vec![]; let matcher = { let mut builder = OverrideBuilder::new(basedir); for pat in includes.iter() { - builder.add(pat).context(SelectWithIgnoreSnafu)?; + builder.add(pat)?; } for pat in excludes.iter() { let pat = format!("!{pat}"); - builder.add(pat.as_str()).context(SelectWithIgnoreSnafu)?; + builder.add(pat.as_str())?; } for pat in reverse_excludes.iter() { - builder.add(pat).context(SelectWithIgnoreSnafu)?; + builder.add(pat)?; } - builder.build().context(SelectWithIgnoreSnafu)? + builder.build()? }; let basedir = basedir .canonicalize() - .with_context(|_| ResolveAbsolutePathSnafu { - path: basedir.display().to_string(), - })?; - let mut it = WalkDir::new(basedir).follow_links(false).into_iter(); + .with_context(|| format!("cannot resolve absolute path: {}", basedir.display()))?; + let mut it = WalkDir::new(basedir.clone()) + .follow_links(false) + .into_iter(); let workdir = repo.work_dir().expect("workdir cannot be absent"); let workdir = workdir .canonicalize() - .with_context(|_| ResolveAbsolutePathSnafu { - path: workdir.display().to_string(), - })?; + .with_context(|| format!("cannot resolve absolute path: {}", basedir.display()))?; let worktree = repo.worktree().expect("worktree cannot be absent"); let mut excludes = worktree .excludes(None) .map_err(Box::new) - .context(GixExcludeOpSnafu)?; + .context("cannot create gix exclude stack")?; while let Some(entry) = it.next() { - let entry = entry.context(TraverseDirSnafu)?; + let entry = entry.context("cannot traverse directory")?; let path = entry.path(); let file_type = entry.file_type(); if !file_type.is_file() && !file_type.is_dir() { - debug!(?file_type, "skip file: {path:?}"); + log::debug!(file_type:?; "skip file: {path:?}"); continue; } @@ -229,29 +218,29 @@ fn select_files_with_git( }); let platform = excludes .at_path(rela_path, mode) - .context(GixCheckExcludeOpSnafu)?; + .context("cannot check gix exclude")?; if file_type.is_dir() { if platform.is_excluded() { - debug!(?path, ?rela_path, "skip git ignored directory"); + log::debug!(path:?, rela_path:?; "skip git ignored directory"); it.skip_current_dir(); continue; } if matcher.matched(rela_path, file_type.is_dir()).is_ignore() { - debug!(?path, ?rela_path, "skip glob ignored directory"); + log::debug!(path:?, rela_path:?; "skip glob ignored directory"); it.skip_current_dir(); continue; } } else if file_type.is_file() { if platform.is_excluded() { - debug!(?path, ?rela_path, "skip git ignored file"); + log::debug!(path:?, rela_path:?; "skip git ignored file"); continue; } if !matcher .matched(rela_path, file_type.is_dir()) .is_whitelist() { - debug!(?path, ?rela_path, "skip glob ignored file"); + log::debug!(path:?, rela_path:?; "skip glob ignored file"); continue; } result.push(path.to_path_buf()); diff --git a/fmt/tests/tests.rs b/fmt/tests/tests.rs index 8f1b684..88023b4 100644 --- a/fmt/tests/tests.rs +++ b/fmt/tests/tests.rs @@ -17,10 +17,9 @@ use std::path::Path; -use hawkeye_fmt::header::{ - model::default_headers, - parser::{parse_header, FileContent}, -}; +use hawkeye_fmt::header::model::default_headers; +use hawkeye_fmt::header::parser::parse_header; +use hawkeye_fmt::header::parser::FileContent; #[test] fn test_remove_file_only_header() { diff --git a/licenserc.toml b/licenserc.toml index 2faff9e..68444bb 100644 --- a/licenserc.toml +++ b/licenserc.toml @@ -41,6 +41,7 @@ excludes = [ # Test files "fmt/tests/content/**", "tests/load_header_path/**", + "tests/regression_blank_line/**", # Generated files ".github/workflows/release.yml", diff --git a/rustfmt.toml b/rustfmt.toml index 8328a59..c3d8222 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -15,7 +15,7 @@ # Copyright 2024 - 2024, tison and the HawkEye contributors # SPDX-License-Identifier: Apache-2.0 -imports_granularity = "Crate" +imports_granularity = "Item" group_imports = "StdExternalCrate" comment_width = 120 wrap_comments = true diff --git a/tests/.gitignore b/tests/.gitignore new file mode 100644 index 0000000..94a3dc5 --- /dev/null +++ b/tests/.gitignore @@ -0,0 +1 @@ +*.formatted diff --git a/tests/it.py b/tests/it.py index b221547..6f6342d 100755 --- a/tests/it.py +++ b/tests/it.py @@ -17,11 +17,27 @@ # SPDX-License-Identifier: Apache-2.0 from pathlib import Path +import difflib import subprocess +def diff_files(file1, file2): + with file1.open("r", encoding="utf8") as f1, file2.open("r", encoding="utf8") as f2: + diff = difflib.unified_diff(f1.readlines(), f2.readlines(), str(file1), str(file2)) + diff = list(diff) + if diff: + for line in diff: + print(line, end="") + exit(1) + + basedir = Path(__file__).parent.absolute() rootdir = basedir.parent subprocess.run(["cargo", "build", "--bin", "hawkeye"], cwd=rootdir, check=True) hawkeye = rootdir / "target" / "debug" / "hawkeye" -subprocess.run([hawkeye, "check", "--fail-if-unknown"], cwd=(basedir / "load_header_path"), check=True) + +subprocess.run([hawkeye, "format", "--fail-if-unknown", "--fail-if-updated=false", "--dry-run"], cwd=(basedir / "load_header_path"), check=True) +diff_files(basedir / "load_header_path" / "main.rs.expected", basedir / "load_header_path" / "main.rs.formatted") + +subprocess.run([hawkeye, "format", "--fail-if-unknown", "--fail-if-updated=false", "--dry-run"], cwd=(basedir / "regression_blank_line"), check=True) +diff_files(basedir / "regression_blank_line" / "main.rs.expected", basedir / "regression_blank_line" / "main.rs.formatted") diff --git a/tests/load_header_path/licenserc.toml b/tests/load_header_path/licenserc.toml index c8b6c51..d91f27a 100644 --- a/tests/load_header_path/licenserc.toml +++ b/tests/load_header_path/licenserc.toml @@ -1,19 +1,7 @@ -# Copyright 2024 Mike Delaney -# -# Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -# -# 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - baseDir = "." headerPath = "license.txt" -excludes = [ ] +excludes = ["licenserc.toml", "*.expected"] [properties] inceptionYear = 2024 diff --git a/tests/load_header_path/main.rs b/tests/load_header_path/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/tests/load_header_path/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/tests/load_header_path/main.rs.expected b/tests/load_header_path/main.rs.expected new file mode 100644 index 0000000..4a3d735 --- /dev/null +++ b/tests/load_header_path/main.rs.expected @@ -0,0 +1,15 @@ +// Copyright 2024 Mike Delaney +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +fn main() { + println!("Hello, world!"); +} diff --git a/tests/regression_blank_line/licenserc.toml b/tests/regression_blank_line/licenserc.toml new file mode 100644 index 0000000..159b1db --- /dev/null +++ b/tests/regression_blank_line/licenserc.toml @@ -0,0 +1,9 @@ +baseDir = "." +headerPath = "Apache-2.0.txt" + +includes = ["*.rs"] +excludes = ["*.expected"] + +[properties] +inceptionYear = 2023 +copyrightOwner = "The CopyrightOwner" diff --git a/tests/regression_blank_line/main.rs b/tests/regression_blank_line/main.rs new file mode 100644 index 0000000..0a908d6 --- /dev/null +++ b/tests/regression_blank_line/main.rs @@ -0,0 +1,5 @@ +// Copyright 2022-2023 The Authors. Licensed under Apache-2.0. + +//! Load balancer + +use macros::define_result; diff --git a/tests/regression_blank_line/main.rs.expected b/tests/regression_blank_line/main.rs.expected new file mode 100644 index 0000000..87d00ff --- /dev/null +++ b/tests/regression_blank_line/main.rs.expected @@ -0,0 +1,17 @@ +// Copyright 2023 The CopyrightOwner +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Load balancer + +use macros::define_result;