Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 57 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 2 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,7 @@ strum_macros = "0.26"
tempfile = "3"
thiserror = "2.0"
thousands = "0.2.0"
time = { version = "0.3.47", features = [
"local-offset",
"macros",
"serde",
"serde-human-readable",
] }
jiff = { version = "0.2.19", features = ["serde"] }
tokio = { version = "1.43", features = ["full", "test-util", "tracing"] }
tracing = "0.1"
tracing-appender = "0.2"
Expand All @@ -93,7 +88,7 @@ version = "0.1.5"

[dependencies.tracing-subscriber]
version = "0.3.20"
features = ["env-filter", "fmt", "json", "local-time", "time"]
features = ["env-filter", "fmt", "json", "local-time"]

[dev-dependencies]
assert_cmd = "2.1.2"
Expand Down
30 changes: 15 additions & 15 deletions src/band.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ use std::sync::Arc;

use crate::transport::Transport;
use itertools::Itertools;
use jiff::Timestamp;
use serde::{Deserialize, Serialize};
use time::OffsetDateTime;
use tracing::{debug, trace, warn};

use crate::jsonio::{read_json, write_json};
Expand Down Expand Up @@ -113,10 +113,10 @@ pub struct Info {
pub is_closed: bool,

/// Time Conserve started writing this band.
pub start_time: OffsetDateTime,
pub start_time: Timestamp,

/// Time this band was completed, if it is complete.
pub end_time: Option<OffsetDateTime>,
pub end_time: Option<Timestamp>,

/// Number of hunks present in the index, if that is known.
pub index_hunk_count: Option<u64>,
Expand Down Expand Up @@ -153,7 +153,7 @@ impl Band {
Some("23.2.0".to_owned())
};
let head = Head {
start_time: OffsetDateTime::now_utc().unix_timestamp(),
start_time: Timestamp::now().as_second(),
band_format_version,
format_flags: format_flags.into(),
};
Expand All @@ -171,7 +171,7 @@ impl Band {
&self.transport,
BAND_TAIL_FILENAME,
&Tail {
end_time: OffsetDateTime::now_utc().unix_timestamp(),
end_time: Timestamp::now().as_second(),
index_hunk_count: Some(index_hunk_count),
},
)
Expand Down Expand Up @@ -267,18 +267,14 @@ impl Band {
pub async fn get_info(&self) -> Result<Info> {
let tail_option: Option<Tail> = read_json(&self.transport, BAND_TAIL_FILENAME).await?;
let start_time =
OffsetDateTime::from_unix_timestamp(self.head.start_time).map_err(|_| {
Error::InvalidMetadata {
details: format!("Invalid band start timestamp {:?}", self.head.start_time),
}
Timestamp::from_second(self.head.start_time).map_err(|_| Error::InvalidMetadata {
details: format!("Invalid band start timestamp {:?}", self.head.start_time),
})?;
let end_time = tail_option
.as_ref()
.map(|tail| {
OffsetDateTime::from_unix_timestamp(tail.end_time).map_err(|_| {
Error::InvalidMetadata {
details: format!("Invalid band end timestamp {:?}", tail.end_time),
}
Timestamp::from_second(tail.end_time).map_err(|_| Error::InvalidMetadata {
details: format!("Invalid band end timestamp {:?}", tail.end_time),
})
})
.transpose()?;
Expand Down Expand Up @@ -352,10 +348,14 @@ mod tests {
assert_eq!(info.id.to_string(), "b0000");
assert!(info.is_closed);
assert_eq!(info.index_hunk_count, Some(0));
let dur = info.end_time.expect("info has an end_time") - info.start_time;
let dur = info
.end_time
.expect("info has an end_time")
.since(info.start_time)
.unwrap();
// Test should have taken (much) less than 5s between starting and finishing
// the band. (It might fail if you set a breakpoint right there.)
assert!(dur < Duration::from_secs(5));
assert!(dur.total(jiff::Unit::Second).unwrap() < 5.0);
}

#[tokio::test]
Expand Down
14 changes: 6 additions & 8 deletions src/bin/conserve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,16 @@ use std::time::Instant;
use clap::builder::{Styles, styling};
use clap::{Parser, Subcommand};
use conserve::change::Change;
use time::UtcOffset;
#[allow(unused_imports)]
use tracing::{Level, debug, error, info, trace, warn};

use crate::transport::Transport;
use conserve::termui::{TermUiMonitor, TraceTimeStyle, enable_tracing};
use conserve::*;

/// Local timezone offset, calculated once at startup, to avoid issues about
/// Local timezone, calculated once at startup, to avoid issues about
/// looking at the environment once multiple threads are running.
static LOCAL_OFFSET: RwLock<UtcOffset> = RwLock::new(UtcOffset::UTC);
static LOCAL_TZ: RwLock<jiff::tz::TimeZone> = RwLock::new(jiff::tz::TimeZone::UTC);

#[mutants::skip] // only visual effects, not worth testing
fn clap_styles() -> Styles {
Expand Down Expand Up @@ -633,7 +632,7 @@ impl Command {
let timezone = if *utc {
None
} else {
Some(*LOCAL_OFFSET.read().unwrap())
Some(LOCAL_TZ.read().unwrap().clone())
};
let archive = Archive::open(Transport::new(archive).await?).await?;
let options = ShowVersionsOptions {
Expand Down Expand Up @@ -716,10 +715,9 @@ fn make_change_callback(
}

fn main() -> Result<ExitCode> {
// Before anything else, get the local time offset, to avoid `time-rs`
// problems with loading it when threads are running.
*LOCAL_OFFSET.write().unwrap() =
UtcOffset::current_local_offset().expect("get local time offset");
// Before anything else, get the local timezone, to avoid issues
// with loading it when threads are running.
*LOCAL_TZ.write().unwrap() = jiff::tz::TimeZone::system();
let args = Args::parse();
let start_time = Instant::now();
let console_level = if args.debug {
Expand Down
4 changes: 2 additions & 2 deletions src/change.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@

use std::fmt;

use jiff::Timestamp;
use serde::Serialize;
use time::OffsetDateTime;

use crate::{Apath, EntryTrait, Kind, Owner, Result, UnixMode};

Expand Down Expand Up @@ -138,7 +138,7 @@ pub struct EntryMetadata {
// TODO: Eventually unify with EntryValue or Entry?
#[serde(flatten)]
pub kind: KindMetadata,
pub mtime: OffsetDateTime,
pub mtime: Timestamp,
#[serde(flatten)]
pub owner: Owner,
pub unix_mode: UnixMode,
Expand Down
4 changes: 2 additions & 2 deletions src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@

use std::fmt::Debug;

use jiff::Timestamp;
use serde::Serialize;
use time::OffsetDateTime;

use crate::*;

Expand All @@ -29,7 +29,7 @@ use crate::*;
pub trait EntryTrait: Debug {
fn apath(&self) -> &Apath;
fn kind(&self) -> Kind;
fn mtime(&self) -> OffsetDateTime;
fn mtime(&self) -> Timestamp;
fn size(&self) -> Option<u64>;
fn symlink_target(&self) -> Option<&str>;
fn unix_mode(&self) -> UnixMode;
Expand Down
11 changes: 5 additions & 6 deletions src/index/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,14 @@
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

use jiff::Timestamp;
use serde_json::json;
use time::OffsetDateTime;

use crate::apath::Apath;
use crate::entry::EntryTrait;
use crate::kind::Kind;
use crate::owner::Owner;
use crate::unix_mode::UnixMode;
use crate::unix_time::FromUnixAndNanos;
use crate::{blockdir, source};

/// Description of one archived file.
Expand Down Expand Up @@ -83,8 +82,8 @@ impl EntryTrait for IndexEntry {
}

#[inline]
fn mtime(&self) -> OffsetDateTime {
OffsetDateTime::from_unix_seconds_and_nanos(self.mtime, self.mtime_nanos)
fn mtime(&self) -> Timestamp {
Timestamp::new(self.mtime, self.mtime_nanos as i32).expect("valid timestamp")
}

/// Size of the file, if it is a file. None for directories and symlinks.
Expand Down Expand Up @@ -142,8 +141,8 @@ impl IndexEntry {
kind: source.kind(),
addrs: Vec::new(),
target: source.symlink_target().map(|t| t.to_owned()),
mtime: mtime.unix_timestamp(),
mtime_nanos: mtime.nanosecond(),
mtime: mtime.as_second(),
mtime_nanos: mtime.subsec_nanosecond() as u32,
unix_mode: source.unix_mode(),
owner: source.owner().to_owned(),
}
Expand Down
12 changes: 6 additions & 6 deletions src/restore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ use std::sync::Arc;
use filetime::set_file_handle_times;
#[cfg(unix)]
use filetime::set_symlink_file_times;
use time::OffsetDateTime;
use jiff::Timestamp;
use tracing::{instrument, trace};

use crate::blockdir::BlockDir;
use crate::counters::Counter;
use crate::index::entry::IndexEntry;
use crate::io::{directory_is_empty, ensure_dir_exists};
use crate::monitor::Monitor;
use crate::unix_time::ToFileTime;
use crate::unix_time::timestamp_to_file_time;
use crate::*;

/// Description of how to restore a tree.
Expand Down Expand Up @@ -176,7 +176,7 @@ fn restore_dir(apath: &Apath, restore_path: &Path, options: &RestoreOptions) ->
struct DirDeferral {
path: PathBuf,
unix_mode: UnixMode,
mtime: OffsetDateTime,
mtime: Timestamp,
owner: Owner,
}

Expand All @@ -200,7 +200,7 @@ fn apply_deferrals(deferrals: &[DirDeferral], monitor: Arc<dyn Monitor>) -> Resu
source,
});
}
if let Err(source) = filetime::set_file_mtime(path, (*mtime).to_file_time()) {
if let Err(source) = filetime::set_file_mtime(path, timestamp_to_file_time(mtime)) {
monitor.error(Error::RestoreModificationTime {
path: path.clone(),
source,
Expand Down Expand Up @@ -247,7 +247,7 @@ async fn restore_file(
source,
})?;

let mtime = Some(source_entry.mtime().to_file_time());
let mtime = Some(timestamp_to_file_time(&source_entry.mtime()));
set_file_handle_times(&out, mtime, mtime).map_err(|source| Error::RestoreModificationTime {
path: path.clone(),
source,
Expand Down Expand Up @@ -291,7 +291,7 @@ fn restore_symlink(path: &Path, entry: &IndexEntry) -> Result<()> {
source,
});
}
let mtime = entry.mtime().to_file_time();
let mtime = timestamp_to_file_time(&entry.mtime());
if let Err(source) = set_symlink_file_times(path, mtime, mtime) {
return Err(Error::RestoreModificationTime {
path: path.to_owned(),
Expand Down
Loading