Upgrade to Rust 2021
- Fix lints - Formatting pass - Add Cargo.lock Use anyhow to improve error handling Fix errors during directory removal in Windows Update dependencies Switch linux build to musl Switch to musl Set version to 0.4.0 Allow using uid instead of mtime Remove name duplication with runner map Fixing typo
This commit is contained in:
parent
99a6ee6ea2
commit
d9aeb582a2
4
.gitignore
vendored
4
.gitignore
vendored
@ -2,10 +2,6 @@
|
|||||||
# will have compiled files and executables
|
# will have compiled files and executables
|
||||||
/target/
|
/target/
|
||||||
|
|
||||||
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
|
|
||||||
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
|
|
||||||
Cargo.lock
|
|
||||||
|
|
||||||
# These are backup files generated by rustfmt
|
# These are backup files generated by rustfmt
|
||||||
**/*.rs.bk
|
**/*.rs.bk
|
||||||
|
|
||||||
|
741
Cargo.lock
generated
Normal file
741
Cargo.lock
generated
Normal file
@ -0,0 +1,741 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "adler"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anyhow"
|
||||||
|
version = "1.0.51"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8b26702f315f53b6071259e15dd9d64528213b44d61de1ec926eca7715d62203"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "atty"
|
||||||
|
version = "0.2.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||||
|
dependencies = [
|
||||||
|
"hermit-abi",
|
||||||
|
"libc",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "autocfg"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bincode"
|
||||||
|
version = "1.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "1.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap"
|
||||||
|
version = "4.0.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8e67816e006b17427c9b4386915109b494fec2d929c63e3bd3561234cbf1bf1e"
|
||||||
|
dependencies = [
|
||||||
|
"atty",
|
||||||
|
"bitflags",
|
||||||
|
"clap_derive",
|
||||||
|
"clap_lex",
|
||||||
|
"once_cell",
|
||||||
|
"strsim",
|
||||||
|
"termcolor",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_derive"
|
||||||
|
version = "4.0.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "16a1b0f6422af32d5da0c58e2703320f379216ee70198241c84173a8c5ac28f3"
|
||||||
|
dependencies = [
|
||||||
|
"heck",
|
||||||
|
"proc-macro-error",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_lex"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8"
|
||||||
|
dependencies = [
|
||||||
|
"os_str_bytes",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "colored"
|
||||||
|
version = "2.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd"
|
||||||
|
dependencies = [
|
||||||
|
"atty",
|
||||||
|
"lazy_static",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crc32fast"
|
||||||
|
version = "1.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "738c290dfaea84fc1ca15ad9c168d083b05a714e1efddd8edaab678dc28d2836"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-channel"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-deque"
|
||||||
|
version = "0.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"crossbeam-epoch",
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-epoch"
|
||||||
|
version = "0.9.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"crossbeam-utils",
|
||||||
|
"lazy_static",
|
||||||
|
"memoffset",
|
||||||
|
"scopeguard",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-utils"
|
||||||
|
version = "0.8.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"lazy_static",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dirs"
|
||||||
|
version = "4.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059"
|
||||||
|
dependencies = [
|
||||||
|
"dirs-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dirs-sys"
|
||||||
|
version = "0.3.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"redox_users",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "either"
|
||||||
|
version = "1.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "filetime"
|
||||||
|
version = "0.2.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "975ccf83d8d9d0d84682850a38c8169027be83368805971cc4f238c2b245bc98"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"redox_syscall",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "flate2"
|
||||||
|
version = "1.0.22"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"crc32fast",
|
||||||
|
"libc",
|
||||||
|
"miniz_oxide",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fuchsia-cprng"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "getrandom"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"wasi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heck"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hermit-abi"
|
||||||
|
version = "0.1.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc"
|
||||||
|
|
||||||
|
[[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.109"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f98a04dce437184842841303488f70d0188c5f51437d2a834dc097eafa909a01"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "log"
|
||||||
|
version = "0.4.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memmem"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a64a92489e2744ce060c349162be1c5f33c6969234104dbd99ddb5feb08b8c15"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memoffset"
|
||||||
|
version = "0.6.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "miniz_oxide"
|
||||||
|
version = "0.4.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b"
|
||||||
|
dependencies = [
|
||||||
|
"adler",
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num_cpus"
|
||||||
|
version = "1.13.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
|
||||||
|
dependencies = [
|
||||||
|
"hermit-abi",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num_threads"
|
||||||
|
version = "0.1.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "once_cell"
|
||||||
|
version = "1.16.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "os_str_bytes"
|
||||||
|
version = "6.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3baf96e39c5359d2eb0dd6ccb42c62b91d9678aa68160d261b9e0ccbf9e9dea9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro-error"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro-error-attr",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro-error-attr"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.47"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.21"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand"
|
||||||
|
version = "0.4.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293"
|
||||||
|
dependencies = [
|
||||||
|
"fuchsia-cprng",
|
||||||
|
"libc",
|
||||||
|
"rand_core 0.3.1",
|
||||||
|
"rdrand",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
|
||||||
|
dependencies = [
|
||||||
|
"rand_core 0.4.2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rayon"
|
||||||
|
version = "1.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"crossbeam-deque",
|
||||||
|
"either",
|
||||||
|
"rayon-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rayon-core"
|
||||||
|
version = "1.9.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-channel",
|
||||||
|
"crossbeam-deque",
|
||||||
|
"crossbeam-utils",
|
||||||
|
"lazy_static",
|
||||||
|
"num_cpus",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rdrand"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
|
||||||
|
dependencies = [
|
||||||
|
"rand_core 0.3.1",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "redox_syscall"
|
||||||
|
version = "0.2.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "redox_users"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom",
|
||||||
|
"redox_syscall",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "remove_dir_all"
|
||||||
|
version = "0.5.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
|
||||||
|
dependencies = [
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "remove_dir_all"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "882f368737489ea543bc5c340e6f3d34a28c39980bd9a979e47322b26f60ac40"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"log",
|
||||||
|
"num_cpus",
|
||||||
|
"rayon",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scopeguard"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "1.0.147"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965"
|
||||||
|
dependencies = [
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_derive"
|
||||||
|
version = "1.0.147"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "simple_logger"
|
||||||
|
version = "4.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e190a521c2044948158666916d9e872cbb9984f755e9bb3b5b75a836205affcd"
|
||||||
|
dependencies = [
|
||||||
|
"atty",
|
||||||
|
"colored",
|
||||||
|
"log",
|
||||||
|
"time",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strsim"
|
||||||
|
version = "0.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "1.0.103"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tar"
|
||||||
|
version = "0.4.37"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d6f5515d3add52e0bbdcad7b83c388bb36ba7b754dda3b5f5bc2d38640cdba5c"
|
||||||
|
dependencies = [
|
||||||
|
"filetime",
|
||||||
|
"libc",
|
||||||
|
"xattr",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tempdir"
|
||||||
|
version = "0.3.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8"
|
||||||
|
dependencies = [
|
||||||
|
"rand",
|
||||||
|
"remove_dir_all 0.5.3",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "termcolor"
|
||||||
|
version = "1.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-util",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time"
|
||||||
|
version = "0.3.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376"
|
||||||
|
dependencies = [
|
||||||
|
"itoa",
|
||||||
|
"libc",
|
||||||
|
"num_threads",
|
||||||
|
"serde",
|
||||||
|
"time-core",
|
||||||
|
"time-macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time-core"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time-macros"
|
||||||
|
version = "0.2.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2"
|
||||||
|
dependencies = [
|
||||||
|
"time-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "uuid"
|
||||||
|
version = "1.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "feb41e78f93363bb2df8b0e86a2ca30eed7806ea16ea0c790d757cf93f79be83"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "version_check"
|
||||||
|
version = "0.9.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "warp-args"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"bincode",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "warp-packer"
|
||||||
|
version = "0.4.0"
|
||||||
|
dependencies = [
|
||||||
|
"bincode",
|
||||||
|
"clap",
|
||||||
|
"flate2",
|
||||||
|
"lazy_static",
|
||||||
|
"tar",
|
||||||
|
"tempdir",
|
||||||
|
"uuid",
|
||||||
|
"warp-args",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "warp-runner"
|
||||||
|
version = "0.4.0"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"bincode",
|
||||||
|
"dirs",
|
||||||
|
"flate2",
|
||||||
|
"log",
|
||||||
|
"memmem",
|
||||||
|
"remove_dir_all 0.7.0",
|
||||||
|
"simple_logger",
|
||||||
|
"tar",
|
||||||
|
"warp-args",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasi"
|
||||||
|
version = "0.10.2+wasi-snapshot-preview1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi"
|
||||||
|
version = "0.3.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-i686-pc-windows-gnu",
|
||||||
|
"winapi-x86_64-pc-windows-gnu",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-i686-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-util"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
||||||
|
dependencies = [
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-x86_64-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-sys"
|
||||||
|
version = "0.42.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
|
||||||
|
dependencies = [
|
||||||
|
"windows_aarch64_gnullvm",
|
||||||
|
"windows_aarch64_msvc",
|
||||||
|
"windows_i686_gnu",
|
||||||
|
"windows_i686_msvc",
|
||||||
|
"windows_x86_64_gnu",
|
||||||
|
"windows_x86_64_gnullvm",
|
||||||
|
"windows_x86_64_msvc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_gnullvm"
|
||||||
|
version = "0.42.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_msvc"
|
||||||
|
version = "0.42.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnu"
|
||||||
|
version = "0.42.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_msvc"
|
||||||
|
version = "0.42.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnu"
|
||||||
|
version = "0.42.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnullvm"
|
||||||
|
version = "0.42.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_msvc"
|
||||||
|
version = "0.42.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "xattr"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
@ -1,2 +1,2 @@
|
|||||||
[workspace]
|
[workspace]
|
||||||
members = ["warp-runner", "warp-packer"]
|
members = ["warp-args", "warp-runner", "warp-packer"]
|
||||||
|
8
Makefile
8
Makefile
@ -2,8 +2,8 @@ all:
|
|||||||
$(MAKE) build
|
$(MAKE) build
|
||||||
|
|
||||||
build:
|
build:
|
||||||
cargo build -p warp-runner --release --target x86_64-unknown-linux-gnu
|
cargo build -p warp-runner --release --target x86_64-unknown-linux-musl
|
||||||
strip target/x86_64-unknown-linux-gnu/release/warp-runner
|
strip target/x86_64-unknown-linux-musl/release/warp-runner
|
||||||
|
|
||||||
CC=x86_64-apple-darwin15-clang cargo build -p warp-runner --release --target x86_64-apple-darwin
|
CC=x86_64-apple-darwin15-clang cargo build -p warp-runner --release --target x86_64-apple-darwin
|
||||||
x86_64-apple-darwin15-strip target/x86_64-apple-darwin/release/warp-runner
|
x86_64-apple-darwin15-strip target/x86_64-apple-darwin/release/warp-runner
|
||||||
@ -11,8 +11,8 @@ build:
|
|||||||
cargo build -p warp-runner --release --target x86_64-pc-windows-gnu
|
cargo build -p warp-runner --release --target x86_64-pc-windows-gnu
|
||||||
strip target/x86_64-pc-windows-gnu/release/warp-runner.exe
|
strip target/x86_64-pc-windows-gnu/release/warp-runner.exe
|
||||||
|
|
||||||
cargo build -p warp-packer --release --target x86_64-unknown-linux-gnu
|
cargo build -p warp-packer --release --target x86_64-unknown-linux-musl
|
||||||
strip target/x86_64-unknown-linux-gnu/release/warp-packer
|
strip target/x86_64-unknown-linux-musl/release/warp-packer
|
||||||
|
|
||||||
CC=x86_64-apple-darwin15-clang cargo build -p warp-packer --release --target x86_64-apple-darwin
|
CC=x86_64-apple-darwin15-clang cargo build -p warp-packer --release --target x86_64-apple-darwin
|
||||||
x86_64-apple-darwin15-strip target/x86_64-apple-darwin/release/warp-packer
|
x86_64-apple-darwin15-strip target/x86_64-apple-darwin/release/warp-packer
|
||||||
|
10
warp-args/Cargo.toml
Normal file
10
warp-args/Cargo.toml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
[package]
|
||||||
|
name = "warp-args"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
bincode = "1.3"
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
22
warp-args/src/lib.rs
Normal file
22
warp-args/src/lib.rs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
use bincode::Options;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
pub const WARP_ARGS_MAGIC: &[u8] = b"DR1PWsJsM6KxNbng9Y38";
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct Args {
|
||||||
|
pub target_file_name: PathBuf,
|
||||||
|
pub prefix: Option<PathBuf>,
|
||||||
|
pub uid: Option<String>,
|
||||||
|
pub clean: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bincode_options() -> impl bincode::Options {
|
||||||
|
bincode::DefaultOptions::new()
|
||||||
|
.with_fixint_encoding()
|
||||||
|
.allow_trailing_bytes()
|
||||||
|
// Make sure bincode does not trust all size prefixes while scanning the binary
|
||||||
|
.with_limit(1_000_000)
|
||||||
|
}
|
@ -1,13 +1,15 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "warp-packer"
|
name = "warp-packer"
|
||||||
version = "0.3.0"
|
version = "0.4.0"
|
||||||
authors = ["Diego Giagio <diego@giagio.com>"]
|
authors = ["Diego Giagio <diego@giagio.com>"]
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = "2.32.0"
|
bincode = "1.3"
|
||||||
dirs = "1.0.4"
|
clap = { version = "4.0", features = ["derive"] }
|
||||||
reqwest = "0.9.2"
|
|
||||||
tempdir = "0.3.7"
|
|
||||||
flate2 = "1.0"
|
flate2 = "1.0"
|
||||||
|
lazy_static = "1.1.0"
|
||||||
tar = "0.4"
|
tar = "0.4"
|
||||||
lazy_static = "1.1.0"
|
tempdir = "0.3.7"
|
||||||
|
uuid = { version = "1.2", features = ["v4"] }
|
||||||
|
warp-args = { path = "../warp-args" }
|
||||||
|
47
warp-packer/src/cli.rs
Normal file
47
warp-packer/src/cli.rs
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
use clap::{Args, Parser, Subcommand};
|
||||||
|
|
||||||
|
#[derive(Parser, Debug)]
|
||||||
|
#[command(author, version, about)]
|
||||||
|
pub struct Cli {
|
||||||
|
#[command(subcommand)]
|
||||||
|
pub command: Command,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Subcommand, Debug)]
|
||||||
|
pub enum Command {
|
||||||
|
Pack(PackArgs),
|
||||||
|
List,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Args, Debug)]
|
||||||
|
pub struct PackArgs {
|
||||||
|
/// Sets the architecture. Use list subcommand to get possible options.
|
||||||
|
#[arg(short, long)]
|
||||||
|
pub arch: String,
|
||||||
|
|
||||||
|
/// Sets the input directory containing the application and dependencies
|
||||||
|
#[arg(short, long)]
|
||||||
|
pub input_dir: PathBuf,
|
||||||
|
|
||||||
|
/// Sets the application executable file name
|
||||||
|
#[arg(short, long)]
|
||||||
|
pub exec: PathBuf,
|
||||||
|
|
||||||
|
/// Sets the resulting self-contained application file name
|
||||||
|
#[arg(short, long)]
|
||||||
|
pub output: PathBuf,
|
||||||
|
|
||||||
|
/// Generate unique id for each package build
|
||||||
|
#[arg(short = 'q', long, default_value_t = false)]
|
||||||
|
pub unique_id: bool,
|
||||||
|
|
||||||
|
/// Prefix to use instead of single-file executable name
|
||||||
|
#[arg(short, long)]
|
||||||
|
pub prefix: Option<PathBuf>,
|
||||||
|
|
||||||
|
/// When using unique-id, do not look for and clean obsolete versions with the same prefix from cache
|
||||||
|
#[arg(short = 'n', long = "no-clean", action = clap::ArgAction::SetFalse)]
|
||||||
|
pub clean: bool,
|
||||||
|
}
|
@ -1,42 +1,37 @@
|
|||||||
extern crate clap;
|
mod cli;
|
||||||
extern crate dirs;
|
|
||||||
extern crate flate2;
|
|
||||||
#[macro_use]
|
|
||||||
extern crate lazy_static;
|
|
||||||
extern crate reqwest;
|
|
||||||
extern crate tar;
|
|
||||||
extern crate tempdir;
|
|
||||||
|
|
||||||
use clap::{App, AppSettings, Arg};
|
use bincode::Options;
|
||||||
use flate2::Compression;
|
use clap::Parser;
|
||||||
use flate2::write::GzEncoder;
|
use flate2::write::GzEncoder;
|
||||||
use std::collections::HashMap;
|
use flate2::Compression;
|
||||||
|
use lazy_static::lazy_static;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io;
|
use std::io::{self, Write};
|
||||||
use std::io::copy;
|
|
||||||
use std::io::Write;
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::process;
|
use std::process;
|
||||||
use tempdir::TempDir;
|
use std::{collections::HashMap, io::BufWriter};
|
||||||
|
use uuid::Uuid;
|
||||||
|
use warp_args::{bincode_options, Args, WARP_ARGS_MAGIC};
|
||||||
|
|
||||||
const APP_NAME: &str = env!("CARGO_PKG_NAME");
|
use crate::cli::Command;
|
||||||
const AUTHOR: &str = env!("CARGO_PKG_AUTHORS");
|
|
||||||
const VERSION: &str = env!("CARGO_PKG_VERSION");
|
|
||||||
|
|
||||||
const RUNNER_MAGIC: &[u8] = b"tVQhhsFFlGGD3oWV4lEPST8I8FEPP54IM0q7daes4E1y3p2U2wlJRYmWmjPYfkhZ0PlT14Ls0j8fdDkoj33f2BlRJavLj3mWGibJsGt5uLAtrCDtvxikZ8UX2mQDCrgE\0";
|
|
||||||
|
|
||||||
const RUNNER_LINUX_X64: &[u8] = include_bytes!("../../target/x86_64-unknown-linux-gnu/release/warp-runner");
|
|
||||||
const RUNNER_MACOS_X64: &[u8] = include_bytes!("../../target/x86_64-apple-darwin/release/warp-runner");
|
|
||||||
const RUNNER_WINDOWS_X64: &[u8] = include_bytes!("../../target/x86_64-pc-windows-gnu/release/warp-runner.exe");
|
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref RUNNER_BY_ARCH: HashMap<&'static str, &'static [u8]> = {
|
static ref RUNNER_BY_ARCH: HashMap<&'static str, &'static [u8]> = {
|
||||||
let mut m = HashMap::new();
|
let mut m = HashMap::new();
|
||||||
m.insert("linux-x64", RUNNER_LINUX_X64);
|
m.insert(
|
||||||
m.insert("macos-x64", RUNNER_MACOS_X64);
|
"linux-x64",
|
||||||
m.insert("windows-x64", RUNNER_WINDOWS_X64);
|
include_bytes!("../../target/x86_64-unknown-linux-musl/release/warp-runner").as_slice(),
|
||||||
|
);
|
||||||
|
m.insert(
|
||||||
|
"macos-x64",
|
||||||
|
include_bytes!("../../target/x86_64-apple-darwin/release/warp-runner").as_slice(),
|
||||||
|
);
|
||||||
|
m.insert(
|
||||||
|
"windows-x64",
|
||||||
|
include_bytes!("../../target/x86_64-pc-windows-gnu/release/warp-runner.exe").as_slice(),
|
||||||
|
);
|
||||||
m
|
m
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -50,43 +45,16 @@ macro_rules! bail {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn patch_runner(arch: &str, exec_name: &str) -> io::Result<Vec<u8>> {
|
fn append_tgz(f: &mut impl io::Write, dir: &Path) -> io::Result<()> {
|
||||||
// Read runner executable in memory
|
|
||||||
let runner_contents = RUNNER_BY_ARCH.get(arch).unwrap();
|
|
||||||
let mut buf = runner_contents.to_vec();
|
|
||||||
|
|
||||||
// Set the correct target executable name into the local magic buffer
|
|
||||||
let magic_len = RUNNER_MAGIC.len();
|
|
||||||
let mut new_magic = vec![0; magic_len];
|
|
||||||
new_magic[..exec_name.len()].clone_from_slice(exec_name.as_bytes());
|
|
||||||
|
|
||||||
// Find the magic buffer offset inside the runner executable
|
|
||||||
let mut offs_opt = None;
|
|
||||||
for (i, chunk) in buf.windows(magic_len).enumerate() {
|
|
||||||
if chunk == RUNNER_MAGIC {
|
|
||||||
offs_opt = Some(i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if offs_opt.is_none() {
|
|
||||||
return Err(io::Error::new(io::ErrorKind::Other, "no magic found inside runner"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Replace the magic with the new one that points to the target executable
|
|
||||||
let offs = offs_opt.unwrap();
|
|
||||||
buf[offs..offs + magic_len].clone_from_slice(&new_magic);
|
|
||||||
|
|
||||||
Ok(buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn create_tgz(dir: &Path, out: &Path) -> io::Result<()> {
|
|
||||||
let f = fs::File::create(out)?;
|
|
||||||
let gz = GzEncoder::new(f, Compression::best());
|
let gz = GzEncoder::new(f, Compression::best());
|
||||||
let mut tar = tar::Builder::new(gz);
|
let mut tar = tar::Builder::new(gz);
|
||||||
tar.follow_symlinks(false);
|
tar.follow_symlinks(false);
|
||||||
tar.append_dir_all(".", dir)?;
|
tar.append_dir_all(".", dir)
|
||||||
Ok(())
|
}
|
||||||
|
|
||||||
|
fn append_args(f: &mut impl io::Write, args: &Args) {
|
||||||
|
f.write_all(WARP_ARGS_MAGIC).unwrap();
|
||||||
|
bincode_options().serialize_into(f, args).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_family = "unix")]
|
#[cfg(target_family = "unix")]
|
||||||
@ -102,76 +70,38 @@ fn create_app_file(out: &Path) -> io::Result<File> {
|
|||||||
|
|
||||||
#[cfg(target_family = "windows")]
|
#[cfg(target_family = "windows")]
|
||||||
fn create_app_file(out: &Path) -> io::Result<File> {
|
fn create_app_file(out: &Path) -> io::Result<File> {
|
||||||
fs::OpenOptions::new()
|
fs::OpenOptions::new().create(true).write(true).open(out)
|
||||||
.create(true)
|
|
||||||
.write(true)
|
|
||||||
.open(out)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_app(runner_buf: &Vec<u8>, tgz_path: &Path, out: &Path) -> io::Result<()> {
|
fn main() -> Result<(), Box<dyn Error>> {
|
||||||
let mut outf = create_app_file(out)?;
|
let args = cli::Cli::parse();
|
||||||
let mut tgzf = fs::File::open(tgz_path)?;
|
|
||||||
outf.write_all(runner_buf)?;
|
|
||||||
copy(&mut tgzf, &mut outf)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() -> Result<(), Box<Error>> {
|
let args = match args.command {
|
||||||
let args = App::new(APP_NAME)
|
Command::List => {
|
||||||
.settings(&[AppSettings::ArgRequiredElseHelp, AppSettings::ColoredHelp])
|
for arch in RUNNER_BY_ARCH.keys() {
|
||||||
.version(VERSION)
|
println!("{arch}");
|
||||||
.author(AUTHOR)
|
}
|
||||||
.about("Create self-contained single binary application")
|
return Ok(());
|
||||||
.arg(Arg::with_name("arch")
|
}
|
||||||
.short("a")
|
Command::Pack(args) => args,
|
||||||
.long("arch")
|
};
|
||||||
.value_name("arch")
|
|
||||||
.help(&format!("Sets the architecture. Supported: {:?}", RUNNER_BY_ARCH.keys()))
|
|
||||||
.display_order(1)
|
|
||||||
.takes_value(true)
|
|
||||||
.required(true))
|
|
||||||
.arg(Arg::with_name("input_dir")
|
|
||||||
.short("i")
|
|
||||||
.long("input_dir")
|
|
||||||
.value_name("input_dir")
|
|
||||||
.help("Sets the input directory containing the application and dependencies")
|
|
||||||
.display_order(2)
|
|
||||||
.takes_value(true)
|
|
||||||
.required(true))
|
|
||||||
.arg(Arg::with_name("exec")
|
|
||||||
.short("e")
|
|
||||||
.long("exec")
|
|
||||||
.value_name("exec")
|
|
||||||
.help("Sets the application executable file name")
|
|
||||||
.display_order(3)
|
|
||||||
.takes_value(true)
|
|
||||||
.required(true))
|
|
||||||
.arg(Arg::with_name("output")
|
|
||||||
.short("o")
|
|
||||||
.long("output")
|
|
||||||
.value_name("output")
|
|
||||||
.help("Sets the resulting self-contained application file name")
|
|
||||||
.display_order(4)
|
|
||||||
.takes_value(true)
|
|
||||||
.required(true))
|
|
||||||
.get_matches();
|
|
||||||
|
|
||||||
let arch = args.value_of("arch").unwrap();
|
if !RUNNER_BY_ARCH.contains_key(&args.arch.as_str()) {
|
||||||
if !RUNNER_BY_ARCH.contains_key(&arch) {
|
bail!(
|
||||||
bail!("Unknown architecture specified: {}, supported: {:?}", arch, RUNNER_BY_ARCH.keys());
|
"Unknown architecture specified: {}, supported: {:?}",
|
||||||
|
args.arch,
|
||||||
|
RUNNER_BY_ARCH.keys()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let input_dir = Path::new(args.value_of("input_dir").unwrap());
|
if fs::metadata(&args.input_dir).is_err() {
|
||||||
if fs::metadata(input_dir).is_err() {
|
bail!(
|
||||||
bail!("Cannot access specified input directory {:?}", input_dir);
|
"Cannot access specified input directory {:?}",
|
||||||
|
args.input_dir
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let exec_name = args.value_of("exec").unwrap();
|
let exec_path = args.input_dir.join(&args.exec);
|
||||||
if exec_name.len() >= RUNNER_MAGIC.len() {
|
|
||||||
bail!("Executable name is too long, please consider using a shorter name");
|
|
||||||
}
|
|
||||||
|
|
||||||
let exec_path = Path::new(input_dir).join(exec_name);
|
|
||||||
match fs::metadata(&exec_path) {
|
match fs::metadata(&exec_path) {
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
bail!("Cannot find file {:?}", exec_path);
|
bail!("Cannot find file {:?}", exec_path);
|
||||||
@ -183,16 +113,24 @@ fn main() -> Result<(), Box<Error>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let runner_buf = patch_runner(&arch, &exec_name)?;
|
println!(
|
||||||
|
"Creating self-contained application binary {:?}...",
|
||||||
|
args.exec
|
||||||
|
);
|
||||||
|
let mut output = BufWriter::new(create_app_file(&args.output).unwrap());
|
||||||
|
output.write_all(RUNNER_BY_ARCH.get(&args.arch.as_str()).unwrap())?;
|
||||||
|
append_args(
|
||||||
|
&mut output,
|
||||||
|
&Args {
|
||||||
|
target_file_name: args.exec,
|
||||||
|
prefix: args.prefix,
|
||||||
|
uid: args.unique_id.then(|| format!("{}", Uuid::new_v4())),
|
||||||
|
clean: args.clean,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
println!("Compressing input directory {:?}...", input_dir);
|
println!("Compressing input directory {:?}...", args.input_dir);
|
||||||
let tmp_dir = TempDir::new(APP_NAME)?;
|
append_tgz(&mut output, &args.input_dir).unwrap();
|
||||||
let tgz_path = tmp_dir.path().join("input.tgz");
|
|
||||||
create_tgz(&input_dir, &tgz_path)?;
|
|
||||||
|
|
||||||
let exec_name = Path::new(args.value_of("output").unwrap());
|
|
||||||
println!("Creating self-contained application binary {:?}...", exec_name);
|
|
||||||
create_app(&runner_buf, &tgz_path, &exec_name)?;
|
|
||||||
|
|
||||||
println!("All done");
|
println!("All done");
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -1,13 +1,17 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "warp-runner"
|
name = "warp-runner"
|
||||||
version = "0.3.0"
|
version = "0.4.0"
|
||||||
authors = ["Diego Giagio <diego@giagio.com>"]
|
authors = ["Diego Giagio <diego@giagio.com>"]
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
memmem = "0.1.1"
|
anyhow = "1.0"
|
||||||
|
bincode = "1.3"
|
||||||
|
dirs = "4.0"
|
||||||
flate2 = "1.0"
|
flate2 = "1.0"
|
||||||
tar = "0.4"
|
|
||||||
dirs = "1.0.4"
|
|
||||||
winapi = "0.3.6"
|
|
||||||
log = "0.4.5"
|
log = "0.4.5"
|
||||||
simple_logger = "1.0.1"
|
memmem = "0.1.1"
|
||||||
|
remove_dir_all = "0.7"
|
||||||
|
simple_logger = "4.0"
|
||||||
|
tar = "0.4"
|
||||||
|
warp-args = { path = "../warp-args" }
|
||||||
|
@ -1,80 +1,87 @@
|
|||||||
use std::env;
|
use log::trace;
|
||||||
use std::io;
|
use std::env;
|
||||||
#[cfg(target_family = "unix")]
|
#[cfg(target_family = "unix")]
|
||||||
use std::fs;
|
use std::fs;
|
||||||
#[cfg(target_family = "unix")]
|
#[cfg(target_family = "unix")]
|
||||||
use std::fs::Permissions;
|
use std::fs::Permissions;
|
||||||
#[cfg(target_family = "unix")]
|
use std::io;
|
||||||
use std::os::unix::fs::PermissionsExt;
|
#[cfg(target_family = "unix")]
|
||||||
use std::path::Path;
|
use std::os::unix::fs::PermissionsExt;
|
||||||
use std::process::Command;
|
use std::path::Path;
|
||||||
use std::process::Stdio;
|
use std::process::Command;
|
||||||
|
use std::process::Stdio;
|
||||||
pub fn execute(target: &Path) -> io::Result<i32> {
|
|
||||||
trace!("target={:?}", target);
|
pub fn execute(target: &Path) -> io::Result<i32> {
|
||||||
|
trace!("target={:?}", target);
|
||||||
let args: Vec<String> = env::args().skip(1).collect();
|
|
||||||
trace!("args={:?}", args);
|
let args: Vec<String> = env::args().skip(1).collect();
|
||||||
|
trace!("args={:?}", args);
|
||||||
do_execute(target, &args)
|
|
||||||
}
|
do_execute(target, &args)
|
||||||
|
}
|
||||||
#[cfg(target_family = "unix")]
|
|
||||||
fn ensure_executable(target: &Path) {
|
#[cfg(target_family = "unix")]
|
||||||
let perms = Permissions::from_mode(0o770);
|
fn ensure_executable(target: &Path) {
|
||||||
fs::set_permissions(target, perms).unwrap();
|
let perms = Permissions::from_mode(0o770);
|
||||||
}
|
fs::set_permissions(target, perms).unwrap();
|
||||||
|
}
|
||||||
#[cfg(target_family = "unix")]
|
|
||||||
fn do_execute(target: &Path, args: &[String]) -> io::Result<i32> {
|
#[cfg(target_family = "unix")]
|
||||||
ensure_executable(target);
|
fn do_execute(target: &Path, args: &[String]) -> io::Result<i32> {
|
||||||
|
ensure_executable(target);
|
||||||
Ok(Command::new(target)
|
|
||||||
.args(args)
|
Ok(Command::new(target)
|
||||||
.stdin(Stdio::inherit())
|
.args(args)
|
||||||
.stdout(Stdio::inherit())
|
.stdin(Stdio::inherit())
|
||||||
.stderr(Stdio::inherit())
|
.stdout(Stdio::inherit())
|
||||||
.spawn()?
|
.stderr(Stdio::inherit())
|
||||||
.wait()?
|
.spawn()?
|
||||||
.code().unwrap_or(1))
|
.wait()?
|
||||||
}
|
.code()
|
||||||
|
.unwrap_or(1))
|
||||||
#[cfg(target_family = "windows")]
|
}
|
||||||
fn is_script(target: &Path) -> bool {
|
|
||||||
const SCRIPT_EXTENSIONS: &[&str] = &["bat", "cmd"];
|
#[cfg(target_family = "windows")]
|
||||||
SCRIPT_EXTENSIONS.contains(
|
fn is_script(target: &Path) -> bool {
|
||||||
&target.extension()
|
const SCRIPT_EXTENSIONS: &[&str] = &["bat", "cmd"];
|
||||||
.unwrap_or_default()
|
SCRIPT_EXTENSIONS.contains(
|
||||||
.to_string_lossy()
|
&target
|
||||||
.to_lowercase().as_str())
|
.extension()
|
||||||
}
|
.unwrap_or_default()
|
||||||
|
.to_string_lossy()
|
||||||
#[cfg(target_family = "windows")]
|
.to_lowercase()
|
||||||
fn do_execute(target: &Path, args: &[String]) -> io::Result<i32> {
|
.as_str(),
|
||||||
let target_str = target.as_os_str().to_str().unwrap();
|
)
|
||||||
|
}
|
||||||
if is_script(target) {
|
|
||||||
let mut cmd_args = Vec::with_capacity(args.len() + 2);
|
#[cfg(target_family = "windows")]
|
||||||
cmd_args.push("/c".to_string());
|
fn do_execute(target: &Path, args: &[String]) -> io::Result<i32> {
|
||||||
cmd_args.push(target_str.to_string());
|
let target_str = target.as_os_str().to_str().unwrap();
|
||||||
cmd_args.extend_from_slice(&args);
|
|
||||||
|
if is_script(target) {
|
||||||
Ok(Command::new("cmd")
|
let mut cmd_args = Vec::with_capacity(args.len() + 2);
|
||||||
.args(cmd_args)
|
cmd_args.push("/c".to_string());
|
||||||
.stdin(Stdio::inherit())
|
cmd_args.push(target_str.to_string());
|
||||||
.stdout(Stdio::inherit())
|
cmd_args.extend_from_slice(&args);
|
||||||
.stderr(Stdio::inherit())
|
|
||||||
.spawn()?
|
Ok(Command::new("cmd")
|
||||||
.wait()?
|
.args(cmd_args)
|
||||||
.code().unwrap_or(1))
|
.stdin(Stdio::inherit())
|
||||||
} else {
|
.stdout(Stdio::inherit())
|
||||||
Ok(Command::new(target)
|
.stderr(Stdio::inherit())
|
||||||
.args(args)
|
.spawn()?
|
||||||
.stdin(Stdio::inherit())
|
.wait()?
|
||||||
.stdout(Stdio::inherit())
|
.code()
|
||||||
.stderr(Stdio::inherit())
|
.unwrap_or(1))
|
||||||
.spawn()?
|
} else {
|
||||||
.wait()?
|
Ok(Command::new(target)
|
||||||
.code().unwrap_or(1))
|
.args(args)
|
||||||
}
|
.stdin(Stdio::inherit())
|
||||||
}
|
.stdout(Stdio::inherit())
|
||||||
|
.stderr(Stdio::inherit())
|
||||||
|
.spawn()?
|
||||||
|
.wait()?
|
||||||
|
.code()
|
||||||
|
.unwrap_or(1))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,99 +1,120 @@
|
|||||||
extern crate flate2;
|
use anyhow::{anyhow, Context, Result};
|
||||||
extern crate memmem;
|
use bincode::Options;
|
||||||
extern crate tar;
|
use flate2::read::GzDecoder;
|
||||||
|
use log::trace;
|
||||||
use self::flate2::read::GzDecoder;
|
use memmem::{Searcher, TwoWaySearcher};
|
||||||
use self::memmem::{Searcher, TwoWaySearcher};
|
use std::fs::File;
|
||||||
use self::tar::Archive;
|
use std::io;
|
||||||
use std::fs::File;
|
use std::io::{BufReader, Read, Seek, SeekFrom};
|
||||||
use std::io;
|
use std::path::Path;
|
||||||
use std::io::{BufReader, Read, Seek, SeekFrom};
|
use tar::Archive;
|
||||||
use std::path::Path;
|
use warp_args::{bincode_options, Args, WARP_ARGS_MAGIC};
|
||||||
|
|
||||||
struct FileSearcher<'a> {
|
struct FileSearcher<'a> {
|
||||||
buf_reader: BufReader<File>,
|
buf_reader: BufReader<File>,
|
||||||
searcher: TwoWaySearcher<'a>,
|
searcher: TwoWaySearcher<'a>,
|
||||||
offs: usize,
|
offs: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> FileSearcher<'a> {
|
impl<'a> FileSearcher<'a> {
|
||||||
fn new(path: &'a Path, magic: &'a [u8]) -> io::Result<FileSearcher<'a>> {
|
fn new(path: &'a Path, magic: &'a [u8]) -> io::Result<FileSearcher<'a>> {
|
||||||
let file = File::open(path)?;
|
let file = File::open(path)?;
|
||||||
Ok(FileSearcher {
|
Ok(FileSearcher {
|
||||||
buf_reader: BufReader::new(file),
|
buf_reader: BufReader::new(file),
|
||||||
searcher: TwoWaySearcher::new(magic),
|
searcher: TwoWaySearcher::new(magic),
|
||||||
offs: 0,
|
offs: 0,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Iterator for FileSearcher<'a> {
|
impl<'a> Iterator for FileSearcher<'a> {
|
||||||
type Item = io::Result<usize>;
|
type Item = io::Result<usize>;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<io::Result<usize>> {
|
fn next(&mut self) -> Option<io::Result<usize>> {
|
||||||
let mut buf = [0; 32 * 1024];
|
let mut buf = [0; 32 * 1024];
|
||||||
let ret;
|
let ret;
|
||||||
|
|
||||||
match self.buf_reader.seek(SeekFrom::Start(self.offs as u64)) {
|
match self.buf_reader.seek(SeekFrom::Start(self.offs as u64)) {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(e) => return Some(Err(e))
|
Err(e) => return Some(Err(e)),
|
||||||
}
|
}
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match self.buf_reader.read(&mut buf[..]) {
|
match self.buf_reader.read(&mut buf[..]) {
|
||||||
Ok(0) => {
|
Ok(0) => {
|
||||||
ret = None;
|
ret = None;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Ok(n) => {
|
Ok(n) => {
|
||||||
match self.searcher.search_in(&buf) {
|
match self.searcher.search_in(&buf) {
|
||||||
Some(pos) => {
|
Some(pos) => {
|
||||||
self.offs += pos;
|
self.offs += pos;
|
||||||
ret = Some(Ok(self.offs));
|
ret = Some(Ok(self.offs));
|
||||||
self.offs += 1; // one past the match so we can try again if necessary
|
self.offs += 1; // one past the match so we can try again if necessary
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
None => self.offs += n
|
None => self.offs += n,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
ret = Some(Err(e));
|
ret = Some(Err(e));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const GZIP_MAGIC: &[u8] = b"\x1f\x8b\x08";
|
const GZIP_MAGIC: &[u8] = b"\x1f\x8b\x08";
|
||||||
|
|
||||||
pub fn extract_to(src: &Path, dst: &Path) -> io::Result<()> {
|
pub fn extract_to(src: &Path, dst: &Path) -> Result<()> {
|
||||||
let mut found = false;
|
FileSearcher::new(src, GZIP_MAGIC)
|
||||||
|
.context("failed searching own binary")?
|
||||||
let searcher = FileSearcher::new(src, GZIP_MAGIC)?;
|
.map(Result::unwrap)
|
||||||
for result in searcher {
|
.find(|offs| extract_at_offset(src, *offs, dst).unwrap())
|
||||||
let offs = result?;
|
.ok_or_else(|| anyhow!("No tarball found inside binary file {}", src.display()))
|
||||||
if extract_at_offset(src, offs, dst).is_ok() {
|
.map(|offs| {
|
||||||
trace!("tarball found at offset {} was extracted successfully", offs);
|
trace!(
|
||||||
found = true;
|
"tarball found at offset {} was extracted successfully",
|
||||||
break;
|
offs
|
||||||
}
|
);
|
||||||
}
|
})
|
||||||
|
}
|
||||||
if found {
|
|
||||||
Ok(())
|
fn extract_at_offset(src: &Path, offs: usize, dst: &Path) -> Result<bool> {
|
||||||
} else {
|
let mut f = File::open(src)
|
||||||
Err(io::Error::new(io::ErrorKind::Other, "no tarball found inside binary"))
|
.with_context(|| format!("Failed to open file to extract from: {}", src.display()))?;
|
||||||
}
|
f.seek(SeekFrom::Start(offs as u64))
|
||||||
}
|
.with_context(|| format!("Failed to read file to extract from: {}", src.display()))?;
|
||||||
|
|
||||||
fn extract_at_offset(src: &Path, offs: usize, dst: &Path) -> io::Result<()> {
|
let gz = GzDecoder::new(f);
|
||||||
let mut f = File::open(src)?;
|
let mut tar = Archive::new(gz);
|
||||||
f.seek(SeekFrom::Start(offs as u64))?;
|
Ok(tar.unpack(dst).is_ok())
|
||||||
|
}
|
||||||
let gz = GzDecoder::new(f);
|
|
||||||
let mut tar = Archive::new(gz);
|
pub fn get_args(src: &Path) -> Result<Args> {
|
||||||
tar.unpack(dst)?;
|
FileSearcher::new(src, WARP_ARGS_MAGIC)
|
||||||
Ok(())
|
.context("failed searching own binary")?
|
||||||
}
|
.map(Result::unwrap)
|
||||||
|
.find_map(|offs| {
|
||||||
|
Some((
|
||||||
|
offs,
|
||||||
|
extract_args_at_offset(src, offs + WARP_ARGS_MAGIC.len()).unwrap()?,
|
||||||
|
))
|
||||||
|
})
|
||||||
|
.ok_or_else(|| anyhow!("No arguments found inside binary file {}", src.display()))
|
||||||
|
.map(|(offs, args)| {
|
||||||
|
trace!("args found at offset {} was extracted successfully", offs);
|
||||||
|
args
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn extract_args_at_offset(src: &Path, offs: usize) -> Result<Option<Args>> {
|
||||||
|
let mut f = File::open(src)
|
||||||
|
.with_context(|| format!("Failed to open file to extract from: {}", src.display()))?;
|
||||||
|
f.seek(SeekFrom::Start(offs as u64))
|
||||||
|
.with_context(|| format!("Failed to read file to extract from: {}", src.display()))?;
|
||||||
|
|
||||||
|
Ok(bincode_options().deserialize_from(f).ok())
|
||||||
|
}
|
||||||
|
@ -1,82 +1,133 @@
|
|||||||
extern crate dirs;
|
use anyhow::Context;
|
||||||
#[macro_use]
|
use anyhow::{anyhow, Result};
|
||||||
extern crate log;
|
use log::{trace, Level};
|
||||||
extern crate simple_logger;
|
use remove_dir_all::remove_dir_all;
|
||||||
|
|
||||||
use log::Level;
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::error::Error;
|
use std::ffi::OsStr;
|
||||||
use std::ffi::*;
|
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io;
|
use std::path::{Path, PathBuf};
|
||||||
use std::path::*;
|
|
||||||
use std::process;
|
use std::process;
|
||||||
|
use warp_args::Args;
|
||||||
|
|
||||||
|
use crate::extractor::get_args;
|
||||||
|
|
||||||
mod extractor;
|
|
||||||
mod executor;
|
mod executor;
|
||||||
|
mod extractor;
|
||||||
|
|
||||||
static TARGET_FILE_NAME_BUF: &'static [u8] = b"tVQhhsFFlGGD3oWV4lEPST8I8FEPP54IM0q7daes4E1y3p2U2wlJRYmWmjPYfkhZ0PlT14Ls0j8fdDkoj33f2BlRJavLj3mWGibJsGt5uLAtrCDtvxikZ8UX2mQDCrgE\0";
|
static STATIC_SUBFOLDER_NAME: &str = "static";
|
||||||
|
|
||||||
fn target_file_name() -> &'static str {
|
fn cache_path(target: &str) -> Result<PathBuf> {
|
||||||
let nul_pos = TARGET_FILE_NAME_BUF.iter()
|
Ok(dirs::data_local_dir()
|
||||||
.position(|elem| *elem == b'\0')
|
.ok_or_else(|| anyhow!("No data local dir found"))?
|
||||||
.expect("TARGET_FILE_NAME_BUF has no NUL terminator");
|
|
||||||
|
|
||||||
let slice = &TARGET_FILE_NAME_BUF[..(nul_pos + 1)];
|
|
||||||
CStr::from_bytes_with_nul(slice)
|
|
||||||
.expect("Can't convert TARGET_FILE_NAME_BUF slice to CStr")
|
|
||||||
.to_str()
|
|
||||||
.expect("Can't convert TARGET_FILE_NAME_BUF CStr to str")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn cache_path(target: &str) -> PathBuf {
|
|
||||||
dirs::data_local_dir()
|
|
||||||
.expect("No data local dir found")
|
|
||||||
.join("warp")
|
.join("warp")
|
||||||
.join("packages")
|
.join("packages")
|
||||||
.join(target)
|
.join(target))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extract(exe_path: &Path, cache_path: &Path) -> io::Result<()> {
|
fn extract(exe_path: &Path, cache_path: &Path) -> Result<()> {
|
||||||
fs::remove_dir_all(cache_path).ok();
|
if cache_path.exists() {
|
||||||
extractor::extract_to(&exe_path, &cache_path)?;
|
remove_dir_all(cache_path)
|
||||||
|
.with_context(|| format!("Failed to remove directory {}", cache_path.display()))?;
|
||||||
|
}
|
||||||
|
extractor::extract_to(exe_path, cache_path).with_context(|| {
|
||||||
|
format!(
|
||||||
|
"Failed to extract {} to {}",
|
||||||
|
exe_path.display(),
|
||||||
|
cache_path.display()
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_cache_folder(self_path: &Path, args: &Args) -> Result<PathBuf> {
|
||||||
|
let prefix = args
|
||||||
|
.prefix
|
||||||
|
.as_deref()
|
||||||
|
.unwrap_or_else(|| Path::new(self_path.file_name().unwrap()));
|
||||||
|
let cache_path = cache_path(&prefix.to_string_lossy())?;
|
||||||
|
|
||||||
|
trace!("self_path={:?}", self_path);
|
||||||
|
trace!("prefix={:?}", prefix);
|
||||||
|
trace!("cache_path={:?}", cache_path);
|
||||||
|
|
||||||
|
if cache_path.exists() && !fs::metadata(&cache_path)?.is_dir() {
|
||||||
|
return Err(anyhow!("cache at {:?} is not a directory", &cache_path));
|
||||||
|
} else {
|
||||||
|
fs::create_dir_all(&cache_path)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(cache_path)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clean_cache(cache_folder: &Path, self_path: &Path, args: &Args) -> Result<()> {
|
||||||
|
if args.uid.is_none() {
|
||||||
|
let subfolder = cache_folder.join(STATIC_SUBFOLDER_NAME);
|
||||||
|
if subfolder.exists()
|
||||||
|
&& fs::metadata(&subfolder)?.modified()? < fs::metadata(self_path)?.modified()?
|
||||||
|
{
|
||||||
|
trace!("static cache older than source, removing");
|
||||||
|
remove_dir_all(subfolder)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
if !args.clean {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let uid = OsStr::new(args.uid.as_ref().unwrap()); // Checked above
|
||||||
|
let static_folder = OsStr::new(STATIC_SUBFOLDER_NAME);
|
||||||
|
|
||||||
|
trace!("cleaning cache");
|
||||||
|
for entry in fs::read_dir(cache_folder)? {
|
||||||
|
let entry = entry?;
|
||||||
|
|
||||||
|
if entry.file_name() == static_folder {
|
||||||
|
trace!("skipped static subfolder {:?}", static_folder);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if entry.file_name() == uid {
|
||||||
|
trace!("skipped own uid {:?}", uid);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
trace!("removing entry {:?}", entry);
|
||||||
|
if let Err(err) = remove_dir_all(entry.path()) {
|
||||||
|
eprintln!(
|
||||||
|
"Error while attempting to remove directory {:?}: {err}",
|
||||||
|
entry.path()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> Result<(), Box<Error>> {
|
fn main() -> Result<()> {
|
||||||
if env::var("WARP_TRACE").is_ok() {
|
if env::var("WARP_TRACE").is_ok() {
|
||||||
simple_logger::init_with_level(Level::Trace)?;
|
simple_logger::init_with_level(Level::Trace)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let self_path = env::current_exe()?;
|
let self_path = env::current_exe()?;
|
||||||
let self_file_name = self_path.file_name().unwrap();
|
let args = get_args(&self_path).unwrap();
|
||||||
let cache_path = cache_path(&self_file_name.to_string_lossy());
|
trace!("args = {:?}", args);
|
||||||
|
|
||||||
trace!("self_path={:?}", self_path);
|
let cache_path = create_cache_folder(&self_path, &args)?;
|
||||||
trace!("self_file_name={:?}", self_file_name);
|
clean_cache(&cache_path, &self_path, &args)?;
|
||||||
trace!("cache_path={:?}", cache_path);
|
|
||||||
|
|
||||||
let target_file_name = target_file_name();
|
let subfolder = args.uid.as_deref().unwrap_or(STATIC_SUBFOLDER_NAME);
|
||||||
let target_path = cache_path.join(target_file_name);
|
let cache_path = cache_path.join(subfolder);
|
||||||
|
|
||||||
trace!("target_exec={:?}", target_file_name);
|
let target_path = cache_path.join(&args.target_file_name);
|
||||||
|
|
||||||
|
trace!("target_exec={:?}", args.target_file_name);
|
||||||
trace!("target_path={:?}", target_path);
|
trace!("target_path={:?}", target_path);
|
||||||
|
|
||||||
match fs::metadata(&cache_path) {
|
if !cache_path.exists() {
|
||||||
Ok(cache) => {
|
trace!("cache empty, extracting");
|
||||||
if cache.modified()? >= fs::metadata(&self_path)?.modified()? {
|
extract(&self_path, &cache_path)?;
|
||||||
trace!("cache is up-to-date");
|
|
||||||
} else {
|
|
||||||
trace!("cache is outdated");
|
|
||||||
extract(&self_path, &cache_path)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
trace!("cache not found");
|
|
||||||
extract(&self_path, &cache_path)?;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let exit_code = executor::execute(&target_path)?;
|
process::exit(executor::execute(&target_path)?);
|
||||||
process::exit(exit_code);
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user