Skip to content

Commit 68b1cfa

Browse files
authored
Merge pull request #207 from epage/ci
fix: Don't write to tmpdir in CI
2 parents 54f0af0 + f23f43e commit 68b1cfa

File tree

6 files changed

+383
-247
lines changed

6 files changed

+383
-247
lines changed

src/lib.rs

Lines changed: 8 additions & 239 deletions
Original file line numberDiff line numberDiff line change
@@ -48,75 +48,15 @@
4848
#[cfg(doctest)]
4949
pub struct ReadmeDoctests;
5050

51-
pub mod report;
52-
use report::{Method, Report};
53-
54-
use std::borrow::Cow;
55-
use std::io::Result as IoResult;
56-
use std::panic::PanicHookInfo;
57-
use std::path::{Path, PathBuf};
58-
59-
/// A convenient metadata struct that describes a crate
60-
///
61-
/// See [`metadata!`]
62-
pub struct Metadata {
63-
name: Cow<'static, str>,
64-
version: Cow<'static, str>,
65-
authors: Option<Cow<'static, str>>,
66-
homepage: Option<Cow<'static, str>>,
67-
repository: Option<Cow<'static, str>>,
68-
support: Option<Cow<'static, str>>,
69-
}
70-
71-
impl Metadata {
72-
/// See [`metadata!`]
73-
pub fn new(name: impl Into<Cow<'static, str>>, version: impl Into<Cow<'static, str>>) -> Self {
74-
Self {
75-
name: name.into(),
76-
version: version.into(),
77-
authors: None,
78-
homepage: None,
79-
repository: None,
80-
support: None,
81-
}
82-
}
51+
mod metadata;
52+
mod panic;
8353

84-
/// The list of authors of the crate
85-
pub fn authors(mut self, value: impl Into<Cow<'static, str>>) -> Self {
86-
let value = value.into();
87-
if !value.is_empty() {
88-
self.authors = value.into();
89-
}
90-
self
91-
}
92-
93-
/// The URL of the crate's website
94-
pub fn homepage(mut self, value: impl Into<Cow<'static, str>>) -> Self {
95-
let value = value.into();
96-
if !value.is_empty() {
97-
self.homepage = value.into();
98-
}
99-
self
100-
}
101-
102-
/// The URL of the crate's repository
103-
pub fn repository(mut self, value: impl Into<Cow<'static, str>>) -> Self {
104-
let value = value.into();
105-
if !value.is_empty() {
106-
self.repository = value.into();
107-
}
108-
self
109-
}
110-
111-
/// The support information
112-
pub fn support(mut self, value: impl Into<Cow<'static, str>>) -> Self {
113-
let value = value.into();
114-
if !value.is_empty() {
115-
self.support = value.into();
116-
}
117-
self
118-
}
119-
}
54+
pub mod report;
55+
pub use metadata::Metadata;
56+
pub use panic::PanicStyle;
57+
pub use panic::handle_dump;
58+
pub use panic::print_msg;
59+
pub use panic::setup_panic;
12060

