settings: cache commit and operation parameters by UserSettings

This helps propagate configuration error. RevsetParseContext is also updated
because it was easier to pass &str in to it.
This commit is contained in:
Yuya Nishihara 2024-12-23 17:30:21 +09:00
parent d91e355674
commit 4a69d0178c
4 changed files with 39 additions and 26 deletions

View File

@ -850,7 +850,7 @@ static BUILTIN_FUNCTION_MAP: Lazy<HashMap<&'static str, RevsetFunction>> = Lazy:
// are generally (although not universally) treated as caseinsensitive too, so
// we use a caseinsensitive match here.
Ok(RevsetExpression::filter(RevsetFilterPredicate::Author(
StringPattern::exact_i(&context.user_email),
StringPattern::exact_i(context.user_email),
)))
});
map.insert("committer", |diagnostics, function, _context| {
@ -2629,7 +2629,7 @@ impl RevsetExtensions {
#[derive(Clone)]
pub struct RevsetParseContext<'a> {
aliases_map: &'a RevsetAliasesMap,
user_email: String,
user_email: &'a str,
date_pattern_context: DatePatternContext,
extensions: &'a RevsetExtensions,
workspace: Option<RevsetWorkspaceContext<'a>>,
@ -2638,7 +2638,7 @@ pub struct RevsetParseContext<'a> {
impl<'a> RevsetParseContext<'a> {
pub fn new(
aliases_map: &'a RevsetAliasesMap,
user_email: String,
user_email: &'a str,
date_pattern_context: DatePatternContext,
extensions: &'a RevsetExtensions,
workspace: Option<RevsetWorkspaceContext<'a>>,
@ -2656,8 +2656,8 @@ impl<'a> RevsetParseContext<'a> {
self.aliases_map
}
pub fn user_email(&self) -> &str {
&self.user_email
pub fn user_email(&self) -> &'a str {
self.user_email
}
pub fn date_pattern_context(&self) -> &DatePatternContext {
@ -2706,7 +2706,7 @@ mod tests {
let extensions = RevsetExtensions::default();
let context = RevsetParseContext::new(
&aliases_map,
"test.user@example.com".to_string(),
"test.user@example.com",
chrono::Utc::now().fixed_offset().into(),
&extensions,
None,
@ -2735,7 +2735,7 @@ mod tests {
let extensions = RevsetExtensions::default();
let context = RevsetParseContext::new(
&aliases_map,
"test.user@example.com".to_string(),
"test.user@example.com",
chrono::Utc::now().fixed_offset().into(),
&extensions,
Some(workspace_ctx),
@ -2760,7 +2760,7 @@ mod tests {
let extensions = RevsetExtensions::default();
let context = RevsetParseContext::new(
&aliases_map,
"test.user@example.com".to_string(),
"test.user@example.com",
chrono::Utc::now().fixed_offset().into(),
&extensions,
None,

View File

@ -41,8 +41,12 @@ use crate::signing::SignBehavior;
#[derive(Debug, Clone)]
pub struct UserSettings {
config: StackedConfig,
user_name: String,
user_email: String,
commit_timestamp: Option<Timestamp>,
operation_timestamp: Option<Timestamp>,
operation_hostname: String,
operation_username: String,
rng: Arc<JJRng>,
}
@ -106,7 +110,7 @@ impl SignSettings {
} else {
SignBehavior::Keep
},
user_email: settings.user_email(),
user_email: settings.user_email().to_owned(),
key: settings.get_string("signing.key").ok(),
}
}
@ -142,17 +146,29 @@ fn to_timestamp(value: ConfigValue) -> Result<Timestamp, Box<dyn std::error::Err
impl UserSettings {
pub fn from_config(config: StackedConfig) -> Result<Self, ConfigGetError> {
let user_name = config.get("user.name").unwrap_or_default();
let user_email = config.get("user.email").unwrap_or_default();
let commit_timestamp = config
.get_value_with("debug.commit-timestamp", to_timestamp)
.optional()?;
let operation_timestamp = config
.get_value_with("debug.operation-timestamp", to_timestamp)
.optional()?;
let operation_hostname = config
.get("operation.hostname")
.unwrap_or_else(|_| whoami::fallible::hostname().expect("valid hostname"));
let operation_username = config
.get("operation.username")
.unwrap_or_else(|_| whoami::username());
let rng_seed = config.get::<u64>("debug.randomness-seed").optional()?;
Ok(UserSettings {
config,
user_name,
user_email,
commit_timestamp,
operation_timestamp,
operation_hostname,
operation_username,
rng: Arc::new(JJRng::new(rng_seed)),
})
}
@ -168,15 +184,15 @@ impl UserSettings {
self.rng.clone()
}
pub fn user_name(&self) -> String {
self.get_string("user.name").unwrap_or_default()
pub fn user_name(&self) -> &str {
&self.user_name
}
// Must not be changed to avoid git pushing older commits with no set name
pub const USER_NAME_PLACEHOLDER: &'static str = "(no name configured)";
pub fn user_email(&self) -> String {
self.get_string("user.email").unwrap_or_default()
pub fn user_email(&self) -> &str {
&self.user_email
}
pub fn fsmonitor_settings(&self) -> Result<FsmonitorSettings, ConfigGetError> {
@ -195,21 +211,19 @@ impl UserSettings {
self.operation_timestamp
}
pub fn operation_hostname(&self) -> String {
self.get_string("operation.hostname")
.unwrap_or_else(|_| whoami::fallible::hostname().expect("valid hostname"))
pub fn operation_hostname(&self) -> &str {
&self.operation_hostname
}
pub fn operation_username(&self) -> String {
self.get_string("operation.username")
.unwrap_or_else(|_| whoami::username())
pub fn operation_username(&self) -> &str {
&self.operation_username
}
pub fn signature(&self) -> Signature {
let timestamp = self.commit_timestamp.unwrap_or_else(Timestamp::now);
Signature {
name: self.user_name(),
email: self.user_email(),
name: self.user_name().to_owned(),
email: self.user_email().to_owned(),
timestamp,
}
}

View File

@ -155,8 +155,8 @@ pub fn create_op_metadata(
.operation_timestamp()
.unwrap_or_else(Timestamp::now);
let end_time = start_time;
let hostname = user_settings.operation_hostname();
let username = user_settings.operation_username();
let hostname = user_settings.operation_hostname().to_owned();
let username = user_settings.operation_username().to_owned();
OperationMetadata {
start_time,
end_time,

View File

@ -69,8 +69,7 @@ fn resolve_symbol_with_extensions(
) -> Result<Vec<CommitId>, RevsetResolutionError> {
let aliases_map = RevsetAliasesMap::default();
let now = chrono::Local::now();
let context =
RevsetParseContext::new(&aliases_map, String::new(), now.into(), extensions, None);
let context = RevsetParseContext::new(&aliases_map, "", now.into(), extensions, None);
let expression = parse(&mut RevsetDiagnostics::new(), symbol, &context).unwrap();
assert_matches!(*expression, RevsetExpression::CommitRef(_));
let symbol_resolver = DefaultSymbolResolver::new(repo, extensions.symbol_resolvers());
@ -2971,7 +2970,7 @@ fn test_evaluate_expression_mine() {
.set_parents(vec![commit1.id().clone()])
.set_author(Signature {
name: "name2".to_string(),
email: settings.user_email(),
email: settings.user_email().to_owned(),
timestamp,
})
.write()