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
|
//! Use `staticconfig::static_config!` to define static configs so they do not
|
||||||
//! have runtime parsing or hashmap insertion overhead.
|
//! have runtime parsing or hashmap insertion overhead.
|
||||||
|
|
||||||
use std::path::Path;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use configmodel::Config;
|
use configmodel::Config;
|
||||||
|
@ -90,8 +90,6 @@ pub trait ConfigSetHgExt {
|
|||||||
/// Load a specified config file. Respect HGPLAIN environment variables.
|
/// Load a specified config file. Respect HGPLAIN environment variables.
|
||||||
/// Return errors parsing files.
|
/// Return errors parsing files.
|
||||||
fn load_hgrc(&mut self, path: impl AsRef<Path>, source: &'static str) -> Vec<Error>;
|
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.
|
/// 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));
|
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> {
|
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();
|
let opts = Options::new().source(source).process_hgplain();
|
||||||
self.load_path(path, &opts)
|
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).
|
/// 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) {
|
pub fn clear_unpinned(&mut self) {
|
||||||
self.sections.clear();
|
self.sections.clear();
|
||||||
self.secondary = None;
|
self.secondary = None;
|
||||||
@ -1161,61 +1079,6 @@ space_list=value1.a value1.b
|
|||||||
assert_eq!(cfg.sections(), cfg2.sections());
|
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]
|
#[test]
|
||||||
fn test_secondary() {
|
fn test_secondary() {
|
||||||
let mut cfg1 = ConfigSet::new();
|
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]
|
#[test]
|
||||||
fn test_get_or() {
|
fn test_get_or() {
|
||||||
let mut cfg = ConfigSet::new();
|
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
|
$ hg config section3.key3
|
||||||
value3
|
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
|
Verify we load internalconfig during clone
|
||||||
$ cd $TESTTMP
|
$ cd $TESTTMP
|
||||||
$ export HG_TEST_INTERNALCONFIG="$TESTTMP/test_hgrc"
|
$ export HG_TEST_INTERNALCONFIG="$TESTTMP/test_hgrc"
|
||||||
|
Loading…
Reference in New Issue
Block a user