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:
Reisz 2021-12-11 13:20:14 +01:00 committed by david
parent 99a6ee6ea2
commit d9aeb582a2
13 changed files with 1226 additions and 387 deletions

4
.gitignore vendored
View File

@ -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
View 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",
]

View File

@ -1,2 +1,2 @@
[workspace] [workspace]
members = ["warp-runner", "warp-packer"] members = ["warp-args", "warp-runner", "warp-packer"]

View File

@ -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
View 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
View 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)
}

View File

@ -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"
tar = "0.4"
lazy_static = "1.1.0" 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
View 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,
}

View File

@ -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(())

View File

@ -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" }

View File

@ -1,9 +1,10 @@
use log::trace;
use std::env; use std::env;
use std::io;
#[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;
use std::io;
#[cfg(target_family = "unix")] #[cfg(target_family = "unix")]
use std::os::unix::fs::PermissionsExt; use std::os::unix::fs::PermissionsExt;
use std::path::Path; use std::path::Path;
@ -36,17 +37,21 @@ fn do_execute(target: &Path, args: &[String]) -> io::Result<i32> {
.stderr(Stdio::inherit()) .stderr(Stdio::inherit())
.spawn()? .spawn()?
.wait()? .wait()?
.code().unwrap_or(1)) .code()
.unwrap_or(1))
} }
#[cfg(target_family = "windows")] #[cfg(target_family = "windows")]
fn is_script(target: &Path) -> bool { fn is_script(target: &Path) -> bool {
const SCRIPT_EXTENSIONS: &[&str] = &["bat", "cmd"]; const SCRIPT_EXTENSIONS: &[&str] = &["bat", "cmd"];
SCRIPT_EXTENSIONS.contains( SCRIPT_EXTENSIONS.contains(
&target.extension() &target
.extension()
.unwrap_or_default() .unwrap_or_default()
.to_string_lossy() .to_string_lossy()
.to_lowercase().as_str()) .to_lowercase()
.as_str(),
)
} }
#[cfg(target_family = "windows")] #[cfg(target_family = "windows")]
@ -66,7 +71,8 @@ fn do_execute(target: &Path, args: &[String]) -> io::Result<i32> {
.stderr(Stdio::inherit()) .stderr(Stdio::inherit())
.spawn()? .spawn()?
.wait()? .wait()?
.code().unwrap_or(1)) .code()
.unwrap_or(1))
} else { } else {
Ok(Command::new(target) Ok(Command::new(target)
.args(args) .args(args)
@ -75,6 +81,7 @@ fn do_execute(target: &Path, args: &[String]) -> io::Result<i32> {
.stderr(Stdio::inherit()) .stderr(Stdio::inherit())
.spawn()? .spawn()?
.wait()? .wait()?
.code().unwrap_or(1)) .code()
.unwrap_or(1))
} }
} }

View File

@ -1,14 +1,14 @@
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 self::tar::Archive;
use std::fs::File; use std::fs::File;
use std::io; use std::io;
use std::io::{BufReader, Read, Seek, SeekFrom}; use std::io::{BufReader, Read, Seek, SeekFrom};
use std::path::Path; use std::path::Path;
use tar::Archive;
use warp_args::{bincode_options, Args, WARP_ARGS_MAGIC};
struct FileSearcher<'a> { struct FileSearcher<'a> {
buf_reader: BufReader<File>, 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)) { 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 {
@ -53,7 +53,7 @@ impl<'a> Iterator for FileSearcher<'a> {
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) => {
@ -68,32 +68,53 @@ impl<'a> Iterator for FileSearcher<'a> {
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(())
} else {
Err(io::Error::new(io::ErrorKind::Other, "no tarball found inside binary"))
}
} }
fn extract_at_offset(src: &Path, offs: usize, dst: &Path) -> io::Result<()> { fn extract_at_offset(src: &Path, offs: usize, dst: &Path) -> Result<bool> {
let mut f = File::open(src)?; let mut f = File::open(src)
f.seek(SeekFrom::Start(offs as u64))?; .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 gz = GzDecoder::new(f);
let mut tar = Archive::new(gz); let mut tar = Archive::new(gz);
tar.unpack(dst)?; Ok(tar.unpack(dst).is_ok())
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())
} }

View File

@ -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()? {
trace!("cache is up-to-date");
} else {
trace!("cache is outdated");
extract(&self_path, &cache_path)?; 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);
} }