cli: anchor version manager (avm) (#1385)
This commit is contained in:
parent
33c5dab909
commit
75469f423c
|
@ -23,6 +23,7 @@ incremented for features.
|
||||||
* ts: Add new `methods` namespace to the program client, introducing a more ergonomic builder API ([#1324](https://github.com/project-serum/anchor/pull/1324)).
|
* ts: Add new `methods` namespace to the program client, introducing a more ergonomic builder API ([#1324](https://github.com/project-serum/anchor/pull/1324)).
|
||||||
* ts: Add registry utility for fetching the latest verified build ([#1371](https://github.com/project-serum/anchor/pull/1371)).
|
* ts: Add registry utility for fetching the latest verified build ([#1371](https://github.com/project-serum/anchor/pull/1371)).
|
||||||
* cli: Expose the solana-test-validator --account flag in Anchor.toml via [[test.validator.account]] ([#1366](https://github.com/project-serum/anchor/pull/1366)).
|
* cli: Expose the solana-test-validator --account flag in Anchor.toml via [[test.validator.account]] ([#1366](https://github.com/project-serum/anchor/pull/1366)).
|
||||||
|
* cli: Add avm, a tool for managing anchor-cli versions ([#1385](https://github.com/project-serum/anchor/pull/1385)).
|
||||||
|
|
||||||
### Breaking
|
### Breaking
|
||||||
|
|
||||||
|
|
|
@ -154,11 +154,11 @@ dependencies = [
|
||||||
"cargo_toml",
|
"cargo_toml",
|
||||||
"chrono",
|
"chrono",
|
||||||
"clap 3.0.13",
|
"clap 3.0.13",
|
||||||
"dirs",
|
"dirs 3.0.2",
|
||||||
"flate2",
|
"flate2",
|
||||||
"heck 0.3.3",
|
"heck 0.3.3",
|
||||||
"pathdiff",
|
"pathdiff",
|
||||||
"rand 0.7.3",
|
"rand",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"semver 1.0.4",
|
"semver 1.0.4",
|
||||||
"serde",
|
"serde",
|
||||||
|
@ -301,6 +301,24 @@ version = "1.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "avm"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"cfg-if 1.0.0",
|
||||||
|
"clap 3.0.13",
|
||||||
|
"dialoguer 0.9.0",
|
||||||
|
"dirs 4.0.0",
|
||||||
|
"once_cell",
|
||||||
|
"reqwest",
|
||||||
|
"semver 1.0.4",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"tempfile",
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "backtrace"
|
name = "backtrace"
|
||||||
version = "0.3.63"
|
version = "0.3.63"
|
||||||
|
@ -959,6 +977,18 @@ dependencies = [
|
||||||
"tempfile",
|
"tempfile",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dialoguer"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "61579ada4ec0c6031cfac3f86fdba0d195a7ebeb5e36693bd53cb5999a25beeb"
|
||||||
|
dependencies = [
|
||||||
|
"console 0.15.0",
|
||||||
|
"lazy_static",
|
||||||
|
"tempfile",
|
||||||
|
"zeroize",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "digest"
|
name = "digest"
|
||||||
version = "0.8.1"
|
version = "0.8.1"
|
||||||
|
@ -995,6 +1025,15 @@ dependencies = [
|
||||||
"dirs-sys",
|
"dirs-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dirs"
|
||||||
|
version = "4.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059"
|
||||||
|
dependencies = [
|
||||||
|
"dirs-sys",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dirs-next"
|
name = "dirs-next"
|
||||||
version = "2.0.0"
|
version = "2.0.0"
|
||||||
|
@ -1074,7 +1113,7 @@ checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"curve25519-dalek 3.2.0",
|
"curve25519-dalek 3.2.0",
|
||||||
"ed25519",
|
"ed25519",
|
||||||
"rand 0.7.3",
|
"rand",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_bytes",
|
"serde_bytes",
|
||||||
"sha2",
|
"sha2",
|
||||||
|
@ -1197,6 +1236,15 @@ version = "0.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
|
checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fastrand"
|
||||||
|
version = "1.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf"
|
||||||
|
dependencies = [
|
||||||
|
"instant",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "feature-probe"
|
name = "feature-probe"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
|
@ -1430,9 +1478,9 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "h2"
|
name = "h2"
|
||||||
version = "0.3.7"
|
version = "0.3.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7fd819562fcebdac5afc5c113c3ec36f902840b70fd4fc458799c8ce4607ae55"
|
checksum = "d9f1f717ddc7b2ba36df7e871fd88db79326551d3d6f1fc406fbfd28b582ff8e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes 1.1.0",
|
"bytes 1.1.0",
|
||||||
"fnv",
|
"fnv",
|
||||||
|
@ -1552,7 +1600,7 @@ checksum = "1323096b05d41827dadeaee54c9981958c0f94e670bc94ed80037d1a7b8b186b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes 1.1.0",
|
"bytes 1.1.0",
|
||||||
"fnv",
|
"fnv",
|
||||||
"itoa",
|
"itoa 0.4.8",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1599,7 +1647,7 @@ dependencies = [
|
||||||
"http-body",
|
"http-body",
|
||||||
"httparse",
|
"httparse",
|
||||||
"httpdate",
|
"httpdate",
|
||||||
"itoa",
|
"itoa 0.4.8",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"socket2 0.4.2",
|
"socket2 0.4.2",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
@ -1610,17 +1658,15 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hyper-rustls"
|
name = "hyper-rustls"
|
||||||
version = "0.22.1"
|
version = "0.23.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5f9f7a97316d44c0af9b0301e65010573a853a9fc97046d7331d7f6bc0fd5a64"
|
checksum = "d87c48c02e0dc5e3b849a2041db3029fd066650f8f717c07bf8ed78ccb895cac"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-util",
|
"http",
|
||||||
"hyper",
|
"hyper",
|
||||||
"log",
|
|
||||||
"rustls",
|
"rustls",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-rustls",
|
"tokio-rustls",
|
||||||
"webpki",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1717,6 +1763,12 @@ version = "0.4.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
|
checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jobserver"
|
name = "jobserver"
|
||||||
version = "0.1.24"
|
version = "0.1.24"
|
||||||
|
@ -1794,7 +1846,7 @@ dependencies = [
|
||||||
"libsecp256k1-core",
|
"libsecp256k1-core",
|
||||||
"libsecp256k1-gen-ecmult",
|
"libsecp256k1-gen-ecmult",
|
||||||
"libsecp256k1-gen-genmult",
|
"libsecp256k1-gen-genmult",
|
||||||
"rand 0.7.3",
|
"rand",
|
||||||
"serde",
|
"serde",
|
||||||
"sha2",
|
"sha2",
|
||||||
"typenum",
|
"typenum",
|
||||||
|
@ -2390,21 +2442,9 @@ checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom 0.1.16",
|
"getrandom 0.1.16",
|
||||||
"libc",
|
"libc",
|
||||||
"rand_chacha 0.2.2",
|
"rand_chacha",
|
||||||
"rand_core 0.5.1",
|
"rand_core 0.5.1",
|
||||||
"rand_hc 0.2.0",
|
"rand_hc",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand"
|
|
||||||
version = "0.8.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"rand_chacha 0.3.1",
|
|
||||||
"rand_core 0.6.3",
|
|
||||||
"rand_hc 0.3.1",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2417,16 +2457,6 @@ dependencies = [
|
||||||
"rand_core 0.5.1",
|
"rand_core 0.5.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_chacha"
|
|
||||||
version = "0.3.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
|
||||||
dependencies = [
|
|
||||||
"ppv-lite86",
|
|
||||||
"rand_core 0.6.3",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand_core"
|
name = "rand_core"
|
||||||
version = "0.5.1"
|
version = "0.5.1"
|
||||||
|
@ -2441,9 +2471,6 @@ name = "rand_core"
|
||||||
version = "0.6.3"
|
version = "0.6.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
|
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
|
||||||
dependencies = [
|
|
||||||
"getrandom 0.2.3",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand_hc"
|
name = "rand_hc"
|
||||||
|
@ -2454,15 +2481,6 @@ dependencies = [
|
||||||
"rand_core 0.5.1",
|
"rand_core 0.5.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_hc"
|
|
||||||
version = "0.3.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7"
|
|
||||||
dependencies = [
|
|
||||||
"rand_core 0.6.3",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rayon"
|
name = "rayon"
|
||||||
version = "1.5.1"
|
version = "1.5.1"
|
||||||
|
@ -2541,15 +2559,16 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "reqwest"
|
name = "reqwest"
|
||||||
version = "0.11.6"
|
version = "0.11.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "66d2927ca2f685faf0fc620ac4834690d29e7abb153add10f5812eef20b5e280"
|
checksum = "87f242f1488a539a79bac6dbe7c8609ae43b7914b7736210f239a37cccb32525"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.13.0",
|
"base64 0.13.0",
|
||||||
"bytes 1.1.0",
|
"bytes 1.1.0",
|
||||||
"encoding_rs",
|
"encoding_rs",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
|
"h2",
|
||||||
"http",
|
"http",
|
||||||
"http-body",
|
"http-body",
|
||||||
"hyper",
|
"hyper",
|
||||||
|
@ -2565,6 +2584,7 @@ dependencies = [
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"rustls",
|
"rustls",
|
||||||
|
"rustls-pemfile",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_urlencoded",
|
"serde_urlencoded",
|
||||||
|
@ -2636,17 +2656,25 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls"
|
name = "rustls"
|
||||||
version = "0.19.1"
|
version = "0.20.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7"
|
checksum = "d37e5e2290f3e040b594b1a9e04377c2c671f1a1cfd9bfdef82106ac1c113f84"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.13.0",
|
|
||||||
"log",
|
"log",
|
||||||
"ring",
|
"ring",
|
||||||
"sct",
|
"sct",
|
||||||
"webpki",
|
"webpki",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls-pemfile"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5eebeaeb360c87bfb72e84abdb3447159c0eaececf1bef2aecd65a8be949d1c9"
|
||||||
|
dependencies = [
|
||||||
|
"base64 0.13.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustversion"
|
name = "rustversion"
|
||||||
version = "1.0.5"
|
version = "1.0.5"
|
||||||
|
@ -2692,9 +2720,9 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sct"
|
name = "sct"
|
||||||
version = "0.6.1"
|
version = "0.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce"
|
checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ring",
|
"ring",
|
||||||
"untrusted",
|
"untrusted",
|
||||||
|
@ -2764,9 +2792,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.130"
|
version = "1.0.136"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913"
|
checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
@ -2782,9 +2810,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.130"
|
version = "1.0.136"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b"
|
checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.32",
|
"proc-macro2 1.0.32",
|
||||||
"quote 1.0.10",
|
"quote 1.0.10",
|
||||||
|
@ -2793,11 +2821,11 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.71"
|
version = "1.0.78"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "063bf466a64011ac24040a49009724ee60a57da1b437617ceb32e53ad61bfb19"
|
checksum = "d23c1ba4cf0efd44be32017709280b32d1cea5c3f1275c3b6d9e8bc54f758085"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa 1.0.1",
|
||||||
"ryu",
|
"ryu",
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
@ -2809,7 +2837,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9"
|
checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"form_urlencoded",
|
"form_urlencoded",
|
||||||
"itoa",
|
"itoa 0.4.8",
|
||||||
"ryu",
|
"ryu",
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
@ -2846,7 +2874,7 @@ dependencies = [
|
||||||
"arrayref",
|
"arrayref",
|
||||||
"bincode",
|
"bincode",
|
||||||
"bs58 0.3.1",
|
"bs58 0.3.1",
|
||||||
"rand 0.7.3",
|
"rand",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serum-borsh",
|
"serum-borsh",
|
||||||
|
@ -3099,7 +3127,7 @@ dependencies = [
|
||||||
"either",
|
"either",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"libc",
|
"libc",
|
||||||
"rand_chacha 0.2.2",
|
"rand_chacha",
|
||||||
"regex-syntax",
|
"regex-syntax",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"ring",
|
"ring",
|
||||||
|
@ -3219,7 +3247,7 @@ dependencies = [
|
||||||
"clap 2.33.3",
|
"clap 2.33.3",
|
||||||
"log",
|
"log",
|
||||||
"nix",
|
"nix",
|
||||||
"rand 0.7.3",
|
"rand",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
"socket2 0.3.19",
|
"socket2 0.3.19",
|
||||||
|
@ -3246,7 +3274,7 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
"nix",
|
"nix",
|
||||||
"rand 0.7.3",
|
"rand",
|
||||||
"rayon",
|
"rayon",
|
||||||
"serde",
|
"serde",
|
||||||
"solana-logger",
|
"solana-logger",
|
||||||
|
@ -3278,7 +3306,7 @@ dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"num-derive",
|
"num-derive",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"rand 0.7.3",
|
"rand",
|
||||||
"rustc_version 0.2.3",
|
"rustc_version 0.2.3",
|
||||||
"rustversion",
|
"rustversion",
|
||||||
"serde",
|
"serde",
|
||||||
|
@ -3311,7 +3339,7 @@ checksum = "82b91d441ed00427226b08e9990367ecb4c952c70ab827c0250bd233e1ae9540"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base32",
|
"base32",
|
||||||
"console 0.14.1",
|
"console 0.14.1",
|
||||||
"dialoguer",
|
"dialoguer 0.6.2",
|
||||||
"hidapi",
|
"hidapi",
|
||||||
"log",
|
"log",
|
||||||
"num-derive",
|
"num-derive",
|
||||||
|
@ -3351,7 +3379,7 @@ dependencies = [
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
"ouroboros",
|
"ouroboros",
|
||||||
"rand 0.7.3",
|
"rand",
|
||||||
"rayon",
|
"rayon",
|
||||||
"regex",
|
"regex",
|
||||||
"rustc_version 0.2.3",
|
"rustc_version 0.2.3",
|
||||||
|
@ -3409,8 +3437,8 @@ dependencies = [
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"pbkdf2 0.6.0",
|
"pbkdf2 0.6.0",
|
||||||
"qstring",
|
"qstring",
|
||||||
"rand 0.7.3",
|
"rand",
|
||||||
"rand_chacha 0.2.2",
|
"rand_chacha",
|
||||||
"rand_core 0.6.3",
|
"rand_core 0.6.3",
|
||||||
"rustc_version 0.2.3",
|
"rustc_version 0.2.3",
|
||||||
"rustversion",
|
"rustversion",
|
||||||
|
@ -3675,13 +3703,13 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tempfile"
|
name = "tempfile"
|
||||||
version = "3.2.0"
|
version = "3.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22"
|
checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
|
"fastrand",
|
||||||
"libc",
|
"libc",
|
||||||
"rand 0.8.4",
|
|
||||||
"redox_syscall 0.2.10",
|
"redox_syscall 0.2.10",
|
||||||
"remove_dir_all",
|
"remove_dir_all",
|
||||||
"winapi",
|
"winapi",
|
||||||
|
@ -3770,7 +3798,7 @@ dependencies = [
|
||||||
"hmac 0.8.1",
|
"hmac 0.8.1",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"pbkdf2 0.4.0",
|
"pbkdf2 0.4.0",
|
||||||
"rand 0.7.3",
|
"rand",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
"sha2",
|
"sha2",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
@ -3837,9 +3865,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-rustls"
|
name = "tokio-rustls"
|
||||||
version = "0.22.0"
|
version = "0.23.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6"
|
checksum = "a27d5f2b839802bd8267fa19b0530f5a08b9c08cd417976be2a65d130fe1c11b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rustls",
|
"rustls",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
@ -3915,7 +3943,7 @@ dependencies = [
|
||||||
"input_buffer",
|
"input_buffer",
|
||||||
"log",
|
"log",
|
||||||
"native-tls",
|
"native-tls",
|
||||||
"rand 0.7.3",
|
"rand",
|
||||||
"sha-1",
|
"sha-1",
|
||||||
"url",
|
"url",
|
||||||
"utf-8",
|
"utf-8",
|
||||||
|
@ -4144,9 +4172,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "webpki"
|
name = "webpki"
|
||||||
version = "0.21.4"
|
version = "0.22.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea"
|
checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ring",
|
"ring",
|
||||||
"untrusted",
|
"untrusted",
|
||||||
|
@ -4154,9 +4182,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "webpki-roots"
|
name = "webpki-roots"
|
||||||
version = "0.21.1"
|
version = "0.22.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "aabe153544e473b775453675851ecc86863d2a81d786d741f6b76778f2a48940"
|
checksum = "552ceb903e957524388c4d3475725ff2c8b7960922063af6ce53c9a43da07449"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"webpki",
|
"webpki",
|
||||||
]
|
]
|
||||||
|
|
|
@ -6,6 +6,7 @@ codegen-units = 1
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = [
|
members = [
|
||||||
|
"avm",
|
||||||
"cli",
|
"cli",
|
||||||
"client",
|
"client",
|
||||||
"lang",
|
"lang",
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
[package]
|
||||||
|
name = "avm"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "avm"
|
||||||
|
path = "src/main.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "anchor"
|
||||||
|
path = "src/anchor/main.rs"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
clap = { version = "3.0.13", features = [ "derive" ]}
|
||||||
|
cfg-if = "1.0.0"
|
||||||
|
anyhow = "1.0.32"
|
||||||
|
dialoguer = "0.9.0"
|
||||||
|
dirs = "4.0"
|
||||||
|
semver = "1.0.4"
|
||||||
|
serde = { version = "1.0.136", features = [ "derive" ]}
|
||||||
|
serde_json = "1.0.78"
|
||||||
|
thiserror = "1.0.30"
|
||||||
|
once_cell = { version = "1.8.0" }
|
||||||
|
reqwest = { version = "0.11.9", features = ['blocking', 'json'] }
|
||||||
|
tempfile = "3.3.0"
|
|
@ -0,0 +1,24 @@
|
||||||
|
use std::{env, fs, process::Command};
|
||||||
|
|
||||||
|
fn main() -> anyhow::Result<()> {
|
||||||
|
let args = env::args().skip(1).collect::<Vec<String>>();
|
||||||
|
|
||||||
|
let version = avm::current_version()
|
||||||
|
.map_err(|_e| anyhow::anyhow!("Anchor version not set. Please run `avm use latest`."))?;
|
||||||
|
|
||||||
|
let binary_path = avm::version_binary_path(&version);
|
||||||
|
if fs::metadata(&binary_path).is_err() {
|
||||||
|
anyhow::bail!(
|
||||||
|
"anchor-cli {} not installed. Please run `avm use {}`.",
|
||||||
|
version,
|
||||||
|
version
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Command::new(binary_path)
|
||||||
|
.args(args)
|
||||||
|
.spawn()?
|
||||||
|
.wait_with_output()
|
||||||
|
.expect("Failed to run anchor-cli");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
|
@ -0,0 +1,287 @@
|
||||||
|
use anyhow::{anyhow, Result};
|
||||||
|
use dialoguer::Input;
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
|
use reqwest::header::USER_AGENT;
|
||||||
|
use semver::Version;
|
||||||
|
use serde::{de, Deserialize};
|
||||||
|
use std::fs;
|
||||||
|
use std::io::Write;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use std::process::Stdio;
|
||||||
|
|
||||||
|
/// Storage directory for AVM, ~/.avm
|
||||||
|
pub static AVM_HOME: Lazy<PathBuf> = Lazy::new(|| {
|
||||||
|
cfg_if::cfg_if! {
|
||||||
|
if #[cfg(test)] {
|
||||||
|
let dir = tempfile::tempdir().expect("Could not create temporary directory");
|
||||||
|
dir.path().join(".avm")
|
||||||
|
} else {
|
||||||
|
let mut user_home = dirs::home_dir().expect("Could not find home directory");
|
||||||
|
user_home.push(".avm");
|
||||||
|
user_home
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/// Path to the current version file ~/.avm/.version
|
||||||
|
pub fn current_version_file_path() -> PathBuf {
|
||||||
|
let mut current_version_file_path = AVM_HOME.to_path_buf();
|
||||||
|
current_version_file_path.push(".version");
|
||||||
|
current_version_file_path
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Read the current version from the version file
|
||||||
|
pub fn current_version() -> Result<Version> {
|
||||||
|
let v = fs::read_to_string(current_version_file_path().as_path())
|
||||||
|
.map_err(|e| anyhow!("Could not read version file: {}", e))?;
|
||||||
|
Version::parse(v.trim_end_matches('\n').to_string().as_str())
|
||||||
|
.map_err(|e| anyhow!("Could not parse version file: {}", e))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Path to the binary for the given version
|
||||||
|
pub fn version_binary_path(version: &Version) -> PathBuf {
|
||||||
|
let mut version_path = AVM_HOME.join("bin");
|
||||||
|
version_path.push(format!("anchor-{}", version));
|
||||||
|
version_path
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Update the current version to a new version
|
||||||
|
pub fn use_version(version: &Version) -> Result<()> {
|
||||||
|
let installed_versions = read_installed_versions();
|
||||||
|
// Make sure the requested version is installed
|
||||||
|
if !installed_versions.contains(version) {
|
||||||
|
let input: String = Input::new()
|
||||||
|
.with_prompt(format!(
|
||||||
|
"anchor-cli {} is not installed, would you like to install it? (y/n)",
|
||||||
|
version
|
||||||
|
))
|
||||||
|
.with_initial_text("y")
|
||||||
|
.default("n".into())
|
||||||
|
.interact_text()?;
|
||||||
|
if matches!(input.as_str(), "y" | "yy" | "Y" | "yes" | "Yes") {
|
||||||
|
install_version(version)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut current_version_file = fs::File::create(current_version_file_path().as_path())?;
|
||||||
|
current_version_file.write_all(version.to_string().as_bytes())?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Install a version of anchor-cli
|
||||||
|
pub fn install_version(version: &Version) -> Result<()> {
|
||||||
|
let exit = std::process::Command::new("cargo")
|
||||||
|
.args(&[
|
||||||
|
"install",
|
||||||
|
"--git",
|
||||||
|
"https://github.com/project-serum/anchor",
|
||||||
|
"--tag",
|
||||||
|
&format!("v{}", &version),
|
||||||
|
"anchor-cli",
|
||||||
|
"--locked",
|
||||||
|
"--root",
|
||||||
|
AVM_HOME.to_str().unwrap(),
|
||||||
|
])
|
||||||
|
.stdout(Stdio::inherit())
|
||||||
|
.stderr(Stdio::inherit())
|
||||||
|
.output()
|
||||||
|
.map_err(|e| {
|
||||||
|
anyhow::format_err!("Cargo install for {} failed: {}", version, e.to_string())
|
||||||
|
})?;
|
||||||
|
if !exit.status.success() {
|
||||||
|
return Err(anyhow!(
|
||||||
|
"Failed to install {}, is it a valid version?",
|
||||||
|
version
|
||||||
|
));
|
||||||
|
}
|
||||||
|
fs::rename(
|
||||||
|
&AVM_HOME.join("bin").join("anchor"),
|
||||||
|
&AVM_HOME.join("bin").join(format!("anchor-{}", version)),
|
||||||
|
)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Remove an installed version of anchor-cli
|
||||||
|
pub fn uninstall_version(version: &Version) -> Result<()> {
|
||||||
|
let version_path = AVM_HOME.join("bin").join(format!("anchor-{}", version));
|
||||||
|
if !version_path.exists() {
|
||||||
|
return Err(anyhow!("anchor-cli {} is not installed", version));
|
||||||
|
}
|
||||||
|
if version == ¤t_version().unwrap() {
|
||||||
|
return Err(anyhow!("anchor-cli {} is currently in use", version));
|
||||||
|
}
|
||||||
|
fs::remove_file(version_path.as_path())?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Ensure the users home directory is setup with the paths required by AVM.
|
||||||
|
pub fn ensure_paths() {
|
||||||
|
let home_dir = AVM_HOME.to_path_buf();
|
||||||
|
if !home_dir.as_path().exists() {
|
||||||
|
fs::create_dir_all(home_dir.clone()).expect("Could not create .avm directory");
|
||||||
|
}
|
||||||
|
let bin_dir = home_dir.join("bin");
|
||||||
|
if !bin_dir.as_path().exists() {
|
||||||
|
fs::create_dir_all(bin_dir).expect("Could not create .avm/bin directory");
|
||||||
|
}
|
||||||
|
if !current_version_file_path().exists() {
|
||||||
|
fs::File::create(current_version_file_path()).expect("Could not create .version file");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Retrieve a list of installable versions of anchor-cli using the GitHub API and tags on the Anchor
|
||||||
|
/// repository.
|
||||||
|
pub fn fetch_versions() -> Vec<semver::Version> {
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct Release {
|
||||||
|
#[serde(rename = "name", deserialize_with = "version_deserializer")]
|
||||||
|
version: semver::Version,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn version_deserializer<'de, D>(deserializer: D) -> Result<semver::Version, D::Error>
|
||||||
|
where
|
||||||
|
D: de::Deserializer<'de>,
|
||||||
|
{
|
||||||
|
let s: &str = de::Deserialize::deserialize(deserializer)?;
|
||||||
|
Version::parse(s.trim_start_matches('v')).map_err(de::Error::custom)
|
||||||
|
}
|
||||||
|
|
||||||
|
let client = reqwest::blocking::Client::new();
|
||||||
|
let versions: Vec<Release> = client
|
||||||
|
.get("https://api.github.com/repos/project-serum/anchor/tags")
|
||||||
|
.header(USER_AGENT, "avm https://github.com/project-serum/anchor")
|
||||||
|
.send()
|
||||||
|
.unwrap()
|
||||||
|
.json()
|
||||||
|
.unwrap();
|
||||||
|
versions.into_iter().map(|r| r.version).collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Print available versions and flags indicating installed, current and latest
|
||||||
|
pub fn list_versions() -> Result<()> {
|
||||||
|
let installed_versions = read_installed_versions();
|
||||||
|
|
||||||
|
let mut available_versions = fetch_versions();
|
||||||
|
// Reverse version list so latest versions are printed last
|
||||||
|
available_versions.reverse();
|
||||||
|
|
||||||
|
available_versions.iter().enumerate().for_each(|(i, v)| {
|
||||||
|
print!("{}", v);
|
||||||
|
let mut flags = vec![];
|
||||||
|
if i == available_versions.len() - 1 {
|
||||||
|
flags.push("latest");
|
||||||
|
}
|
||||||
|
if installed_versions.contains(v) {
|
||||||
|
flags.push("installed");
|
||||||
|
}
|
||||||
|
if current_version().unwrap() == v.clone() {
|
||||||
|
flags.push("current");
|
||||||
|
}
|
||||||
|
if flags.is_empty() {
|
||||||
|
println!();
|
||||||
|
} else {
|
||||||
|
println!("\t({})", flags.join(", "));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_latest_version() -> semver::Version {
|
||||||
|
let available_versions = fetch_versions();
|
||||||
|
available_versions.first().unwrap().clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Read the installed anchor-cli versions by reading the binaries in the AVM_HOME/bin directory.
|
||||||
|
pub fn read_installed_versions() -> Vec<semver::Version> {
|
||||||
|
let home_dir = AVM_HOME.to_path_buf();
|
||||||
|
let mut versions = vec![];
|
||||||
|
for file in fs::read_dir(&home_dir.join("bin")).unwrap() {
|
||||||
|
let file_name = file.unwrap().file_name();
|
||||||
|
// Match only things that look like anchor-*
|
||||||
|
if file_name.to_str().unwrap().starts_with("anchor-") {
|
||||||
|
let version = file_name
|
||||||
|
.to_str()
|
||||||
|
.unwrap()
|
||||||
|
.trim_start_matches("anchor-")
|
||||||
|
.parse::<semver::Version>()
|
||||||
|
.unwrap();
|
||||||
|
versions.push(version);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
versions
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::*;
|
||||||
|
use semver::Version;
|
||||||
|
use std::fs;
|
||||||
|
use std::io::Write;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_ensure_paths() {
|
||||||
|
ensure_paths();
|
||||||
|
assert!(AVM_HOME.exists());
|
||||||
|
let bin_dir = AVM_HOME.join("bin");
|
||||||
|
assert!(bin_dir.exists());
|
||||||
|
let current_version_file = AVM_HOME.join(".version");
|
||||||
|
assert!(current_version_file.exists());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_current_version_file_path() {
|
||||||
|
ensure_paths();
|
||||||
|
assert!(current_version_file_path().exists());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_version_binary_path() {
|
||||||
|
assert!(
|
||||||
|
version_binary_path(&Version::parse("0.18.2").unwrap())
|
||||||
|
== AVM_HOME.join("bin/anchor-0.18.2")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_current_version() {
|
||||||
|
ensure_paths();
|
||||||
|
let mut current_version_file =
|
||||||
|
fs::File::create(current_version_file_path().as_path()).unwrap();
|
||||||
|
current_version_file.write_all("0.18.2".as_bytes()).unwrap();
|
||||||
|
assert!(current_version().unwrap() == Version::parse("0.18.2").unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic(expected = "anchor-cli 0.18.1 is not installed")]
|
||||||
|
fn test_uninstall_non_installed_version() {
|
||||||
|
uninstall_version(&Version::parse("0.18.1").unwrap()).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic(expected = "anchor-cli 0.18.2 is currently in use")]
|
||||||
|
fn test_uninstalled_in_use_version() {
|
||||||
|
ensure_paths();
|
||||||
|
let version = Version::parse("0.18.2").unwrap();
|
||||||
|
let mut current_version_file =
|
||||||
|
fs::File::create(current_version_file_path().as_path()).unwrap();
|
||||||
|
current_version_file.write_all("0.18.2".as_bytes()).unwrap();
|
||||||
|
// Create a fake binary for anchor-0.18.2 in the bin directory
|
||||||
|
fs::File::create(version_binary_path(&version)).unwrap();
|
||||||
|
uninstall_version(&version).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_read_installed_versions() {
|
||||||
|
ensure_paths();
|
||||||
|
let version = Version::parse("0.18.2").unwrap();
|
||||||
|
// Create a fake binary for anchor-0.18.2 in the bin directory
|
||||||
|
fs::File::create(version_binary_path(&version)).unwrap();
|
||||||
|
let expected = vec![version];
|
||||||
|
assert!(read_installed_versions() == expected);
|
||||||
|
// Should ignore this file because its not anchor- prefixed
|
||||||
|
fs::File::create(AVM_HOME.join("bin").join("garbage").as_path()).unwrap();
|
||||||
|
assert!(read_installed_versions() == expected);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
use anyhow::{Error, Result};
|
||||||
|
use clap::{Parser, Subcommand};
|
||||||
|
use semver::Version;
|
||||||
|
|
||||||
|
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||||
|
|
||||||
|
#[derive(Parser)]
|
||||||
|
#[clap(name = "avm", about = "Anchor version manager")]
|
||||||
|
pub struct Cli {
|
||||||
|
#[clap(subcommand)]
|
||||||
|
command: Commands,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Subcommand)]
|
||||||
|
pub enum Commands {
|
||||||
|
#[clap(about = "Use a specific version of Anchor")]
|
||||||
|
Use {
|
||||||
|
#[clap(parse(try_from_str = parse_version))]
|
||||||
|
version: Version,
|
||||||
|
},
|
||||||
|
#[clap(about = "Install a version of Anchor")]
|
||||||
|
Install {
|
||||||
|
#[clap(parse(try_from_str = parse_version))]
|
||||||
|
version: Version,
|
||||||
|
},
|
||||||
|
#[clap(about = "Uninstall a version of Anchor")]
|
||||||
|
Uninstall {
|
||||||
|
#[clap(parse(try_from_str = parse_version))]
|
||||||
|
version: Version,
|
||||||
|
},
|
||||||
|
#[clap(about = "List available versions of Anchor")]
|
||||||
|
List {},
|
||||||
|
}
|
||||||
|
|
||||||
|
// If `latest` is passed use the latest available version.
|
||||||
|
fn parse_version(version: &str) -> Result<Version, Error> {
|
||||||
|
if version == "latest" {
|
||||||
|
Ok(avm::get_latest_version())
|
||||||
|
} else {
|
||||||
|
Version::parse(version).map_err(|e| anyhow::anyhow!(e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn entry(opts: Cli) -> Result<()> {
|
||||||
|
match opts.command {
|
||||||
|
Commands::Use { version } => avm::use_version(&version),
|
||||||
|
Commands::Install { version } => avm::install_version(&version),
|
||||||
|
Commands::Uninstall { version } => avm::uninstall_version(&version),
|
||||||
|
Commands::List {} => avm::list_versions(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> Result<()> {
|
||||||
|
// Make sure the user's home directory is setup with the paths required by AVM.
|
||||||
|
avm::ensure_paths();
|
||||||
|
|
||||||
|
let opt = Cli::parse();
|
||||||
|
entry(opt)
|
||||||
|
}
|
Loading…
Reference in New Issue