1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
//! Error type shared by the library and the CLI.
use std::path::PathBuf;
use thiserror::Error;
use crate::shell::Shell;
/// Convenience alias for [`Result`] using [`enum@Error`].
pub type Result<T, E = Error> = std::result::Result<T, E>;
/// Every way in which `eish` can fail.
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum Error {
/// The `--shell` value could not be recognised.
#[error("unknown shell `{input}` (expected one of: {expected})")]
UnknownShell {
/// The value that was supplied.
input: String,
/// Comma separated list of accepted values.
expected: &'static str,
},
/// The `--proxy` value could not be recognised.
#[error("unknown proxy `{input}` (expected one of: {expected})")]
UnknownProxy {
/// The value that was supplied.
input: String,
/// Comma separated list of accepted values.
expected: &'static str,
},
/// The positional `owner/repo[@tag]` argument could not be parsed.
#[error(
"invalid repository spec `{input}` (expected `<owner>/<repo>` or `<owner>/<repo>@<tag>`)"
)]
InvalidSpec {
/// The value that was supplied.
input: String,
},
/// The release requested by the user does not exist (or is not published).
#[error("no release found for {repo} (tag: {tag})")]
ReleaseNotFound {
/// `owner/repo`.
repo: String,
/// The requested tag, or `latest`.
tag: String,
},
/// None of the files attached to the release look like prebuilt binaries.
#[error(
"release {repo} (tag: {tag}) has no assets matching a known Rust target triple; \
use `--target`/`--binary` or check that the release publishes binaries"
)]
NoAssets {
/// `owner/repo`.
repo: String,
/// The resolved tag.
tag: String,
},
/// A proxy was selected that cannot serve GitHub release assets.
#[error(
"proxy `{proxy}` cannot serve GitHub release assets; use `github`, `gh-proxy` or `xget`, \
or switch to `--type file`"
)]
UnsupportedProxy {
/// The offending proxy name.
proxy: &'static str,
},
/// A target triple was requested that the release does not publish.
#[error("no asset for target `{target}`; available targets: {available}")]
UnknownTarget {
/// The target triple that was requested.
target: String,
/// Space separated list of targets that *are* available.
available: String,
},
/// A program name was requested that the release does not publish.
#[error("no assets for `{name}` in this release; available programs: {available}")]
UnknownProgram {
/// The name that was requested.
name: String,
/// Space separated list of program names that *are* available.
available: String,
},
/// The release publishes several programs and none was chosen.
#[error(
"{repo} publishes {} programs and an installer installs only one\n \
choose one with --name: {}",
programs.len(),
programs.join(", ")
)]
AmbiguousProgram {
/// `owner/repo`.
repo: String,
/// The programs on offer, best-covered first.
programs: Vec<String>,
},
/// The GitHub API answered, but with an error status we can explain.
#[error("GitHub API request to {url} failed with HTTP {status}: {hint}")]
ApiStatus {
/// The status code that was returned.
status: u16,
/// The URL that was requested.
url: String,
/// A short explanation of the most likely cause.
hint: &'static str,
},
/// The GitHub API request failed.
#[error("failed to query {url}: {source}")]
Http {
/// The URL that was requested.
url: String,
/// The underlying transport error.
#[source]
source: Box<ureq::Error>,
},
/// The GitHub API returned something we could not decode.
#[error("failed to decode GitHub API response: {source}")]
Decode {
/// The underlying JSON error.
#[source]
source: serde_json::Error,
},
/// A JSON file could not be read.
#[error("failed to read {path}: {source}")]
ReadFile {
/// The path that was read.
path: PathBuf,
/// The underlying I/O error.
#[source]
source: std::io::Error,
},
/// The generated script could not be written to disk.
#[error("failed to write {path}: {source}")]
WriteFile {
/// The path that was written.
path: PathBuf,
/// The underlying I/O error.
#[source]
source: std::io::Error,
},
/// Rendering the installer template failed.
#[error("failed to render the {shell} installer: {source}")]
Render {
/// The shell whose template failed.
shell: Shell,
/// The underlying template error.
#[source]
source: minijinja::Error,
},
}