Implemented initial WIP mod resolver

This commit is contained in:
Warren Hood 2024-08-17 17:11:04 +02:00
parent 3a91def282
commit 09e3c066b6
9 changed files with 632 additions and 348 deletions

644
Cargo.lock generated
View file

@ -17,30 +17,6 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "aho-corasick"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
dependencies = [
"memchr",
]
[[package]]
name = "android-tzdata"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
[[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.15"
@ -90,6 +66,12 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "atomic-waker"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
[[package]]
name = "autocfg"
version = "1.3.0"
@ -117,18 +99,24 @@ version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
[[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 = "bytes"
version = "1.7.1"
@ -137,9 +125,9 @@ checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50"
[[package]]
name = "cc"
version = "1.1.11"
version = "1.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fb8dd288a69fc53a1996d7ecfbf4a20d59065bff137ce7e56bbd620de191189"
checksum = "72db2f7947ecee9b03b510377e8bb9077afa27176fdbff55c51027e976fdcc48"
dependencies = [
"shlex",
]
@ -150,21 +138,6 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chrono"
version = "0.4.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
dependencies = [
"android-tzdata",
"iana-time-zone",
"js-sys",
"num-traits",
"serde",
"wasm-bindgen",
"windows-targets 0.52.6",
]
[[package]]
name = "clap"
version = "4.5.15"
@ -211,12 +184,31 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0"
[[package]]
name = "core-foundation"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "core-foundation-sys"
version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
[[package]]
name = "encoding_rs"
version = "0.8.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59"
dependencies = [
"cfg-if",
]
[[package]]
name = "equivalent"
version = "1.0.1"
@ -224,27 +216,42 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "ferinth"
version = "2.11.0"
name = "errno"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e02ddb7dbc6a683bf0e53786279a3a621977609df68eedb3311d05a8de807eb"
checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
dependencies = [
"chrono",
"lazy-regex",
"once_cell",
"reqwest",
"serde",
"serde_json",
"thiserror",
"url",
"libc",
"windows-sys 0.52.0",
]
[[package]]
name = "fastrand"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a"
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "foreign-types"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
dependencies = [
"foreign-types-shared",
]
[[package]]
name = "foreign-types-shared"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
[[package]]
name = "form_urlencoded"
version = "1.2.1"
@ -269,6 +276,12 @@ version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
[[package]]
name = "futures-sink"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"
[[package]]
name = "futures-task"
version = "0.3.30"
@ -304,6 +317,25 @@ version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd"
[[package]]
name = "h2"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab"
dependencies = [
"atomic-waker",
"bytes",
"fnv",
"futures-core",
"futures-sink",
"http",
"indexmap",
"slab",
"tokio",
"tokio-util",
"tracing",
]
[[package]]
name = "hashbrown"
version = "0.14.5"
@ -371,6 +403,7 @@ dependencies = [
"bytes",
"futures-channel",
"futures-util",
"h2",
"http",
"http-body",
"httparse",
@ -396,7 +429,22 @@ dependencies = [
"tokio",
"tokio-rustls",
"tower-service",
"webpki-roots",
]
[[package]]
name = "hyper-tls"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0"
dependencies = [
"bytes",
"http-body-util",
"hyper",
"hyper-util",
"native-tls",
"tokio",
"tokio-native-tls",
"tower-service",
]
[[package]]
@ -419,29 +467,6 @@ dependencies = [
"tracing",
]
[[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"
@ -489,29 +514,6 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "lazy-regex"
version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "576c8060ecfdf2e56995cf3274b4f2d71fa5e4fa3607c1c0b63c10180ee58741"
dependencies = [
"lazy-regex-proc_macros",
"once_cell",
"regex",
]
[[package]]
name = "lazy-regex-proc_macros"
version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9efb9e65d4503df81c615dc33ff07042a9408ac7f26b45abee25566f7fbfd12c"
dependencies = [
"proc-macro2",
"quote",
"regex",
"syn",
]
[[package]]
name = "lhash"
version = "1.1.0"
@ -520,9 +522,25 @@ checksum = "744a4c881f502e98c2241d2e5f50040ac73b30194d64452bb6260393b53f0dc9"
[[package]]
name = "libc"
version = "0.2.155"
version = "0.2.156"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
checksum = "a5f43f184355eefb8d17fc948dbecf6c13be3c141f20d834ae842193a448c72a"
[[package]]
name = "linux-raw-sys"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
[[package]]
name = "lock_api"
version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
dependencies = [
"autocfg",
"scopeguard",
]
[[package]]
name = "log"
@ -535,8 +553,9 @@ name = "mcmpmgr"
version = "0.1.0"
dependencies = [
"clap",
"ferinth",
"lhash",
"reqwest",
"semver",
"serde",
"tokio",
"toml",
@ -576,12 +595,20 @@ dependencies = [
]
[[package]]
name = "num-traits"
version = "0.2.19"
name = "native-tls"
version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466"
dependencies = [
"autocfg",
"libc",
"log",
"openssl",
"openssl-probe",
"openssl-sys",
"schannel",
"security-framework",
"security-framework-sys",
"tempfile",
]
[[package]]
@ -599,6 +626,73 @@ version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]]
name = "openssl"
version = "0.10.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1"
dependencies = [
"bitflags 2.6.0",
"cfg-if",
"foreign-types",
"libc",
"once_cell",
"openssl-macros",
"openssl-sys",
]
[[package]]
name = "openssl-macros"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "openssl-probe"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
[[package]]
name = "openssl-sys"
version = "0.9.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6"
dependencies = [
"cc",
"libc",
"pkg-config",
"vcpkg",
]
[[package]]
name = "parking_lot"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
dependencies = [
"lock_api",
"parking_lot_core",
]
[[package]]
name = "parking_lot_core"
version = "0.9.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"smallvec",
"windows-targets 0.52.6",
]
[[package]]
name = "percent-encoding"
version = "2.3.1"
@ -638,13 +732,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "ppv-lite86"
version = "0.2.20"
name = "pkg-config"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
dependencies = [
"zerocopy",
]
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
[[package]]
name = "proc-macro2"
@ -655,54 +746,6 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "quinn"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b22d8e7369034b9a7132bc2008cac12f2013c8132b45e0554e6e20e2617f2156"
dependencies = [
"bytes",
"pin-project-lite",
"quinn-proto",
"quinn-udp",
"rustc-hash",
"rustls",
"socket2",
"thiserror",
"tokio",
"tracing",
]
[[package]]
name = "quinn-proto"
version = "0.11.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba92fb39ec7ad06ca2582c0ca834dfeadcaf06ddfc8e635c80aa7e1c05315fdd"
dependencies = [
"bytes",
"rand",
"ring",
"rustc-hash",
"rustls",
"slab",
"thiserror",
"tinyvec",
"tracing",
]
[[package]]
name = "quinn-udp"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8bffec3605b73c6f1754535084a85229fa8a30f86014e6c81aeec4abb68b0285"
dependencies = [
"libc",
"once_cell",
"socket2",
"tracing",
"windows-sys 0.52.0",
]
[[package]]
name = "quote"
version = "1.0.36"
@ -713,64 +756,14 @@ dependencies = [
]
[[package]]
name = "rand"
version = "0.8.5"
name = "redox_syscall"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
"bitflags 2.6.0",
]
[[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 = "regex"
version = "1.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
[[package]]
name = "reqwest"
version = "0.12.5"
@ -779,37 +772,38 @@ checksum = "c7d6d2a27d57148378eb5e111173f4276ad26340ecc5c49a4a2152167a2d6a37"
dependencies = [
"base64",
"bytes",
"encoding_rs",
"futures-core",
"futures-util",
"h2",
"http",
"http-body",
"http-body-util",
"hyper",
"hyper-rustls",
"hyper-tls",
"hyper-util",
"ipnet",
"js-sys",
"log",
"mime",
"native-tls",
"once_cell",
"percent-encoding",
"pin-project-lite",
"quinn",
"rustls",
"rustls-pemfile",
"rustls-pki-types",
"serde",
"serde_json",
"serde_urlencoded",
"sync_wrapper",
"system-configuration",
"tokio",
"tokio-rustls",
"tokio-native-tls",
"tower-service",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"webpki-roots",
"winreg",
]
@ -835,10 +829,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
[[package]]
name = "rustc-hash"
version = "2.0.0"
name = "rustix"
version = "0.38.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152"
checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f"
dependencies = [
"bitflags 2.6.0",
"errno",
"libc",
"linux-raw-sys",
"windows-sys 0.52.0",
]
[[package]]
name = "rustls"
@ -847,7 +848,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c58f8c84392efc0a126acce10fa59ff7b3d2ac06ab451a33f2741989b806b044"
dependencies = [
"once_cell",
"ring",
"rustls-pki-types",
"rustls-webpki",
"subtle",
@ -887,6 +887,53 @@ version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
[[package]]
name = "schannel"
version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534"
dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "security-framework"
version = "2.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
dependencies = [
"bitflags 2.6.0",
"core-foundation",
"core-foundation-sys",
"libc",
"security-framework-sys",
]
[[package]]
name = "security-framework-sys"
version = "2.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "semver"
version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
dependencies = [
"serde",
]
[[package]]
name = "serde"
version = "1.0.207"
@ -909,9 +956,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.124"
version = "1.0.125"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "66ad62847a56b3dba58cc891acd13884b9c61138d330c0d7b6181713d4fce38d"
checksum = "83c8e735a073ccf5be70aa8066aa984eaf2fa000db6c8d0100ae605b366d31ed"
dependencies = [
"itoa",
"memchr",
@ -946,6 +993,15 @@ version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "signal-hook-registry"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1"
dependencies = [
"libc",
]
[[package]]
name = "slab"
version = "0.4.9"
@ -1007,23 +1063,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394"
[[package]]
name = "thiserror"
version = "1.0.63"
name = "system-configuration"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724"
checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7"
dependencies = [
"thiserror-impl",
"bitflags 1.3.2",
"core-foundation",
"system-configuration-sys",
]
[[package]]
name = "thiserror-impl"
version = "1.0.63"
name = "system-configuration-sys"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9"
dependencies = [
"proc-macro2",
"quote",
"syn",
"core-foundation-sys",
"libc",
]
[[package]]
name = "tempfile"
version = "3.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64"
dependencies = [
"cfg-if",
"fastrand",
"once_cell",
"rustix",
"windows-sys 0.59.0",
]
[[package]]
@ -1051,11 +1121,35 @@ dependencies = [
"bytes",
"libc",
"mio",
"parking_lot",
"pin-project-lite",
"signal-hook-registry",
"socket2",
"tokio-macros",
"windows-sys 0.52.0",
]
[[package]]
name = "tokio-macros"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tokio-native-tls"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
dependencies = [
"native-tls",
"tokio",
]
[[package]]
name = "tokio-rustls"
version = "0.26.0"
@ -1067,6 +1161,19 @@ dependencies = [
"tokio",
]
[[package]]
name = "tokio-util"
version = "0.7.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1"
dependencies = [
"bytes",
"futures-core",
"futures-sink",
"pin-project-lite",
"tokio",
]
[[package]]
name = "toml"
version = "0.8.19"
@ -1189,7 +1296,6 @@ dependencies = [
"form_urlencoded",
"idna",
"percent-encoding",
"serde",
]
[[package]]
@ -1198,6 +1304,12 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "vcpkg"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "want"
version = "0.3.1"
@ -1290,24 +1402,6 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "webpki-roots"
version = "0.26.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd7c23921eeb1713a4e851530e9b9756e4fb0e89978582942612524cf09f01cd"
dependencies = [
"rustls-pki-types",
]
[[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.6",
]
[[package]]
name = "windows-sys"
version = "0.48.0"
@ -1326,6 +1420,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"
@ -1466,27 +1569,6 @@ dependencies = [
"windows-sys 0.48.0",
]
[[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",
]
[[package]]
name = "zeroize"
version = "1.8.1"

View file

@ -5,8 +5,9 @@ edition = "2021"
[dependencies]
clap = { version = "4.5.15", features = ["derive"] }
ferinth = "2.11.0"
lhash = { version = "1.1.0", features = ["sha1", "sha512"] }
reqwest = { version = "0.12.5", features = ["json"] }
semver = { version = "1.0.23", features = ["serde"] }
serde = { version = "1.0.207", features = ["derive"] }
tokio = "1.39.2"
tokio = { version = "1.39.2", features = ["full"] }
toml = "0.8.19"

View file

@ -1,11 +1,12 @@
mod modpack;
mod mod_meta;
mod modpack;
mod providers;
mod resolver;
use clap::{Parser, Subcommand};
use mod_meta::{ModMeta, ModProvider};
use modpack::ModpackMeta;
use std::{error::Error, path::PathBuf};
use std::{borrow::BorrowMut, error::Error, path::PathBuf};
/// A Minecraft Modpack Manager
#[derive(Parser)]
@ -61,7 +62,8 @@ enum Commands {
},
}
fn main() -> Result<(), Box<dyn Error>> {
#[tokio::main(flavor = "multi_thread")]
async fn main() -> Result<(), Box<dyn Error>> {
let cli = Cli::parse();
if let Some(command) = cli.command {
@ -123,6 +125,7 @@ fn main() -> Result<(), Box<dyn Error>> {
url,
} => {
let mut modpack_meta = ModpackMeta::load_from_current_directory()?;
let old_modpack_meta = modpack_meta.clone();
let mut mod_meta = ModMeta::new(&name)?;
if let Some(url) = url {
@ -134,9 +137,29 @@ fn main() -> Result<(), Box<dyn Error>> {
modpack_meta = modpack_meta.add_mod(&mod_meta);
modpack_meta.save_current_dir_project()?;
let mut modpack_lock = resolver::PinnedPackMeta::load_from_current_directory()?;
modpack_lock.pin_mod(&mod_meta);
modpack_lock.save_current_dir_lock()?;
let revert_modpack_meta = |e| -> ! {
let revert_result = old_modpack_meta.save_current_dir_project();
if let Err(result) = revert_result {
panic!("Failed to revert modpack meta: {}", result);
}
panic!("Reverted modpack meta:\n{}", e);
};
match resolver::PinnedPackMeta::load_from_current_directory().await {
Ok(mut modpack_lock) => {
let pin_result = modpack_lock.pin_mod(&mod_meta, &modpack_meta).await;
if let Err(e) = pin_result {
revert_modpack_meta(e);
}
if let Err(e) = modpack_lock.save_current_dir_lock() {
revert_modpack_meta(e);
}
}
Err(e) => {
revert_modpack_meta(e);
}
};
}
}
};

View file

@ -2,7 +2,7 @@ use std::{borrow::BorrowMut, error::Error};
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Hash, Clone)]
pub enum ModProvider {
/// Get mods from CurseForge
CurseForge,
@ -29,7 +29,7 @@ impl std::str::FromStr for ModProvider {
pub struct ModMeta {
pub name: String,
pub version: String,
providers: Option<Vec<ModProvider>>,
pub providers: Option<Vec<ModProvider>>,
download_url: Option<String>,
}

View file

@ -1,8 +1,5 @@
use std::{collections::HashMap, error::Error, path::PathBuf};
use ferinth::Ferinth;
use serde::{Deserialize, Serialize};
use crate::mod_meta::{ModMeta, ModProvider};
const MODPACK_FILENAME: &str = "modpack.toml";
@ -35,13 +32,13 @@ impl std::str::FromStr for ModLoader {
}
}
#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct ModpackMeta {
pack_name: String,
mc_version: String,
modloader: ModLoader,
pub mc_version: String,
pub modloader: ModLoader,
mods: HashMap<String, ModMeta>,
default_providers: Vec<ModProvider>,
pub default_providers: Vec<ModProvider>,
}
impl ModpackMeta {

22
src/providers/mod.rs Normal file
View file

@ -0,0 +1,22 @@
use std::path::PathBuf;
use serde::{Deserialize, Serialize};
use crate::mod_meta::ModMeta;
pub mod modrinth;
pub mod raw;
#[derive(Serialize, Deserialize)]
enum FileSource {
Download { url: String, sha1: String, sha512: String},
Local { path: PathBuf, sha1: String, sha512: String },
}
#[derive(Serialize, Deserialize)]
pub struct PinnedMod {
/// Source of the files for the mod
source: Vec<FileSource>,
/// Version of mod
version: semver::Version,
/// Pinned dependencies of a pinned mod
deps: Option<Vec<PinnedMod>>
}

144
src/providers/modrinth.rs Normal file
View file

@ -0,0 +1,144 @@
use serde::{Deserialize, Serialize};
use std::error::Error;
use super::PinnedMod;
use crate::{mod_meta::ModMeta, modpack::ModpackMeta, providers::FileSource};
pub struct Modrinth {
client: reqwest::Client,
}
#[derive(Serialize, Deserialize, Debug)]
struct VersionDeps {
dependency_type: String,
project_id: String,
file_name: Option<String>,
version_id: Option<String>,
}
#[derive(Serialize, Deserialize, Debug)]
struct VersionHashes {
sha1: String,
sha512: String,
}
#[derive(Serialize, Deserialize, Debug)]
struct VersionFiles {
// file_type: String,
filename: String,
hashes: VersionHashes,
// primary: bool,
// size: i64,
url: String,
}
#[derive(Serialize, Deserialize, Debug)]
struct ModrinthProjectVersion {
author_id: String,
date_published: String,
dependencies: Vec<VersionDeps>,
// downloads: i64,
files: Vec<VersionFiles>,
// loaders: Vec<String>,
// name: String,
// project_id: String,
version_number: semver::Version,
// version_type: String,
}
impl Modrinth {
pub fn new() -> Self {
Self {
..Default::default()
}
}
/// Resolve a list of mod candidates in order of newest to oldest
pub async fn resolve(
&self,
mod_meta: &ModMeta,
pack_meta: &ModpackMeta,
) -> Result<Vec<PinnedMod>, Box<dyn Error>> {
let mut versions = self.get_project_versions(&mod_meta.name, pack_meta).await?;
versions.sort_by_key(|v| v.version_number.clone());
versions.reverse();
if mod_meta.version == "*" {
return Ok(versions
.into_iter()
.map(|v| PinnedMod {
source: v
.files
.into_iter()
.map(|f| FileSource::Download {
url: f.url,
sha1: f.hashes.sha1,
sha512: f.hashes.sha512,
})
.collect(),
version: v.version_number,
deps: None, // TODO: Implement automagic transitive dep installation and pinning
})
.collect());
}
// TODO: Implement more general version constraints
let expected_version = semver::Version::parse(&mod_meta.version)?;
for v in versions.into_iter() {
if v.version_number == expected_version {
return Ok(vec![PinnedMod {
source: v
.files
.into_iter()
.map(|f| FileSource::Download {
url: f.url,
sha1: f.hashes.sha1,
sha512: f.hashes.sha512,
})
.collect(),
version: v.version_number,
deps: None,
}]);
}
}
Err(format!(
"Couldn't find a version for mod '{}' that satisfies the version constraint `{}`",
mod_meta.name, mod_meta.version
)
.into())
}
async fn get_project_versions(
&self,
mod_id: &str,
pack_meta: &ModpackMeta,
) -> Result<Vec<ModrinthProjectVersion>, Box<dyn Error>> {
let project_Versions: Vec<ModrinthProjectVersion> = self
.client
.get(format!(
"https://api.modrinth.com/v2/project/{mod_id}/version"
))
.query(&[
(
"loaders",
format!("[\"{}\"]", pack_meta.modloader.to_string().to_lowercase()),
),
("game_versions", format!("[\"{}\"]", pack_meta.mc_version)),
])
.send()
.await?
.json()
.await?;
Ok(project_Versions)
}
}
impl Default for Modrinth {
fn default() -> Self {
Self {
client: Default::default(),
}
}
}

0
src/providers/raw.rs Normal file
View file

View file

@ -1,68 +1,81 @@
use serde::{Deserialize, Serialize};
use std::{collections::HashMap, error::Error, path::PathBuf};
use std::{
borrow::Borrow,
collections::{HashMap, HashSet},
error::Error,
path::PathBuf,
};
use crate::{mod_meta::ModMeta, modpack::ModpackMeta};
use crate::{
mod_meta::{ModMeta, ModProvider},
modpack::ModpackMeta,
providers::{modrinth::Modrinth, PinnedMod},
};
const MODPACK_LOCK_FILENAME: &str = "modpack.lock";
#[derive(Serialize, Deserialize)]
enum FileSource {
Download { url: String },
Local { path: PathBuf },
}
#[derive(Serialize, Deserialize)]
struct PinnedMod {
/// Source of the file
source: FileSource,
/// SHA1 Hash
sha1: String,
/// SHA512 Hash
sha512: String,
/// Version of mod
version: String,
}
impl PinnedMod {
pub fn resolve_mod(mod_metadata: &ModMeta) -> Self {
// TODO: Actually implement this
Self {
source: FileSource::Download {
url: format!("https://fake.url/mods/{}", mod_metadata.name),
},
sha1: "FakeSha1".into(),
sha512: "FakeSha512".into(),
version: if mod_metadata.version == "*" {
"1.0.0-fake-latest-version".into()
} else {
mod_metadata.version.clone()
},
}
}
}
#[derive(Serialize, Deserialize)]
pub struct PinnedPackMeta {
mods: HashMap<String, PinnedMod>,
#[serde(skip_serializing, skip_deserializing)]
modrinth: Modrinth,
}
impl PinnedPackMeta {
pub fn new() -> Self {
Self {
mods: Default::default(),
modrinth: Modrinth::new(),
}
}
pub fn pin_mod(&mut self, mod_metadata: &ModMeta) -> &mut Self {
let pinned_mod = PinnedMod::resolve_mod(mod_metadata);
self.mods.insert(mod_metadata.name.clone(), pinned_mod);
self
pub async fn pin_mod(
&mut self,
mod_metadata: &ModMeta,
pack_metadata: &ModpackMeta,
) -> Result<(), Box<dyn Error>> {
let mod_providers = if let Some(mod_providers) = &mod_metadata.providers {
mod_providers
} else {
&vec![]
};
let mut checked_providers: HashSet<ModProvider> = HashSet::new();
for mod_provider in mod_providers
.iter()
.chain(pack_metadata.default_providers.iter())
{
if checked_providers.contains(&mod_provider) {
// No need to repeat a check for a provider if we have already checked it
continue;
}
checked_providers.insert(mod_provider.clone());
match mod_provider {
crate::mod_meta::ModProvider::CurseForge => unimplemented!(),
crate::mod_meta::ModProvider::Modrinth => {
let pinned_mods = self.modrinth.resolve(&mod_metadata, pack_metadata).await;
if let Ok(pinned_mods) = pinned_mods {
pinned_mods.into_iter().for_each(|m| {
self.mods.insert(mod_metadata.name.clone(), m);
});
} else if let Err(e) = pinned_mods {
return Err(format!(
"Failed to resolve mod '{}' (provider={:#?}) with constraint {}: {}",
mod_metadata.name, mod_provider, mod_metadata.version, e
)
.into());
}
}
crate::mod_meta::ModProvider::Raw => unimplemented!(),
};
}
Ok(())
}
pub fn init(&mut self, modpack_meta: &ModpackMeta) {
modpack_meta.iter_mods().for_each(|m| {
self.pin_mod(m);
});
pub async fn init(&mut self, modpack_meta: &ModpackMeta) -> Result<(), Box<dyn Error>> {
for mod_meta in modpack_meta.iter_mods() {
self.pin_mod(mod_meta, modpack_meta).await?;
}
Ok(())
}
pub fn save_to_file(&self, path: &PathBuf) -> Result<(), Box<dyn Error>> {
@ -81,18 +94,20 @@ impl PinnedPackMeta {
Ok(())
}
pub fn load_from_directory(directory: &PathBuf) -> Result<Self, Box<dyn Error>> {
pub async fn load_from_directory(directory: &PathBuf) -> Result<Self, Box<dyn Error>> {
let modpack_lock_file_path = directory.clone().join(PathBuf::from(MODPACK_LOCK_FILENAME));
if !modpack_lock_file_path.exists() {
let mut new_modpack_lock = Self::new();
new_modpack_lock.init(&ModpackMeta::load_from_directory(directory)?);
new_modpack_lock
.init(&ModpackMeta::load_from_directory(directory)?)
.await?;
return Ok(new_modpack_lock);
};
let modpack_lock_contents = std::fs::read_to_string(modpack_lock_file_path)?;
Ok(toml::from_str(&modpack_lock_contents)?)
}
pub fn load_from_current_directory() -> Result<Self, Box<dyn Error>> {
Self::load_from_directory(&std::env::current_dir()?)
pub async fn load_from_current_directory() -> Result<Self, Box<dyn Error>> {
Self::load_from_directory(&std::env::current_dir()?).await
}
}