diff --git a/Cargo.lock b/Cargo.lock index 02b52cb..8c52eb4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,9 +13,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.14" +version = "0.6.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" dependencies = [ "anstyle", "anstyle-parse", @@ -28,33 +28,33 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" [[package]] name = "anstyle-parse" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" dependencies = [ "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.3" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" dependencies = [ "anstyle", "windows-sys 0.52.0", @@ -62,15 +62,15 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "bitflags" @@ -87,15 +87,27 @@ dependencies = [ "generic-array", ] +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "cc" -version = "1.0.104" +version = "1.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74b6a57f98764a267ff415d50a25e6e166f3831a5071af4995296ea97d210490" +checksum = "2e80e3b6a3ab07840e1cae9b0666a63970dc28e8ed5ffbcdacbfc760c281bfc1" dependencies = [ "jobserver", "libc", - "once_cell", + "shlex", ] [[package]] @@ -106,9 +118,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.5.8" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84b3edb18336f4df585bc9aa31dd99c036dfa5dc5e9a2939a722a188f3a8970d" +checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" dependencies = [ "clap_builder", "clap_derive", @@ -116,9 +128,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.8" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1c09dd5ada6c6c78075d6fd0da3f90d8080651e2d6cc8eb2f1aaa4034ced708" +checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" dependencies = [ "anstream", "anstyle", @@ -128,9 +140,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.8" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bac35c6dafb060fd4d275d9a4ffae97917c13a6327903a8be2153cd964f7085" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" dependencies = [ "heck", "proc-macro2", @@ -140,15 +152,15 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "colorchoice" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" [[package]] name = "colored" @@ -162,9 +174,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.12" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" dependencies = [ "libc", ] @@ -245,6 +257,12 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + [[package]] name = "either" version = "1.13.0" @@ -269,9 +287,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" +checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" [[package]] name = "form_urlencoded" @@ -282,6 +300,16 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fsio" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dad0ce30be0cc441b325c5d705c8b613a0ca0d92b6a8953d41bd236dc09a36d0" +dependencies = [ + "dunce", + "rand", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -292,11 +320,24 @@ dependencies = [ "version_check", ] +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + [[package]] name = "git2" -version = "0.18.3" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "232e6a7bfe35766bf715e55a88b39a700596c0ccfd88cd3680b4cdb40d66ef70" +checksum = "b903b73e45dc0c6c596f2d37eccece7c1c8bb6e4407b001096387c63d0d93724" dependencies = [ "bitflags", "libc", @@ -309,9 +350,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.5" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" [[package]] name = "heck" @@ -346,9 +387,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.6" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", "hashbrown", @@ -356,9 +397,9 @@ dependencies = [ [[package]] name = "is_terminal_polyfill" -version = "1.70.0" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "itertools" @@ -377,13 +418,22 @@ checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jobserver" -version = "0.1.31" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" +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 = "lazy_static" version = "1.5.0" @@ -392,43 +442,28 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.155" +version = "0.2.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" [[package]] name = "libgit2-sys" -version = "0.16.2+1.7.2" +version = "0.17.0+1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee4126d8b4ee5c9d9ea891dd875cfdc1e9d0950437179104b183d7d8a74d24e8" +checksum = "10472326a8a6477c3c20a64547b0059e4b0d086869eee31e6d7da728a8eb7224" dependencies = [ "cc", "libc", - "libssh2-sys", "libz-sys", "openssl-sys", "pkg-config", ] -[[package]] -name = "libssh2-sys" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dc8a030b787e2119a731f1951d6a773e2280c660f8ec4b0f5e1505a386e71ee" -dependencies = [ - "cc", - "libc", - "libz-sys", - "openssl-sys", - "pkg-config", - "vcpkg", -] - [[package]] name = "libz-sys" -version = "1.1.18" +version = "1.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c15da26e5af7e25c90b37a2d75cdbf940cf4a55316de9d84c679c9b8bfabf82e" +checksum = "d2d16453e800a8cf6dd2fc3eb4bc99b786a9b90c663b8559a5b1a041bf89e472" dependencies = [ "cc", "libc", @@ -444,11 +479,14 @@ dependencies = [ "clap", "colored", "crossbeam", + "getrandom", "git2", "lazy_static", "log", + "print_logger", "rayon", "regex", + "run_script", "serde", "serde_derive", "serde_json", @@ -481,6 +519,9 @@ name = "log" version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +dependencies = [ + "value-bag", +] [[package]] name = "memchr" @@ -488,16 +529,6 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" -[[package]] -name = "memmap" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "minimal-lexical" version = "0.2.1" @@ -526,9 +557,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "openssl-probe" @@ -538,9 +569,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.102" +version = "0.9.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" +checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" dependencies = [ "cc", "libc", @@ -579,28 +610,78 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pkg-config" -version = "0.3.30" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" + +[[package]] +name = "ppv-lite86" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "print_logger" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b5eab70ba6d3b75e14626179d0df093eadc855d76f04b8da2e48804c06cc633" +dependencies = [ + "log", + "regex", + "termcolor", +] [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + [[package]] name = "rayon" version = "1.10.0" @@ -623,18 +704,18 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.2" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" dependencies = [ "bitflags", ] [[package]] name = "regex" -version = "1.10.5" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" dependencies = [ "aho-corasick", "memchr", @@ -644,9 +725,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" dependencies = [ "aho-corasick", "memchr", @@ -655,15 +736,24 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "run_script" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f20d7c40e6d6fc2ff69ad8e8bac4d39a5fc1874402647ac92b620954d56d5c3e" +dependencies = [ + "fsio", +] [[package]] name = "rustix" -version = "0.38.34" +version = "0.38.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" dependencies = [ "bitflags", "errno", @@ -686,18 +776,18 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" -version = "1.0.203" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.203" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", @@ -706,20 +796,21 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.120" +version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] [[package]] name = "serde_spanned" -version = "0.6.6" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" dependencies = [ "serde", ] @@ -738,16 +829,23 @@ dependencies = [ [[package]] name = "sha1dir" version = "1.0.10" -source = "git+https://github.com/tanneberger/sha1dir#cf5a15703edcb3946ca847353cec4af644fcba75" +source = "git+https://github.com/tanneberger/sha1dir#0ca1e593297836663bab09a7d69156fd580f8e2a" dependencies = [ "clap", - "memmap", + "js-sys", "num_cpus", "parking_lot", "rayon", "sha1", + "wasm-logger", ] +[[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" @@ -762,9 +860,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.68" +version = "2.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "901fa70d88b9d6c98022e23b4136f9f3e54e4662c3bc1bd1d84a42a9a0f0c1e9" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" dependencies = [ "proc-macro2", "quote", @@ -773,21 +871,31 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.10.1" +version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" dependencies = [ "cfg-if", "fastrand", + "once_cell", "rustix", - "windows-sys 0.52.0", + "windows-sys 0.59.0", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", ] [[package]] name = "tinyvec" -version = "1.6.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c55115c6fbe2d2bef26eb09ad74bde02d8255476fc0c7b515ef09fbb35742d82" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ "tinyvec_macros", ] @@ -800,9 +908,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "toml" -version = "0.8.14" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" dependencies = [ "serde", "serde_spanned", @@ -812,18 +920,18 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.6" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.22.14" +version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f21c7aaf97f1bd9ca9d4f9e73b0a6c74bd5afef56f2bc931943a6e1c37e04e38" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ "indexmap", "serde", @@ -840,21 +948,21 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unicode-bidi" -version = "0.3.15" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" +checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "unicode-normalization" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" dependencies = [ "tinyvec", ] @@ -877,6 +985,12 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "value-bag" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a84c137d37ab0142f0f2ddfe332651fdbf252e7b7dbb4e67b6c1f1b2e925101" + [[package]] name = "vcpkg" version = "0.2.15" @@ -885,9 +999,9 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "versions" @@ -901,38 +1015,107 @@ dependencies = [ ] [[package]] -name = "which" -version = "6.0.1" +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.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8211e4f58a2b2805adfbefbc07bab82958fc91e3836339b1ab7ae32465dce0d7" +checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" dependencies = [ - "either", - "home", - "rustix", - "winsafe", + "cfg-if", + "once_cell", + "wasm-bindgen-macro", ] [[package]] -name = "winapi" -version = "0.3.9" +name = "wasm-bindgen-backend" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", ] [[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" +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 = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] [[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" +name = "wasm-bindgen-shared" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" + +[[package]] +name = "wasm-logger" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "074649a66bb306c8f2068c9016395fa65d8e08d2affcbf95acf3c24c3ab19718" +dependencies = [ + "log", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "web-sys" +version = "0.3.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "which" +version = "6.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ee928febd44d98f2f459a4a79bd4d928591333a494a10a868418ac1b39cf1f" +dependencies = [ + "either", + "home", + "rustix", + "winsafe", +] + +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.59.0", +] [[package]] name = "windows-sys" @@ -952,6 +1135,15 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-targets" version = "0.48.5" @@ -1075,9 +1267,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.6.13" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59b5e5f6c299a3c7890b876a2a587f3115162487e704907d9b6cd29473052ba1" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" dependencies = [ "memchr", ] @@ -1087,3 +1279,24 @@ name = "winsafe" version = "0.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904" + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/Cargo.toml b/Cargo.toml index 1133fc4..ec8bb2f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,10 +8,20 @@ homepage = "https://lf-lang.org" repository = "https://github.com/lf-lang/lingo" license = "BSD-2-Clause" +[lib] +name = "liblingo" +path = "src/lib.rs" +crate-type = ["cdylib", "rlib"] + [[bin]] name = "lingo" publish = true path = "./src/main.rs" +required-features = ["binary"] + +[features] +default = ["binary"] +binary = ["which", "git2"] [dependencies] @@ -19,13 +29,16 @@ clap = { version = "4.1", features = ["derive"] } serde = "1.0" serde_json = "1.0" serde_derive = "1.0" -which = "6.0" regex = "1.8" lazy_static = "1.4" rayon = "1.7" -toml = {version = "0.8"} +toml = { version = "0.8" } crossbeam = "0.8" -git2 = "0.18" +run_script = "0.11" +getrandom = {version="0.2", features = ["js"]} +which = { version = "6.0", optional = true } +git2 = { version = "0.19", optional = true, default-features=false, features = ["https"]} +print_logger = "0.2.0" tempfile = "3.0" url = { version = "2.5", features = ["serde"] } anyhow = "1.0" diff --git a/src/args.rs b/src/args.rs index f60d98d..6423ac8 100644 --- a/src/args.rs +++ b/src/args.rs @@ -7,6 +7,7 @@ use std::path::PathBuf; #[value(rename_all = "lowercase")] pub enum TargetLanguage { C, + CCpp, Cpp, Rust, TypeScript, diff --git a/src/backends/cmake_c.rs b/src/backends/cmake_c.rs index a3718bf..235db54 100644 --- a/src/backends/cmake_c.rs +++ b/src/backends/cmake_c.rs @@ -5,9 +5,9 @@ use std::process::Command; use crate::backends::{ BatchBackend, BatchBuildResults, BuildCommandOptions, BuildProfile, BuildResult, CommandSpec, }; +use crate::package::App; use crate::util::errors::LingoError; use crate::util::execute_command_to_build_result; -use crate::App; pub struct CmakeC; diff --git a/src/backends/cmake_cpp.rs b/src/backends/cmake_cpp.rs index eab56b5..62e85b8 100644 --- a/src/backends/cmake_cpp.rs +++ b/src/backends/cmake_cpp.rs @@ -3,8 +3,8 @@ use std::io::Write; use std::process::Command; +use crate::package::App; use crate::util::execute_command_to_build_result; -use crate::App; use crate::backends::{ BatchBackend, BatchBuildResults, BuildCommandOptions, BuildProfile, BuildResult, CommandSpec, diff --git a/src/backends/lfc.rs b/src/backends/lfc.rs index 6730f3d..97edd53 100644 --- a/src/backends/lfc.rs +++ b/src/backends/lfc.rs @@ -60,7 +60,7 @@ impl BatchBackend for LFC { /// Formats LFC arguments to JSON. #[derive(Serialize, Clone)] -struct LfcJsonArgs<'a> { +pub struct LfcJsonArgs<'a> { /// Path to the LF source file containing the main reactor. pub src: &'a Path, /// Path to the directory into which build artifacts like diff --git a/src/backends/mod.rs b/src/backends/mod.rs index 60ce8e2..5c7c790 100644 --- a/src/backends/mod.rs +++ b/src/backends/mod.rs @@ -11,6 +11,7 @@ use crate::package::{ OUTPUT_DIRECTORY, }; use crate::util::errors::{AnyError, BuildResult, LingoError}; +use crate::{GitCloneAndCheckoutCap, WhichCapability}; pub mod cmake_c; pub mod cmake_cpp; @@ -19,7 +20,12 @@ pub mod npm; pub mod pnpm; #[allow(clippy::single_match)] // there more options will be added to this match block -pub fn execute_command<'a>(command: &CommandSpec, config: &'a mut Config) -> BatchBuildResults<'a> { +pub fn execute_command<'a>( + command: &CommandSpec, + config: &'a mut Config, + which: WhichCapability, + clone: GitCloneAndCheckoutCap, +) -> BatchBuildResults<'a> { let mut result = BatchBuildResults::new(); let dependencies = Vec::from_iter(config.dependencies.clone()); @@ -28,6 +34,7 @@ pub fn execute_command<'a>(command: &CommandSpec, config: &'a mut Config) -> Bat let manager = match DependencyManager::from_dependencies( dependencies.clone(), &PathBuf::from(OUTPUT_DIRECTORY), + &clone, ) { Ok(value) => value, Err(e) => { @@ -54,7 +61,7 @@ pub fn execute_command<'a>(command: &CommandSpec, config: &'a mut Config) -> Bat let mut by_build_system = HashMap::<(BuildSystem, TargetLanguage), Vec<&App>>::new(); for app in &config.apps { by_build_system - .entry((app.build_system(), app.target)) + .entry((app.build_system(&which), app.target)) .or_default() .push(app); } @@ -168,10 +175,10 @@ impl<'a> BatchBuildResults<'a> { for (app, b) in &self.results { match b { Ok(()) => { - println!("- {}: Success", &app.name); + log::info!("- {}: Success", &app.name); } Err(e) => { - println!("- {}: Error: {}", &app.name, e); + log::error!("- {}: Error: {}", &app.name, e); } } } diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..48531f2 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,63 @@ +use crate::package::tree::GitLock; +use std::io; + +pub mod args; +pub mod backends; +pub mod package; +pub mod util; + +#[derive(Debug)] +pub enum WhichError { + /// An executable binary with that name was not found + CannotFindBinaryPath, + /// There was nowhere to search and the provided name wasn't an absolute path + CannotGetCurrentDirAndPathListEmpty, + /// Failed to canonicalize the path found + CannotCanonicalize, +} +#[derive(Debug)] +pub struct GitCloneError(pub String); // TODO: create a more domain-specific error time like the actual git2::Error + +impl std::fmt::Display for WhichError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + WhichError::CannotFindBinaryPath => write!(f, "cannot find binary"), + WhichError::CannotGetCurrentDirAndPathListEmpty => { + write!(f, "cannot get current dir and path list empty") + } + WhichError::CannotCanonicalize => write!(f, "cannot canonicalize"), + } + } +} + +impl std::fmt::Display for GitCloneError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) + } +} + +impl std::error::Error for WhichError {} + +impl std::error::Error for GitCloneError {} + +pub struct GitUrl<'a>(&'a str); + +impl<'a> From<&'a str> for GitUrl<'a> { + fn from(value: &'a str) -> Self { + GitUrl(value) + } +} + +impl<'a> From> for &'a str { + fn from(value: GitUrl<'a>) -> Self { + value.0 + } +} + +pub type WhichCapability<'a> = Box Result + 'a>; +pub type GitCloneCapability<'a> = + Box Result<(), GitCloneError> + 'a>; +pub type FsReadCapability<'a> = Box io::Result + 'a>; +pub type GitCloneAndCheckoutCap<'a> = Box< + dyn Fn(GitUrl, &std::path::Path, Option) -> Result, GitCloneError> + 'a, +>; diff --git a/src/main.rs b/src/main.rs index 519d39a..9715753 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,35 +1,92 @@ +use liblingo::args::TargetLanguage; use std::io::ErrorKind; -use std::path::Path; +use std::path::{Path, PathBuf}; use std::process::Command; use std::{env, io}; use clap::Parser; +use git2::Repository; + +use liblingo::args::InitArgs; +use liblingo::args::{BuildArgs, Command as ConsoleCommand, CommandLineArgs}; +use liblingo::backends::{BatchBuildResults, BuildCommandOptions, CommandSpec}; +use liblingo::package::tree::GitLock; +use liblingo::package::{Config, ConfigFile}; +use liblingo::util::errors::{BuildResult, LingoError}; +use liblingo::{GitCloneCapability, GitCloneError, GitUrl, WhichCapability, WhichError}; + +fn do_repo_clone(url: GitUrl, into: &std::path::Path) -> Result<(), GitCloneError> { + Repository::clone(url.into(), into).map_or_else( + |err: git2::Error| Err(GitCloneError(format!("{}", err))), + |_| Ok(()), + ) +} -use crate::args::{InitArgs, TargetLanguage}; -use args::{BuildArgs, Command as ConsoleCommand, CommandLineArgs}; -use package::App; +fn do_which(cmd: &str) -> Result { + which::which(cmd).map_err(|err| match err { + which::Error::CannotFindBinaryPath => WhichError::CannotFindBinaryPath, + which::Error::CannotGetCurrentDirAndPathListEmpty => { + WhichError::CannotGetCurrentDirAndPathListEmpty + } + which::Error::CannotCanonicalize => WhichError::CannotCanonicalize, + }) +} -use crate::backends::{BatchBuildResults, BuildCommandOptions, CommandSpec}; -use crate::package::{Config, ConfigFile}; -use crate::util::errors::{BuildResult, LingoError}; +fn do_clone_and_checkout( + git_url: GitUrl, + outpath: &Path, + git_tag: Option, +) -> Result, GitCloneError> { + let repo = Repository::clone(<&str>::from(git_url), outpath) + .map_err(|_| GitCloneError("clone failed".to_string()))?; + let mut git_rev = None; + + if let Some(git_lock) = git_tag { + let name = match git_lock { + GitLock::Tag(tag) => tag, + GitLock::Branch(branch) => branch, + GitLock::Rev(rev) => rev, + }; + + // TODO: this produces hard to debug output + let (object, reference) = repo + .revparse_ext(&name) + .map_err(|_| GitCloneError("cannot parse rev".to_string()))?; + repo.checkout_tree(&object, None) + .map_err(|_| GitCloneError("cannot checkout rev".to_string()))?; + + match reference { + // gref is an actual reference like branches or tags + Some(gref) => { + git_rev = gref.target().map(|v| v.to_string()); + repo.set_head(gref.name().unwrap()) + } + // this is a commit, not a reference + None => repo.set_head_detached(object.id()), + } + .map_err(|_| GitCloneError("cannot checkout rev".to_string()))?; + } -pub mod args; -pub mod backends; -pub mod package; -pub(crate) mod util; + Ok(git_rev) +} + +fn do_read_to_string(p: &Path) -> io::Result { + std::fs::read_to_string(p) +} fn main() { + print_logger::new().init().unwrap(); // parses command line arguments let args = CommandLineArgs::parse(); // Finds Lingo.toml recursively inside the parent directories. // If it exists the returned path is absolute. - let lingo_path = util::find_toml(&env::current_dir().unwrap()); + let lingo_path = liblingo::util::find_toml(&env::current_dir().unwrap()); // tries to read Lingo.toml let mut wrapped_config = lingo_path.as_ref().and_then(|path| { - ConfigFile::from(path) - .map_err(|err| println!("Error while reading Lingo.toml: {}", err)) + ConfigFile::from(path, Box::new(do_read_to_string)) + .map_err(|err| log::error!("Error while reading Lingo.toml: {}", err)) .ok() .map(|cf| cf.to_config(path.parent().unwrap())) }); @@ -39,7 +96,12 @@ fn main() { print_res(result) } - let result = execute_command(&mut wrapped_config, args.command); + let result = execute_command( + &mut wrapped_config, + args.command, + Box::new(do_which), + Box::new(do_repo_clone), + ); match result { CommandResult::Batch(res) => res.print_results(), @@ -51,7 +113,7 @@ fn print_res(result: BuildResult) { match result { Ok(_) => {} Err(errs) => { - println!("{}", errs); + log::error!("{}", errs); } } } @@ -79,9 +141,16 @@ fn validate(config: &mut Option, command: &ConsoleCommand) -> BuildResul } } -fn execute_command(config: &mut Option, command: ConsoleCommand) -> CommandResult { +fn execute_command<'a>( + config: &'a mut Option, + command: ConsoleCommand, + _which_capability: WhichCapability, + git_clone_capability: GitCloneCapability, +) -> CommandResult<'a> { match (config, command) { - (_, ConsoleCommand::Init(init_config)) => CommandResult::Single(do_init(init_config)), + (_, ConsoleCommand::Init(init_config)) => { + CommandResult::Single(do_init(init_config, &git_clone_capability)) + } (None, _) => CommandResult::Single(Err(Box::new(io::Error::new( ErrorKind::NotFound, "Error: Missing Lingo.toml file", @@ -93,7 +162,7 @@ fn execute_command(config: &mut Option, command: ConsoleCommand) -> Comm let mut res = build(&build_command_args, config); res.map(|app| { let mut command = Command::new(app.executable_path()); - util::run_and_capture(&mut command)?; + liblingo::util::run_and_capture(&mut command)?; Ok(()) }); CommandResult::Batch(res) @@ -105,12 +174,13 @@ fn execute_command(config: &mut Option, command: ConsoleCommand) -> Comm } } -fn do_init(init_config: InitArgs) -> BuildResult { +fn do_init(init_config: InitArgs, git_clone_capability: &GitCloneCapability) -> BuildResult { let initial_config = ConfigFile::new_for_init_task(&init_config)?; initial_config.write(Path::new("./Lingo.toml"))?; initial_config.setup_example( init_config.platform, init_config.language.unwrap_or(TargetLanguage::Cpp), + git_clone_capability, ) } @@ -119,7 +189,8 @@ fn build<'a>(args: &BuildArgs, config: &'a mut Config) -> BatchBuildResults<'a> CommandSpec::Build(BuildCommandOptions { profile: args.build_profile(), compile_target_code: !args.no_compile, - lfc_exec_path: util::find_lfc_exec(args).expect("TODO replace me"), + lfc_exec_path: liblingo::util::find_lfc_exec(args, Box::new(do_which)) + .expect("TODO replace me"), max_threads: args.threads, keep_going: args.keep_going, }), @@ -129,9 +200,13 @@ fn build<'a>(args: &BuildArgs, config: &'a mut Config) -> BatchBuildResults<'a> } fn run_command(task: CommandSpec, config: &mut Config, _fail_at_end: bool) -> BatchBuildResults { - //let apps = config.apps.iter().collect::>(); - //let dependencies = Vec::from_iter(config.dependencies.into_iter()); - backends::execute_command(&task, config) + let _apps = config.apps.iter().collect::>(); + liblingo::backends::execute_command( + &task, + config, + Box::new(do_which), + Box::new(do_clone_and_checkout), + ) } enum CommandResult<'a> { diff --git a/src/package/lock.rs b/src/package/lock.rs index eea5d3b..9bf4b05 100644 --- a/src/package/lock.rs +++ b/src/package/lock.rs @@ -1,5 +1,6 @@ use colored::Colorize; use serde::{Deserialize, Deserializer, Serialize, Serializer}; +use sha1dir; use versions::Versioning; use log::error; @@ -12,6 +13,8 @@ use std::fs; use std::path::{Path, PathBuf}; use std::str::FromStr; +use crate::GitCloneAndCheckoutCap; + use crate::package::management::copy_dir_all; use crate::package::{ deserialize_version, serialize_version, @@ -205,14 +208,20 @@ impl DependencyLock { } } - pub fn init(&mut self, lfc_include_folder: &Path) -> anyhow::Result<()> { + pub fn init( + &mut self, + lfc_include_folder: &Path, + git_clone_and_checkout_cap: &GitCloneAndCheckoutCap, + ) -> anyhow::Result<()> { for (_, lock) in self.dependencies.iter() { let temp = lfc_include_folder.join(&lock.name); // the Lingo.toml for this dependency doesnt exists, hence we need to fetch this package if !temp.join("Lingo.toml").exists() { let mut details = PackageDetails::try_from(&lock.source)?; - details.fetch(&temp).expect("cannot pull package"); + details + .fetch(&temp, git_clone_and_checkout_cap) + .expect("cannot pull package"); } let hash = sha1dir::checksum_current_dir(&temp, false); diff --git a/src/package/management.rs b/src/package/management.rs index feddd30..61b9c2e 100644 --- a/src/package/management.rs +++ b/src/package/management.rs @@ -2,7 +2,8 @@ use colored::Colorize; use log::error; use versions::{Requirement, Versioning}; -use git2::ErrorCode; +use crate::{GitCloneAndCheckoutCap, GitUrl}; +use sha1dir; use std::collections::HashMap; use std::fs; use std::fs::File; @@ -67,7 +68,11 @@ impl TryFrom<&PackageLockSource> for PackageDetails { impl PackageDetails { /// this function fetches the specified location and places it at the given location - pub fn fetch(&mut self, library_path: &PathBuf) -> anyhow::Result<()> { + pub fn fetch( + &mut self, + library_path: &PathBuf, + clone: &GitCloneAndCheckoutCap, + ) -> anyhow::Result<()> { match &self.mutual_exclusive { ProjectSource::Path(path_buf) => { let src = fs::canonicalize(path_buf)?; @@ -75,36 +80,12 @@ impl PackageDetails { Ok(copy_dir_all(src, dst)?) } ProjectSource::Git(git_url) => { - let repo = git2::Repository::clone(git_url.as_str(), library_path)?; - let git_lock = self.git_tag.clone().unwrap_or({ - GitLock::Branch( - repo.head() - .expect("no head in branch") - .name() - .ok_or(ErrorCode::Ambiguous) - .expect("head doesn't have a name") - .to_string(), - ) - }); - let name = match git_lock { - GitLock::Tag(tag) => tag, - GitLock::Branch(branch) => branch, - GitLock::Rev(rev) => rev, - }; - - // TODO: this produces hard to debug output - let (object, reference) = repo.revparse_ext(&name)?; - repo.checkout_tree(&object, None)?; - - Ok(match reference { - // gref is an actual reference like branches or tags - Some(gref) => { - self.git_rev = gref.target().map(|v| v.to_string()); - repo.set_head(gref.name().unwrap())? - } - // this is a commit, not a reference - None => repo.set_head_detached(object.id())?, - }) + self.git_rev = clone( + GitUrl::from(git_url.as_str()), + library_path, + self.git_tag.clone(), + )?; + Ok(()) } _ => Ok(()), } @@ -115,6 +96,7 @@ impl DependencyManager { pub fn from_dependencies( dependencies: Vec<(String, PackageDetails)>, target_path: &Path, + git_clone_and_checkout_cap: &GitCloneAndCheckoutCap, ) -> anyhow::Result { // create library folder let library_path = target_path.join(LIBRARY_DIRECTORY); @@ -132,7 +114,8 @@ impl DependencyManager { // if a lock file is present it will load the dependencies from it and checks // integrity of the build directory - if let Ok(()) = lock.init(&target_path.join("lfc_include")) { + if let Ok(()) = lock.init(&target_path.join("lfc_include"), git_clone_and_checkout_cap) + { return Ok(DependencyManager { pulling_queue: vec![], lock, @@ -144,7 +127,11 @@ impl DependencyManager { manager = DependencyManager::default(); // starts recursively pulling dependencies - let root_nodes = manager.pull(dependencies.clone(), target_path)?; + let root_nodes = manager.pull( + dependencies.clone(), + target_path, + git_clone_and_checkout_cap, + )?; // flattens the dependency tree and makes the package selection let selection = DependencyManager::flatten(root_nodes.clone())?; @@ -175,6 +162,7 @@ impl DependencyManager { &mut self, mut dependencies: Vec<(String, PackageDetails)>, root_path: &Path, + git_clone_and_checkout_cap: &GitCloneAndCheckoutCap, ) -> anyhow::Result> { let mut sub_dependencies = vec![]; self.pulling_queue.append(&mut dependencies); @@ -189,6 +177,7 @@ impl DependencyManager { &package_name, package_details, &sub_dependency_path, + git_clone_and_checkout_cap, ) { Ok(value) => value, Err(e) => { @@ -211,6 +200,7 @@ impl DependencyManager { name: &str, mut package: PackageDetails, base_path: &Path, + git_clone_and_checkout_cap: &GitCloneAndCheckoutCap, ) -> anyhow::Result { // creating the directory where the library will be housed let library_path = base_path; //.join("libs"); @@ -226,7 +216,7 @@ impl DependencyManager { fs::create_dir_all(&temporary_path)?; // cloning the specified package - package.fetch(&temporary_path)?; + package.fetch(&temporary_path, git_clone_and_checkout_cap)?; let hash = sha1dir::checksum_current_dir(&temporary_path, false); let include_path = library_path.join(hash.to_string()); diff --git a/src/package/mod.rs b/src/package/mod.rs index 1a5e494..a138206 100644 --- a/src/package/mod.rs +++ b/src/package/mod.rs @@ -4,16 +4,14 @@ pub mod tree; pub mod target_properties; -use git2::Repository; use serde::de::{Error, Visitor}; use serde::{Deserializer, Serializer}; use serde_derive::{Deserialize, Serialize}; use std::collections::HashMap; use tempfile::tempdir; use versions::Versioning; -use which::which; -use std::fs::{read_to_string, remove_dir_all, remove_file, write}; +use std::fs::{remove_dir_all, remove_file, write}; use std::io::ErrorKind; use std::path::{Path, PathBuf}; use std::str::FromStr; @@ -35,6 +33,7 @@ use crate::util::{ analyzer, copy_recursively, errors::{BuildResult, LingoError}, }; +use crate::{FsReadCapability, GitCloneCapability, GitUrl, WhichCapability}; /// place where are the build artifacts will be dropped pub const OUTPUT_DIRECTORY: &str = "build"; @@ -246,7 +245,7 @@ impl LibraryFile { } impl App { - pub fn build_system(&self) -> BuildSystem { + pub fn build_system(&self, which: &WhichCapability) -> BuildSystem { match self.target { TargetLanguage::C => CMake, TargetLanguage::Cpp => CMake, @@ -378,10 +377,15 @@ impl ConfigFile { write(path, toml_string) } - pub fn from(path: &Path) -> io::Result { - read_to_string(path).and_then(|contents| { - toml::from_str(&contents) - .map_err(|e| io::Error::new(ErrorKind::InvalidData, format!("{}", e))) + pub fn from(path: &Path, fsr: FsReadCapability) -> io::Result { + let contents = fsr(path); + contents.and_then(|contents| { + toml::from_str(&contents).map_err(|e| { + io::Error::new( + ErrorKind::InvalidData, + format!("failed to convert string to toml: {}", e), + ) + }) }) } @@ -400,10 +404,10 @@ impl ConfigFile { Ok(()) } - fn setup_template_repo(&self, url: &str) -> BuildResult { + fn setup_template_repo(&self, url: &str, clone: &GitCloneCapability) -> BuildResult { let dir = tempdir()?; let tmp_path = dir.path(); - Repository::clone(url, tmp_path)?; + clone(GitUrl::from(url), tmp_path)?; // Copy the cloned template repo into the project directory copy_recursively(tmp_path, Path::new("."))?; // Remove temporary folder @@ -412,9 +416,9 @@ impl ConfigFile { } // Sets up a LF project with Zephyr as the target platform. - fn setup_zephyr(&self) -> BuildResult { + fn setup_zephyr(&self, clone: &GitCloneCapability) -> BuildResult { let url = "https://github.com/lf-lang/lf-west-template"; - self.setup_template_repo(url)?; + self.setup_template_repo(url, clone)?; remove_file(".gitignore")?; remove_dir_all(Path::new(".git"))?; Ok(()) @@ -422,10 +426,10 @@ impl ConfigFile { // Sets up a LF project with RP2040 MCU as the target platform. // Initializes a repo using the lf-pico-template - fn setup_rp2040(&self) -> BuildResult { + fn setup_rp2040(&self, clone: &GitCloneCapability) -> BuildResult { let url = "https://github.com/lf-lang/lf-pico-template"; // leave git artifacts - self.setup_template_repo(url)?; + self.setup_template_repo(url, clone)?; Ok(()) } @@ -433,12 +437,13 @@ impl ConfigFile { &self, platform: Platform, target_language: TargetLanguage, + git_clone_capability: &GitCloneCapability, ) -> BuildResult { if is_valid_location_for_project(Path::new(".")) { match platform { Platform::Native => self.setup_native(target_language), - Platform::Zephyr => self.setup_zephyr(), - Platform::RP2040 => self.setup_rp2040(), + Platform::Zephyr => self.setup_zephyr(git_clone_capability), + Platform::RP2040 => self.setup_rp2040(git_clone_capability), } } else { Err(Box::new(LingoError::InvalidProjectLocation( diff --git a/src/util/analyzer.rs b/src/util/analyzer.rs index 6f82433..07fe106 100644 --- a/src/util/analyzer.rs +++ b/src/util/analyzer.rs @@ -7,7 +7,7 @@ use regex::Regex; use crate::args::TargetLanguage; -lazy_static! { +lazy_static! { // FIXME: ad hoc parsing using regexes should be forbidden static ref TARGET_RE: Regex = Regex::new(r"\btarget\s+(\w+)\s*[{;]").unwrap(); } lazy_static! { @@ -22,10 +22,10 @@ fn search_inside_file(path: &Path) -> io::Result> { let mut target: TargetLanguage = DEFAULT_TARGET; for line in content.split('\n') { - if let Some(captures) = MAIN_REACTOR_RE.captures(line) { + if let Some(captures) = TARGET_RE.captures(line) { target = TargetLanguage::from_str(captures.get(1).unwrap().as_str(), true).unwrap(); } - if let Some(captures) = TARGET_RE.captures(line) { + if let Some(captures) = MAIN_REACTOR_RE.captures(line) { let name = captures.get(1).unwrap().as_str().into(); return Ok(Some(MainReactorSpec { name, diff --git a/src/util/command_line.rs b/src/util/command_line.rs index fde75ed..447d55b 100644 --- a/src/util/command_line.rs +++ b/src/util/command_line.rs @@ -38,7 +38,7 @@ pub fn run_and_capture(command: &mut Command) -> io::Result<(ExitStatus, Vec // These expects should be guaranteed to be ok because we used piped(). let mut child_stdout = child.stdout.take().expect("logic error getting stdout"); let mut child_stderr = child.stderr.take().expect("logic error getting stderr"); - println!("Running {:?}", command); + log::info!("Running {:?}", command); thread::scope(|s| { let stdout_thread = s.spawn(|_| -> io::Result> { @@ -72,7 +72,7 @@ pub fn run_and_capture(command: &mut Command) -> io::Result<(ExitStatus, Vec pub fn execute_command_to_build_result(mut command: Command) -> BuildResult { match run_and_capture(&mut command) { Err(e) => { - eprintln!("error occured while executing commandline: {:?}", &e); + log::error!("error occured while executing commandline: {:?}", &e); Err(Box::new(e)) } Ok((status, _, _)) if !status.success() => { diff --git a/src/util/mod.rs b/src/util/mod.rs index d96a9c2..ac4782f 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -1,13 +1,12 @@ -use which::which; - -use std::path::{Path, PathBuf}; -use std::{fs, io}; - pub mod analyzer; mod command_line; pub mod errors; pub use command_line::*; +use std::path::{Path, PathBuf}; +use std::{fs, io}; + +use crate::WhichCapability; /// finds toml file recurisvely pub fn find_toml(input_path: &Path) -> Option { @@ -57,14 +56,17 @@ pub fn delete_subdirs(path_root: &Path, subdirs: &[&str]) -> io::Result<()> { } pub fn default_build_clean(out_dir: &Path) -> io::Result<()> { - println!("removing build artifacts in {:?}", out_dir); + log::info!("removing build artifacts in {:?}", out_dir); delete_subdirs( out_dir, &["bin", "include", "src-gen", "lib64", "share", "build"], ) } -pub fn find_lfc_exec(args: &crate::BuildArgs) -> Result { +pub fn find_lfc_exec( + args: &crate::args::BuildArgs, + which: WhichCapability, +) -> Result { if let Some(lfc) = &args.lfc { if lfc.exists() { return Ok(lfc.clone());