1 use crate::errors::{HgError, HgResultExt, IoErrorContext, IoResultExt}; |
1 use crate::errors::{HgError, HgResultExt, IoErrorContext, IoResultExt}; |
2 use crate::vfs::VfsImpl; |
2 use crate::vfs::{Vfs, VfsImpl}; |
3 use std::io::Write; |
3 use std::io::Write; |
|
4 use std::path::Path; |
4 |
5 |
5 /// An utility to append to a log file with the given name, and optionally |
6 /// An utility to append to a log file with the given name, and optionally |
6 /// rotate it after it reaches a certain maximum size. |
7 /// rotate it after it reaches a certain maximum size. |
7 /// |
8 /// |
8 /// Rotation works by renaming "example.log" to "example.log.1", after renaming |
9 /// Rotation works by renaming "example.log" to "example.log.1", after renaming |
62 // The last iteration renames `{name}.1` to |
63 // The last iteration renames `{name}.1` to |
63 // `{name}.2` |
64 // `{name}.2` |
64 for i in (1..self.max_files).rev() { |
65 for i in (1..self.max_files).rev() { |
65 self.vfs |
66 self.vfs |
66 .rename( |
67 .rename( |
67 format!("{}.{}", self.name, i), |
68 Path::new(&format!("{}.{}", self.name, i)), |
68 format!("{}.{}", self.name, i + 1), |
69 Path::new(&format!("{}.{}", self.name, i + 1)), |
|
70 false, |
69 ) |
71 ) |
70 .io_not_found_as_none()?; |
72 .io_not_found_as_none()?; |
71 } |
73 } |
72 // Then rename `{name}` to `{name}.1`. This is the |
74 // Then rename `{name}` to `{name}.1`. This is the |
73 // previously-opened `file`. |
75 // previously-opened `file`. |
74 self.vfs |
76 self.vfs |
75 .rename(self.name, format!("{}.1", self.name)) |
77 .rename( |
|
78 Path::new(&self.name), |
|
79 Path::new(&format!("{}.1", self.name)), |
|
80 false, |
|
81 ) |
76 .io_not_found_as_none()?; |
82 .io_not_found_as_none()?; |
77 // Finally, create a new `{name}` file and replace our `file` |
83 // Finally, create a new `{name}` file and replace our `file` |
78 // handle. |
84 // handle. |
79 file = open()?; |
85 file = open()?; |
80 } |
86 } |
85 } |
91 } |
86 |
92 |
87 #[test] |
93 #[test] |
88 fn test_rotation() { |
94 fn test_rotation() { |
89 let temp = tempfile::tempdir().unwrap(); |
95 let temp = tempfile::tempdir().unwrap(); |
90 let vfs = VfsImpl { |
96 let vfs = VfsImpl::new(temp.path().to_owned(), false); |
91 base: temp.path().to_owned(), |
|
92 }; |
|
93 let logger = LogFile::new(vfs.clone(), "log") |
97 let logger = LogFile::new(vfs.clone(), "log") |
94 .max_size(Some(3)) |
98 .max_size(Some(3)) |
95 .max_files(2); |
99 .max_files(2); |
96 logger.write(b"one\n").unwrap(); |
100 logger.write(b"one\n").unwrap(); |
97 logger.write(b"two\n").unwrap(); |
101 logger.write(b"two\n").unwrap(); |