12161
/// Initialize [`Metadata`]
12262
#[macro_export]
@@ -161,174 +101,3 @@ macro_rules! setup_panic {
161101
$crate::setup_panic!($crate::metadata!());
162102
};
163103
}
164-
165-
#[doc(hidden)]
166-
pub fn setup_panic(meta: impl Fn() -> Metadata) {
167-
#![allow(deprecated)]
168-
169-
#[allow(unused_imports)]
170-
use std::panic;
171-
172-
match PanicStyle::default() {
173-
PanicStyle::Debug => {}
174-
PanicStyle::Human => {
175-
let meta = meta();
176-
177-
panic::set_hook(Box::new(move |info: &PanicHookInfo<'_>| {
178-
let file_path = handle_dump(&meta, info);
179-
print_msg(file_path, &meta)
180-
.expect("human-panic: printing error message to console failed");
181-
}));
182-
}
183-
}
184-
}
185-
186-
/// Style of panic to be used
187-
#[non_exhaustive]
188-
#[derive(Copy, Clone, PartialEq, Eq)]
189-
pub enum PanicStyle {
190-
/// Normal panic
191-
Debug,
192-
/// Human-formatted panic
193-
Human,
194-
}
195-
196-
impl Default for PanicStyle {
197-
fn default() -> Self {
198-
if cfg!(debug_assertions) {
199-
PanicStyle::Debug
200-
} else {
201-
match ::std::env::var("RUST_BACKTRACE") {
202-
Ok(_) => PanicStyle::Debug,
203-
Err(_) => PanicStyle::Human,
204-
}
205-
}
206-
}
207-
}
208-
209-
/// Utility function that prints a message to our human users
210-
#[cfg(feature = "color")]
211-
pub fn print_msg<P: AsRef<Path>>(file_path: Option<P>, meta: &Metadata) -> IoResult<()> {
212-
use std::io::Write as _;
213-
214-
let stderr = anstream::stderr();
215-
let mut stderr = stderr.lock();
216-
217-
write!(stderr, "{}", anstyle::AnsiColor::Red.render_fg())?;
218-
write_msg(&mut stderr, file_path, meta)?;
219-
write!(stderr, "{}", anstyle::Reset.render())?;
220-
221-
Ok(())
222-
}
223-
224-
#[cfg(not(feature = "color"))]
225-
pub fn print_msg<P: AsRef<Path>>(file_path: Option<P>, meta: &Metadata) -> IoResult<()> {
226-
let stderr = std::io::stderr();
227-
let mut stderr = stderr.lock();
228-
229-
write_msg(&mut stderr, file_path, meta)?;
230-
231-
Ok(())
232-
}
233-
234-
fn write_msg<P: AsRef<Path>>(
235-
buffer: &mut impl std::io::Write,
236-
file_path: Option<P>,
237-
meta: &Metadata,
238-
) -> IoResult<()> {
239-
let Metadata {
240-
name,
241-
authors,
242-
homepage,
243-
repository,
244-
support,
245-
..
246-
} = meta;
247-
248-
writeln!(buffer, "Well, this is embarrassing.\n")?;
249-
writeln!(
250-
buffer,
251-
"{name} had a problem and crashed. To help us diagnose the \
252-
problem you can send us a crash report.\n"
253-
)?;
254-
writeln!(
255-
buffer,
256-
"We have generated a report file at \"{}\". Submit an \
257-
issue or email with the subject of \"{} Crash Report\" and include the \
258-
report as an attachment.\n",
259-
match file_path {
260-
Some(fp) => format!("{}", fp.as_ref().display()),
261-
None => "<Failed to store file to disk>".to_owned(),
262-
},
263-
name
264-
)?;
265-
266-
if let Some(homepage) = homepage {
267-
writeln!(buffer, "- Homepage: {homepage}")?;
268-
} else if let Some(repository) = repository {
269-
writeln!(buffer, "- Repository: {repository}")?;
270-
}
271-
if let Some(authors) = authors {
272-
writeln!(buffer, "- Authors: {authors}")?;
273-
}
274-
if let Some(support) = support {
275-
writeln!(buffer, "\nTo submit the crash report:\n\n{support}")?;
276-
}
277-
writeln!(
278-
buffer,
279-
"\nWe take privacy seriously, and do not perform any \
280-
automated error collection. In order to improve the software, we rely on \
281-
people to submit reports.\n"
282-
)?;
283-
writeln!(buffer, "Thank you kindly!")?;
284-
285-
Ok(())
286-
}
287-
288-
/// Utility function which will handle dumping information to disk
289-
#[allow(deprecated)]
290-
pub fn handle_dump(meta: &Metadata, panic_info: &PanicHookInfo<'_>) -> Option<PathBuf> {
291-
let mut expl = String::new();
292-
293-
let message = match (
294-
panic_info.payload().downcast_ref::<&str>(),
295-
panic_info.payload().downcast_ref::<String>(),
296-
) {
297-
(Some(s), _) => Some((*s).to_owned()),
298-
(_, Some(s)) => Some(s.to_owned()),
299-
(None, None) => None,
300-
};
301-
302-
let cause = match message {
303-
Some(m) => m,
304-
None => "Unknown".into(),
305-
};
306-
307-
match panic_info.location() {
308-
Some(location) => expl.push_str(&format!(
309-
"Panic occurred in file '{}' at line {}\n",
310-
location.file(),
311-
location.line()
312-
)),
313-
None => expl.push_str("Panic location unknown.\n"),
314-
}
315-
316-
let report = Report::new(&meta.name, &meta.version, Method::Panic, expl, cause);
317-
318-
if let Ok(f) = report.persist() {
319-
Some(f)
320-
} else {
321-
use std::io::Write as _;
322-
let stderr = std::io::stderr();
323-
let mut stderr = stderr.lock();
324-
325-
let _ = writeln!(
326-
stderr,
327-
"{}",
328-
report
329-
.serialize()
330-
.expect("only doing toml compatible types")
331-
);
332-
None
333-
}
334-
}

src/metadata.rs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
use std::borrow::Cow;
2+
3+
/// A convenient metadata struct that describes a crate
4+
///
5+
/// See [`metadata!`][crate::metadata!]
6+
pub struct Metadata {
7+
pub(crate) name: Cow<'static, str>,
8+
pub(crate) version: Cow<'static, str>,
9+
pub(crate) authors: Option<Cow<'static, str>>,
10+
pub(crate) homepage: Option<Cow<'static, str>>,
11+
pub(crate) repository: Option<Cow<'static, str>>,
12+
pub(crate) support: Option<Cow<'static, str>>,
13+
}
14+
15+
impl Metadata {
16+
/// See [`metadata!`][crate::metadata!]
17+
pub fn new(name: impl Into<Cow<'static, str>>, version: impl Into<Cow<'static, str>>) -> Self {
18+
Self {
19+
name: name.into(),
20+
version: version.into(),
21+
authors: None,
22+
homepage: None,
23+
repository: None,
24+
support: None,
25+
}
26+
}
27+
28+
/// The list of authors of the crate
29+
pub fn authors(mut self, value: impl Into<Cow<'static, str>>) -> Self {
30+
let value = value.into();
31+
if !value.is_empty() {
32+
self.authors = value.into();
33+
}
34+
self
35+
}
36+
37+
/// The URL of the crate's website
38+
pub fn homepage(mut self, value: impl Into<Cow<'static, str>>) -> Self {
39+
let value = value.into();
40+
if !value.is_empty() {
41+
self.homepage = value.into();
42+
}
43+
self
44+
}
45+
46+
/// The URL of the crate's repository
47+
pub fn repository(mut self, value: impl Into<Cow<'static, str>>) -> Self {
48+
let value = value.into();
49+
if !value.is_empty() {
50+
self.repository = value.into();
51+
}
52+
self
53+
}
54+
55+
/// The support information
56+
pub fn support(mut self, value: impl Into<Cow<'static, str>>) -> Self {
57+
let value = value.into();
58+
if !value.is_empty() {
59+
self.support = value.into();
60+
}
61+
self
62+
}
63+
}

0 commit comments

Comments
 (0)