mirror of
https://github.com/facebook/sapling.git
synced 2024-10-04 13:57:13 +03:00
config/loader: drop ensure_location_supersets
Summary: The config validation logic was migrated to Chef in D56651559. Remove this function to unblock config layout refactoring. Reviewed By: muirdm Differential Revision: D56592494 fbshipit-source-id: 04a6a6f5bf4da7131f8aab45909467c8d74b5d1c
This commit is contained in:
parent
d49f558773
commit
44ebe2309c
@ -10,7 +10,6 @@
|
||||
//! Use `staticconfig::static_config!` to define static configs so they do not
|
||||
//! have runtime parsing or hashmap insertion overhead.
|
||||
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
|
||||
use configmodel::Config;
|
||||
|
@ -90,8 +90,6 @@ pub trait ConfigSetHgExt {
|
||||
/// Load a specified config file. Respect HGPLAIN environment variables.
|
||||
/// Return errors parsing files.
|
||||
fn load_hgrc(&mut self, path: impl AsRef<Path>, source: &'static str) -> Vec<Error>;
|
||||
|
||||
fn validate_dynamic(&mut self) -> Result<(), Error>;
|
||||
}
|
||||
|
||||
/// Load config from specified "minimal repo", or global config if no path specified.
|
||||
@ -389,7 +387,7 @@ impl ConfigSetHgExt for ConfigSet {
|
||||
return Err(Errors(errors));
|
||||
}
|
||||
|
||||
self.validate_dynamic().map_err(|err| Errors(vec![err]))
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn load_system(&mut self, opts: Options, ident: &Identity) -> Vec<Error> {
|
||||
@ -630,31 +628,6 @@ impl ConfigSetHgExt for ConfigSet {
|
||||
let opts = Options::new().source(source).process_hgplain();
|
||||
self.load_path(path, &opts)
|
||||
}
|
||||
|
||||
#[cfg(feature = "fb")]
|
||||
fn validate_dynamic(&mut self) -> Result<(), Error> {
|
||||
let allowed_locations: Option<Vec<String>> =
|
||||
self.get_opt::<Vec<String>>("configs", "allowedlocations")?;
|
||||
let allowed_configs: Option<Vec<String>> =
|
||||
self.get_opt::<Vec<String>>("configs", "allowedconfigs")?;
|
||||
|
||||
Ok(self.ensure_location_supersets(
|
||||
allowed_locations
|
||||
.as_ref()
|
||||
.map(|v| HashSet::from_iter(v.iter().map(|s| s.as_str()))),
|
||||
allowed_configs.as_ref().map(|v| {
|
||||
HashSet::from_iter(v.iter().map(|s| {
|
||||
s.split_once('.')
|
||||
.expect("allowed configs must contain dots")
|
||||
}))
|
||||
}),
|
||||
))
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "fb"))]
|
||||
fn validate_dynamic(&mut self) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Read repo name from various places (remotefilelog.reponame, paths.default, .hg/reponame).
|
||||
|
@ -544,88 +544,6 @@ impl ConfigSet {
|
||||
}
|
||||
}
|
||||
|
||||
/// Drop configs from sources that are outside `allowed_locations` or
|
||||
/// `allowed_configs`.
|
||||
///
|
||||
/// This function is being removed but we need logging to understand its
|
||||
/// side-effect.
|
||||
pub fn ensure_location_supersets(
|
||||
&mut self,
|
||||
allowed_locations: Option<HashSet<&str>>,
|
||||
allowed_configs: Option<HashSet<(&str, &str)>>,
|
||||
) {
|
||||
for (sname, section) in self.sections.iter_mut() {
|
||||
for (kname, values) in section.items.iter_mut() {
|
||||
let values_copy = values.clone();
|
||||
let mut removals = 0;
|
||||
// value with a larger index takes precedence.
|
||||
for (index, value) in values_copy.iter().enumerate() {
|
||||
// Convert the index into the original index.
|
||||
let index = index - removals;
|
||||
|
||||
// Get the filename of the value's rc location
|
||||
let path: PathBuf = match value.location() {
|
||||
None => continue,
|
||||
Some((path, _)) => path,
|
||||
};
|
||||
let location: Option<String> = path
|
||||
.file_name()
|
||||
.and_then(|f| f.to_str())
|
||||
.map(|s| s.to_string());
|
||||
// If only certain locations are allowed, and this isn't one of them, remove
|
||||
// it. If location is None, it came from inmemory, so don't filter it.
|
||||
if let Some(location) = location {
|
||||
if crate::builtin::get(location.as_str()).is_none()
|
||||
&& allowed_locations
|
||||
.as_ref()
|
||||
.map(|a| a.contains(location.as_str()))
|
||||
== Some(false)
|
||||
&& allowed_configs
|
||||
.as_ref()
|
||||
.map(|a| a.contains(&(sname, kname)))
|
||||
!= Some(true)
|
||||
{
|
||||
tracing::trace!(
|
||||
target: "configset::validate",
|
||||
"dropping {}.{} set by {} ({})",
|
||||
sname.as_ref(),
|
||||
kname.as_ref(),
|
||||
path.display().to_string(),
|
||||
value
|
||||
.value()
|
||||
.as_ref()
|
||||
.map(|v| v.as_ref())
|
||||
.unwrap_or_default(),
|
||||
);
|
||||
values.remove(index);
|
||||
removals += 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the removal changes the config, log it as mismatched.
|
||||
if let (Some(before_remove), Some(after_remove)) =
|
||||
(values_copy.last(), values.last())
|
||||
{
|
||||
if before_remove.value != after_remove.value {
|
||||
let source = match before_remove.location() {
|
||||
None => before_remove.source().to_string(),
|
||||
Some(l) => l.0.display().to_string(),
|
||||
};
|
||||
tracing::info!(
|
||||
target: "config_mismatch",
|
||||
config=&format!("{sname}.{kname}"),
|
||||
expected=after_remove.value.clone().unwrap_or_default().as_ref(),
|
||||
actual=before_remove.value.clone().unwrap_or_default().as_ref(),
|
||||
source=source,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clear_unpinned(&mut self) {
|
||||
self.sections.clear();
|
||||
self.secondary = None;
|
||||
@ -1161,61 +1079,6 @@ space_list=value1.a value1.b
|
||||
assert_eq!(cfg.sections(), cfg2.sections());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_allowed_locations() {
|
||||
let mut cfg = ConfigSet::new();
|
||||
|
||||
fn set(
|
||||
cfg: &mut ConfigSet,
|
||||
section: &'static str,
|
||||
key: &'static str,
|
||||
value: &'static str,
|
||||
location: &'static str,
|
||||
) {
|
||||
cfg.set_internal(
|
||||
Text::from_static(section),
|
||||
Text::from_static(key),
|
||||
Some(Text::from_static(value)),
|
||||
Some(ValueLocation {
|
||||
path: Arc::new(Path::new(location).to_owned()),
|
||||
content: Text::from_static(""),
|
||||
location: 0..1,
|
||||
}),
|
||||
&Options::new()
|
||||
.source(Text::from_static("source"))
|
||||
.pin(false),
|
||||
);
|
||||
}
|
||||
|
||||
set(&mut cfg, "section1", "key1", "value1", "subset1");
|
||||
set(&mut cfg, "section2", "key2", "value2", "subset2");
|
||||
|
||||
let mut allow_list = HashSet::new();
|
||||
allow_list.insert("subset1");
|
||||
|
||||
cfg.ensure_location_supersets(Some(allow_list.clone()), None);
|
||||
assert_eq!(
|
||||
cfg.get("section1", "key1"),
|
||||
Some(Text::from_static("value1"))
|
||||
);
|
||||
assert_eq!(cfg.get("section2", "key2"), None);
|
||||
|
||||
// Check that allow_configs allows the config through, even if allow_locations did not.
|
||||
let mut allow_configs = HashSet::new();
|
||||
allow_configs.insert(("section2", "key2"));
|
||||
|
||||
set(&mut cfg, "section2", "key2", "value2", "subset2");
|
||||
cfg.ensure_location_supersets(Some(allow_list), Some(allow_configs));
|
||||
assert_eq!(
|
||||
cfg.get("section1", "key1"),
|
||||
Some(Text::from_static("value1"))
|
||||
);
|
||||
assert_eq!(
|
||||
cfg.get("section2", "key2"),
|
||||
Some(Text::from_static("value2"))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_secondary() {
|
||||
let mut cfg1 = ConfigSet::new();
|
||||
@ -1277,41 +1140,6 @@ x = 2
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_verifier_removal() {
|
||||
let mut cfg = ConfigSet::new();
|
||||
|
||||
fn set(
|
||||
cfg: &mut ConfigSet,
|
||||
section: &'static str,
|
||||
key: &'static str,
|
||||
value: &'static str,
|
||||
location: &'static str,
|
||||
) {
|
||||
cfg.set_internal(
|
||||
Text::from_static(section),
|
||||
Text::from_static(key),
|
||||
Some(Text::from_static(value)),
|
||||
Some(ValueLocation {
|
||||
path: Arc::new(Path::new(location).to_owned()),
|
||||
content: Text::from_static(""),
|
||||
location: 0..1,
|
||||
}),
|
||||
&Options::new().source(Text::from_static("source")),
|
||||
);
|
||||
}
|
||||
|
||||
// This test verifies that allowed location removal and subset removal interact nicely
|
||||
// together.
|
||||
set(&mut cfg, "section", "key", "value", "subset");
|
||||
set(&mut cfg, "section", "key", "value2", "super");
|
||||
|
||||
let mut allowed_locations = HashSet::new();
|
||||
allowed_locations.insert("super");
|
||||
|
||||
cfg.ensure_location_supersets(Some(allowed_locations), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_or() {
|
||||
let mut cfg = ConfigSet::new();
|
||||
|
@ -168,43 +168,6 @@ Verify we don't regenerate configs if the Mercurial version hasn't changed
|
||||
$ hg config section3.key3
|
||||
value3
|
||||
|
||||
Verify configs.allowedlocations limits config loading to the allowed locations
|
||||
$ cat >> .hg/hgrc <<EOF
|
||||
> %include hgrc1
|
||||
> %include hgrc2
|
||||
> %include hgrc3
|
||||
> EOF
|
||||
$ cat >> .hg/hgrc1 <<EOF
|
||||
> [zz_section]
|
||||
> key=foo
|
||||
> [zz_other_section]
|
||||
> other_key=other_foo
|
||||
> EOF
|
||||
$ cat >> .hg/hgrc2 <<EOF
|
||||
> [zz_section]
|
||||
> key=bar
|
||||
> [zz_other_section]
|
||||
> other_key=other_bar
|
||||
> EOF
|
||||
$ hg config --debug | grep ': zz_'
|
||||
$TESTTMP/shared_copy/.hg/hgrc2:2: zz_section.key=bar
|
||||
$TESTTMP/shared_copy/.hg/hgrc2:4: zz_other_section.other_key=other_bar
|
||||
|
||||
$ hg config --debug --config "configs.allowedlocations=hgrc1 .hgrc" | grep ': zz_'
|
||||
$TESTTMP/shared_copy/.hg/hgrc1:2: zz_section.key=foo
|
||||
$TESTTMP/shared_copy/.hg/hgrc1:4: zz_other_section.other_key=other_foo
|
||||
|
||||
$ hg config --debug --config "configs.allowedlocations=hgrc2 .hgrc" | grep ': zz_'
|
||||
$TESTTMP/shared_copy/.hg/hgrc2:2: zz_section.key=bar
|
||||
$TESTTMP/shared_copy/.hg/hgrc2:4: zz_other_section.other_key=other_bar
|
||||
|
||||
$ hg config --debug --config "configs.allowedlocations=hgrc3 .hgrc" | grep ': zz_'
|
||||
[1]
|
||||
|
||||
$ hg config --debug --config "configs.allowedlocations=hgrc3 .hgrc" --config "configs.allowedconfigs=zz_section.key .hgrc" | grep 'zz_section\.'
|
||||
--config: configs.allowedconfigs=zz_section.key .hgrc
|
||||
$TESTTMP/shared_copy/.hg/hgrc2:2: zz_section.key=bar
|
||||
|
||||
Verify we load internalconfig during clone
|
||||
$ cd $TESTTMP
|
||||
$ export HG_TEST_INTERNALCONFIG="$TESTTMP/test_hgrc"
|
||||
|
Loading…
Reference in New Issue
Block a user