Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: simplify __MISE_WATCH variable to only contain the most recent timestamp #3282

Merged
merged 2 commits into from
Nov 29, 2024
Merged
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
1 change: 1 addition & 0 deletions e2e/run_all_tests
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ for index in "${!FILES[@]}"; do
continue
fi

mise x -- wait-for-gh-rate-limit
# Actually run the test
"$ROOT/e2e/run_test" "$TEST_NAME" # fail fast for now
# if ! "$ROOT/e2e/run_test" "$TEST_NAME"; then
Expand Down
2 changes: 2 additions & 0 deletions registry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,7 @@ flatc.backends = ["ubi:google/flatbuffers[exe=flatc]", "asdf:TheOpenDictionary/a
flatc.test = ["flatc --version", "flatc version {{version}}"]
flutter.backends = ["asdf:oae/asdf-flutter", "vfox:version-fox/vfox-flutter"]
fluttergen.backends = ["ubi:FlutterGen/flutter_gen[exe=fluttergen]", "asdf:FlutterGen/asdf-fluttergen"]
fluttergen.os = ["linux", "macos"]
fluttergen.test = ["fluttergen --version", "FlutterGen v{{version}}"]
flux2.backends = ["aqua:fluxcd/flux2", "asdf:tablexi/asdf-flux2"]
flux2.test = ["flux --version", "flux version {{version}}"]
Expand All @@ -347,6 +348,7 @@ flyway.backends = ["asdf:junminahn/asdf-flyway"]
func-e.backends = ["tetratelabs/func-e", "asdf:carnei-ro/asdf-func-e"]
func-e.test = ["func-e --version", "func-e version {{version}}"]
furyctl.backends = ["ubi:sighupio/furyctl", "asdf:sighupio/asdf-furyctl"]
furyctl.os = ["linux", "macos"]
furyctl.test = ["furyctl version", "{{version}}"]
fx.backends = ["aqua:antonmedv/fx", "asdf:https://gitlab.com/wt0f/asdf-fx"]
fzf.backends = ["ubi:junegunn/fzf", "asdf:kompiro/asdf-fzf"]
Expand Down
130 changes: 13 additions & 117 deletions src/hook_env.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use std::collections::{BTreeMap, BTreeSet};
use std::collections::BTreeSet;
use std::io::prelude::*;
use std::ops::Deref;
use std::path::{Path, PathBuf};
use std::time::SystemTime;
use std::time::{SystemTime, UNIX_EPOCH};

use base64::prelude::*;
use eyre::Result;
Expand Down Expand Up @@ -75,29 +75,15 @@ pub fn dir_change() -> Option<(PathBuf, PathBuf)> {
}

fn have_files_been_modified(watches: &HookEnvWatches, watch_files: BTreeSet<PathBuf>) -> bool {
// make sure they have exactly the same config filenames
let watch_keys = watches.files.keys().cloned().collect::<BTreeSet<_>>();
if watch_keys != watch_files {
trace!(
"config files do not match {:?}",
watch_keys.symmetric_difference(&watch_files)
);
return true;
}

// check the files to see if they've been altered
let mut modified = false;
for (fp, prev_modtime) in &watches.files {
if let Ok(modtime) = fp
.metadata()
.expect("accessing config file modtime")
.modified()
{
for fp in &watch_files {
if let Ok(modtime) = fp.metadata().and_then(|m| m.modified()) {
let modtime = modtime
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.as_secs();
if modtime != *prev_modtime {
if modtime > watches.latest_update {
trace!("file modified: {:?}", fp);
modified = true;
watch_files::add_modified_file(fp.clone());
Expand All @@ -117,9 +103,9 @@ fn have_mise_env_vars_been_modified(watches: &HookEnvWatches) -> bool {
false
}

#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug, Default, Serialize, Deserialize)]
pub struct HookEnvWatches {
files: BTreeMap<PathBuf, u64>,
latest_update: u64,
env_var_hash: String,
}

Expand All @@ -141,20 +127,17 @@ pub fn deserialize_watches(raw: String) -> Result<HookEnvWatches> {
pub fn build_watches(
watch_files: impl IntoIterator<Item = WatchFilePattern>,
) -> Result<HookEnvWatches> {
let mut watches = BTreeMap::new();
let mut max_modtime = UNIX_EPOCH;
for cf in get_watch_files(watch_files) {
watches.insert(
cf.clone(),
cf.metadata()?
.modified()?
.duration_since(SystemTime::UNIX_EPOCH)?
.as_secs(),
);
max_modtime = std::cmp::max(cf.metadata()?.modified()?, max_modtime);
}

Ok(HookEnvWatches {
files: watches,
env_var_hash: get_mise_env_vars_hashed(),
latest_update: max_modtime
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.as_secs(),
})
}

Expand Down Expand Up @@ -222,90 +205,3 @@ pub fn build_env_commands(shell: &dyn Shell, patches: &EnvDiffPatches) -> String

output
}

#[cfg(test)]
mod tests {
use std::time::UNIX_EPOCH;

use pretty_assertions::{assert_eq, assert_str_eq};
use test_log::test;

use super::*;

#[test]
fn test_have_config_files_been_modified() {
let files = BTreeSet::new();
let watches = HookEnvWatches {
files: BTreeMap::new(),
env_var_hash: "".into(),
};
assert!(!have_files_been_modified(&watches, files));

let fp = env::current_dir().unwrap().join(".test-tool-versions");
let watches = HookEnvWatches {
files: BTreeMap::from([(
fp.clone(),
UNIX_EPOCH
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.as_secs(),
)]),
env_var_hash: "".into(),
};
let files = BTreeSet::from([fp.clone()]);
assert!(have_files_been_modified(&watches, files));

let modtime = fp.metadata().unwrap().modified().unwrap();
let watches = HookEnvWatches {
files: BTreeMap::from([(
fp.clone(),
modtime
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.as_secs(),
)]),
env_var_hash: "".into(),
};
let files = BTreeSet::from([fp]);
assert!(!have_files_been_modified(&watches, files));
}

#[test]
fn test_serialize_watches_empty() {
let watches = HookEnvWatches {
files: BTreeMap::new(),
env_var_hash: "".into(),
};
let serialized = serialize_watches(&watches).unwrap();
let deserialized = deserialize_watches(serialized).unwrap();
assert_eq!(deserialized.files.len(), 0);
}

#[test]
fn test_serialize_watches() {
let serialized = serialize_watches(&HookEnvWatches {
files: BTreeMap::from([(
PathBuf::from("foo"),
UNIX_EPOCH
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.as_secs(),
)]),
env_var_hash: "testing-123".into(),
})
.unwrap();
let deserialized = deserialize_watches(serialized).unwrap();
assert_eq!(deserialized.files.len(), 1);
assert_str_eq!(deserialized.env_var_hash, "testing-123");
assert_eq!(
*deserialized
.files
.get(PathBuf::from("foo").as_path())
.unwrap(),
UNIX_EPOCH
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.as_secs()
);
}
}