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
|
||||
/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
|
||||
**/*.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]
|
||||
members = ["warp-runner", "warp-packer"]
|
||||
members = ["warp-args", "warp-runner", "warp-packer"]
|
||||
|
8
Makefile
8
Makefile
@ -2,8 +2,8 @@ all:
|
||||
$(MAKE) build
|
||||
|
||||
build:
|
||||
cargo build -p warp-runner --release --target x86_64-unknown-linux-gnu
|
||||
strip target/x86_64-unknown-linux-gnu/release/warp-runner
|
||||
cargo build -p warp-runner --release --target x86_64-unknown-linux-musl
|
||||
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
|
||||
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
|
||||
strip target/x86_64-pc-windows-gnu/release/warp-runner.exe
|
||||
|
||||
cargo build -p warp-packer --release --target x86_64-unknown-linux-gnu
|
||||
strip target/x86_64-unknown-linux-gnu/release/warp-packer
|
||||
cargo build -p warp-packer --release --target x86_64-unknown-linux-musl
|
||||
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
|
||||
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]
|
||||
name = "warp-packer"
|
||||
version = "0.3.0"
|
||||
version = "0.4.0"
|
||||
authors = ["Diego Giagio <diego@giagio.com>"]
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
clap = "2.32.0"
|
||||
dirs = "1.0.4"
|
||||
reqwest = "0.9.2"
|
||||
tempdir = "0.3.7"
|
||||
bincode = "1.3"
|
||||
clap = { version = "4.0", features = ["derive"] }
|
||||
flate2 = "1.0"
|
||||
tar = "0.4"
|
||||
lazy_static = "1.1.0"
|
||||
tar = "0.4"
|
||||
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;
|
||||
extern crate dirs;
|
||||
extern crate flate2;
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
extern crate reqwest;
|
||||
extern crate tar;
|
||||
extern crate tempdir;
|
||||
mod cli;
|
||||
|
||||
use clap::{App, AppSettings, Arg};
|
||||
use flate2::Compression;
|
||||
use bincode::Options;
|
||||
use clap::Parser;
|
||||
use flate2::write::GzEncoder;
|
||||
use std::collections::HashMap;
|
||||
use flate2::Compression;
|
||||
use lazy_static::lazy_static;
|
||||
use std::error::Error;
|
||||
use std::fs;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
use std::io::copy;
|
||||
use std::io::Write;
|
||||
use std::io::{self, Write};
|
||||
use std::path::Path;
|
||||
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");
|
||||
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");
|
||||
use crate::cli::Command;
|
||||
|
||||
lazy_static! {
|
||||
static ref RUNNER_BY_ARCH: HashMap<&'static str, &'static [u8]> = {
|
||||
let mut m = HashMap::new();
|
||||
m.insert("linux-x64", RUNNER_LINUX_X64);
|
||||
m.insert("macos-x64", RUNNER_MACOS_X64);
|
||||
m.insert("windows-x64", RUNNER_WINDOWS_X64);
|
||||
m.insert(
|
||||
"linux-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
|
||||
};
|
||||
}
|
||||
@ -50,43 +45,16 @@ macro_rules! bail {
|
||||
})
|
||||
}
|
||||
|
||||
fn patch_runner(arch: &str, exec_name: &str) -> io::Result<Vec<u8>> {
|
||||
// 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)?;
|
||||
fn append_tgz(f: &mut impl io::Write, dir: &Path) -> io::Result<()> {
|
||||
let gz = GzEncoder::new(f, Compression::best());
|
||||
let mut tar = tar::Builder::new(gz);
|
||||
tar.follow_symlinks(false);
|
||||
tar.append_dir_all(".", dir)?;
|
||||
Ok(())
|
||||
tar.append_dir_all(".", dir)
|
||||
}
|
||||
|
||||
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")]
|
||||
@ -102,76 +70,38 @@ fn create_app_file(out: &Path) -> io::Result<File> {
|
||||
|
||||
#[cfg(target_family = "windows")]
|
||||
fn create_app_file(out: &Path) -> io::Result<File> {
|
||||
fs::OpenOptions::new()
|
||||
.create(true)
|
||||
.write(true)
|
||||
.open(out)
|
||||
fs::OpenOptions::new().create(true).write(true).open(out)
|
||||
}
|
||||
|
||||
fn create_app(runner_buf: &Vec<u8>, tgz_path: &Path, out: &Path) -> io::Result<()> {
|
||||
let mut outf = create_app_file(out)?;
|
||||
let mut tgzf = fs::File::open(tgz_path)?;
|
||||
outf.write_all(runner_buf)?;
|
||||
copy(&mut tgzf, &mut outf)?;
|
||||
Ok(())
|
||||
}
|
||||
fn main() -> Result<(), Box<dyn Error>> {
|
||||
let args = cli::Cli::parse();
|
||||
|
||||
fn main() -> Result<(), Box<Error>> {
|
||||
let args = App::new(APP_NAME)
|
||||
.settings(&[AppSettings::ArgRequiredElseHelp, AppSettings::ColoredHelp])
|
||||
.version(VERSION)
|
||||
.author(AUTHOR)
|
||||
.about("Create self-contained single binary application")
|
||||
.arg(Arg::with_name("arch")
|
||||
.short("a")
|
||||
.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 args = match args.command {
|
||||
Command::List => {
|
||||
for arch in RUNNER_BY_ARCH.keys() {
|
||||
println!("{arch}");
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
Command::Pack(args) => args,
|
||||
};
|
||||
|
||||
let arch = args.value_of("arch").unwrap();
|
||||
if !RUNNER_BY_ARCH.contains_key(&arch) {
|
||||
bail!("Unknown architecture specified: {}, supported: {:?}", arch, RUNNER_BY_ARCH.keys());
|
||||
if !RUNNER_BY_ARCH.contains_key(&args.arch.as_str()) {
|
||||
bail!(
|
||||
"Unknown architecture specified: {}, supported: {:?}",
|
||||
args.arch,
|
||||
RUNNER_BY_ARCH.keys()
|
||||
);
|
||||
}
|
||||
|
||||
let input_dir = Path::new(args.value_of("input_dir").unwrap());
|
||||
if fs::metadata(input_dir).is_err() {
|
||||
bail!("Cannot access specified input directory {:?}", input_dir);
|
||||
if fs::metadata(&args.input_dir).is_err() {
|
||||
bail!(
|
||||
"Cannot access specified input directory {:?}",
|
||||
args.input_dir
|
||||
);
|
||||
}
|
||||
|
||||
let exec_name = args.value_of("exec").unwrap();
|
||||
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);
|
||||
let exec_path = args.input_dir.join(&args.exec);
|
||||
match fs::metadata(&exec_path) {
|
||||
Err(_) => {
|
||||
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);
|
||||
let tmp_dir = TempDir::new(APP_NAME)?;
|
||||
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!("Compressing input directory {:?}...", args.input_dir);
|
||||
append_tgz(&mut output, &args.input_dir).unwrap();
|
||||
|
||||
println!("All done");
|
||||
Ok(())
|
||||
|
@ -1,13 +1,17 @@
|
||||
[package]
|
||||
name = "warp-runner"
|
||||
version = "0.3.0"
|
||||
version = "0.4.0"
|
||||
authors = ["Diego Giagio <diego@giagio.com>"]
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
memmem = "0.1.1"
|
||||
anyhow = "1.0"
|
||||
bincode = "1.3"
|
||||
dirs = "4.0"
|
||||
flate2 = "1.0"
|
||||
tar = "0.4"
|
||||
dirs = "1.0.4"
|
||||
winapi = "0.3.6"
|
||||
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,9 +1,10 @@
|
||||
use log::trace;
|
||||
use std::env;
|
||||
use std::io;
|
||||
#[cfg(target_family = "unix")]
|
||||
use std::fs;
|
||||
#[cfg(target_family = "unix")]
|
||||
use std::fs::Permissions;
|
||||
use std::io;
|
||||
#[cfg(target_family = "unix")]
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
use std::path::Path;
|
||||
@ -36,17 +37,21 @@ fn do_execute(target: &Path, args: &[String]) -> io::Result<i32> {
|
||||
.stderr(Stdio::inherit())
|
||||
.spawn()?
|
||||
.wait()?
|
||||
.code().unwrap_or(1))
|
||||
.code()
|
||||
.unwrap_or(1))
|
||||
}
|
||||
|
||||
#[cfg(target_family = "windows")]
|
||||
fn is_script(target: &Path) -> bool {
|
||||
const SCRIPT_EXTENSIONS: &[&str] = &["bat", "cmd"];
|
||||
SCRIPT_EXTENSIONS.contains(
|
||||
&target.extension()
|
||||
&target
|
||||
.extension()
|
||||
.unwrap_or_default()
|
||||
.to_string_lossy()
|
||||
.to_lowercase().as_str())
|
||||
.to_lowercase()
|
||||
.as_str(),
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(target_family = "windows")]
|
||||
@ -66,7 +71,8 @@ fn do_execute(target: &Path, args: &[String]) -> io::Result<i32> {
|
||||
.stderr(Stdio::inherit())
|
||||
.spawn()?
|
||||
.wait()?
|
||||
.code().unwrap_or(1))
|
||||
.code()
|
||||
.unwrap_or(1))
|
||||
} else {
|
||||
Ok(Command::new(target)
|
||||
.args(args)
|
||||
@ -75,6 +81,7 @@ fn do_execute(target: &Path, args: &[String]) -> io::Result<i32> {
|
||||
.stderr(Stdio::inherit())
|
||||
.spawn()?
|
||||
.wait()?
|
||||
.code().unwrap_or(1))
|
||||
.code()
|
||||
.unwrap_or(1))
|
||||
}
|
||||
}
|
@ -1,14 +1,14 @@
|
||||
extern crate flate2;
|
||||
extern crate memmem;
|
||||
extern crate tar;
|
||||
|
||||
use self::flate2::read::GzDecoder;
|
||||
use self::memmem::{Searcher, TwoWaySearcher};
|
||||
use self::tar::Archive;
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use bincode::Options;
|
||||
use flate2::read::GzDecoder;
|
||||
use log::trace;
|
||||
use memmem::{Searcher, TwoWaySearcher};
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
use std::io::{BufReader, Read, Seek, SeekFrom};
|
||||
use std::path::Path;
|
||||
use tar::Archive;
|
||||
use warp_args::{bincode_options, Args, WARP_ARGS_MAGIC};
|
||||
|
||||
struct FileSearcher<'a> {
|
||||
buf_reader: BufReader<File>,
|
||||
@ -36,7 +36,7 @@ impl<'a> Iterator for FileSearcher<'a> {
|
||||
|
||||
match self.buf_reader.seek(SeekFrom::Start(self.offs as u64)) {
|
||||
Ok(_) => {}
|
||||
Err(e) => return Some(Err(e))
|
||||
Err(e) => return Some(Err(e)),
|
||||
}
|
||||
|
||||
loop {
|
||||
@ -53,7 +53,7 @@ impl<'a> Iterator for FileSearcher<'a> {
|
||||
self.offs += 1; // one past the match so we can try again if necessary
|
||||
break;
|
||||
}
|
||||
None => self.offs += n
|
||||
None => self.offs += n,
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
@ -68,32 +68,53 @@ impl<'a> Iterator for FileSearcher<'a> {
|
||||
|
||||
const GZIP_MAGIC: &[u8] = b"\x1f\x8b\x08";
|
||||
|
||||
pub fn extract_to(src: &Path, dst: &Path) -> io::Result<()> {
|
||||
let mut found = false;
|
||||
|
||||
let searcher = FileSearcher::new(src, GZIP_MAGIC)?;
|
||||
for result in searcher {
|
||||
let offs = result?;
|
||||
if extract_at_offset(src, offs, dst).is_ok() {
|
||||
trace!("tarball found at offset {} was extracted successfully", offs);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if found {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(io::Error::new(io::ErrorKind::Other, "no tarball found inside binary"))
|
||||
}
|
||||
pub fn extract_to(src: &Path, dst: &Path) -> Result<()> {
|
||||
FileSearcher::new(src, GZIP_MAGIC)
|
||||
.context("failed searching own binary")?
|
||||
.map(Result::unwrap)
|
||||
.find(|offs| extract_at_offset(src, *offs, dst).unwrap())
|
||||
.ok_or_else(|| anyhow!("No tarball found inside binary file {}", src.display()))
|
||||
.map(|offs| {
|
||||
trace!(
|
||||
"tarball found at offset {} was extracted successfully",
|
||||
offs
|
||||
);
|
||||
})
|
||||
}
|
||||
|
||||
fn extract_at_offset(src: &Path, offs: usize, dst: &Path) -> io::Result<()> {
|
||||
let mut f = File::open(src)?;
|
||||
f.seek(SeekFrom::Start(offs as u64))?;
|
||||
fn extract_at_offset(src: &Path, offs: usize, dst: &Path) -> Result<bool> {
|
||||
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()))?;
|
||||
|
||||
let gz = GzDecoder::new(f);
|
||||
let mut tar = Archive::new(gz);
|
||||
tar.unpack(dst)?;
|
||||
Ok(())
|
||||
Ok(tar.unpack(dst).is_ok())
|
||||
}
|
||||
|
||||
pub fn get_args(src: &Path) -> Result<Args> {
|
||||
FileSearcher::new(src, WARP_ARGS_MAGIC)
|
||||
.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;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
extern crate simple_logger;
|
||||
|
||||
use log::Level;
|
||||
use anyhow::Context;
|
||||
use anyhow::{anyhow, Result};
|
||||
use log::{trace, Level};
|
||||
use remove_dir_all::remove_dir_all;
|
||||
use std::env;
|
||||
use std::error::Error;
|
||||
use std::ffi::*;
|
||||
use std::ffi::OsStr;
|
||||
use std::fs;
|
||||
use std::io;
|
||||
use std::path::*;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process;
|
||||
use warp_args::Args;
|
||||
|
||||
use crate::extractor::get_args;
|
||||
|
||||
mod extractor;
|
||||
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 {
|
||||
let nul_pos = TARGET_FILE_NAME_BUF.iter()
|
||||
.position(|elem| *elem == b'\0')
|
||||
.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")
|
||||
fn cache_path(target: &str) -> Result<PathBuf> {
|
||||
Ok(dirs::data_local_dir()
|
||||
.ok_or_else(|| anyhow!("No data local dir found"))?
|
||||
.join("warp")
|
||||
.join("packages")
|
||||
.join(target)
|
||||
.join(target))
|
||||
}
|
||||
|
||||
fn extract(exe_path: &Path, cache_path: &Path) -> io::Result<()> {
|
||||
fs::remove_dir_all(cache_path).ok();
|
||||
extractor::extract_to(&exe_path, &cache_path)?;
|
||||
fn extract(exe_path: &Path, cache_path: &Path) -> Result<()> {
|
||||
if cache_path.exists() {
|
||||
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(())
|
||||
}
|
||||
|
||||
fn main() -> Result<(), Box<Error>> {
|
||||
fn main() -> Result<()> {
|
||||
if env::var("WARP_TRACE").is_ok() {
|
||||
simple_logger::init_with_level(Level::Trace)?;
|
||||
}
|
||||
|
||||
let self_path = env::current_exe()?;
|
||||
let self_file_name = self_path.file_name().unwrap();
|
||||
let cache_path = cache_path(&self_file_name.to_string_lossy());
|
||||
let args = get_args(&self_path).unwrap();
|
||||
trace!("args = {:?}", args);
|
||||
|
||||
trace!("self_path={:?}", self_path);
|
||||
trace!("self_file_name={:?}", self_file_name);
|
||||
trace!("cache_path={:?}", cache_path);
|
||||
let cache_path = create_cache_folder(&self_path, &args)?;
|
||||
clean_cache(&cache_path, &self_path, &args)?;
|
||||
|
||||
let target_file_name = target_file_name();
|
||||
let target_path = cache_path.join(target_file_name);
|
||||
let subfolder = args.uid.as_deref().unwrap_or(STATIC_SUBFOLDER_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);
|
||||
|
||||
match fs::metadata(&cache_path) {
|
||||
Ok(cache) => {
|
||||
if cache.modified()? >= fs::metadata(&self_path)?.modified()? {
|
||||
trace!("cache is up-to-date");
|
||||
} else {
|
||||
trace!("cache is outdated");
|
||||
if !cache_path.exists() {
|
||||
trace!("cache empty, extracting");
|
||||
extract(&self_path, &cache_path)?;
|
||||
}
|
||||
}
|
||||
Err(_) => {
|
||||
trace!("cache not found");
|
||||
extract(&self_path, &cache_path)?;
|
||||
}
|
||||
}
|
||||
|
||||
let exit_code = executor::execute(&target_path)?;
|
||||
process::exit(exit_code);
|
||||
process::exit(executor::execute(&target_path)?);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user