diff --git a/rust/Cargo.lock b/rust/Cargo.lock --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -256,7 +256,7 @@ [[package]] name = "format-bytes" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "format-bytes-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -317,7 +317,7 @@ "crossbeam-channel 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "derive_more 0.99.11 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", - "format-bytes 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "format-bytes 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "home 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "im-rc 15.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -740,7 +740,7 @@ "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", "derive_more 0.99.11 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "format-bytes 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "format-bytes 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "hg-core 0.1.0", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1000,7 +1000,7 @@ "checksum either 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" "checksum env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" "checksum flate2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)" = "7411863d55df97a419aa64cb4d2f167103ea9d767e2c54a1868b7ac3f6b47129" -"checksum format-bytes 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cc35f5e45d6b31053cea13078ffc6fa52fa8617aa54b7ac2011720d9c009e04f" +"checksum format-bytes 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8030ff4b04f0ca1c612d6fe49f2fc18caf56fb01497cb370b41cfd36d89b3b06" "checksum format-bytes-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b05089e341a0460449e2210c3bf7b61597860b07f0deae58da38dbed0a4c6b6d" "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" "checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" diff --git a/rust/hg-core/src/config/config.rs b/rust/hg-core/src/config/config.rs --- a/rust/hg-core/src/config/config.rs +++ b/rust/hg-core/src/config/config.rs @@ -14,6 +14,7 @@ }; use crate::utils::files::get_bytes_from_os_str; use format_bytes::{write_bytes, DisplayBytes}; +use std::collections::HashSet; use std::env; use std::path::{Path, PathBuf}; use std::str; @@ -343,6 +344,14 @@ None } + /// Return all keys defined for the given section + pub fn get_section_keys(&self, section: &[u8]) -> HashSet<&[u8]> { + self.layers + .iter() + .flat_map(|layer| layer.iter_keys(section)) + .collect() + } + /// Get raw values bytes from all layers (even untrusted ones) in order /// of precedence. #[cfg(test)] diff --git a/rust/hg-core/src/config/layer.rs b/rust/hg-core/src/config/layer.rs --- a/rust/hg-core/src/config/layer.rs +++ b/rust/hg-core/src/config/layer.rs @@ -115,6 +115,14 @@ Some(self.sections.get(section)?.get(item)?) } + /// Returns the keys defined in the given section + pub fn iter_keys(&self, section: &[u8]) -> impl Iterator { + self.sections + .get(section) + .into_iter() + .flat_map(|section| section.keys().map(|vec| &**vec)) + } + pub fn is_empty(&self) -> bool { self.sections.is_empty() } diff --git a/rust/rhg/Cargo.toml b/rust/rhg/Cargo.toml --- a/rust/rhg/Cargo.toml +++ b/rust/rhg/Cargo.toml @@ -17,5 +17,5 @@ micro-timer = "0.3.1" regex = "1.3.9" env_logger = "0.7.1" -format-bytes = "0.2.0" +format-bytes = "0.2.1" users = "0.11.0" diff --git a/rust/rhg/src/main.rs b/rust/rhg/src/main.rs --- a/rust/rhg/src/main.rs +++ b/rust/rhg/src/main.rs @@ -4,7 +4,7 @@ use clap::AppSettings; use clap::Arg; use clap::ArgMatches; -use format_bytes::format_bytes; +use format_bytes::{format_bytes, join}; use hg::config::Config; use hg::repo::{Repo, RepoError}; use hg::utils::files::{get_bytes_from_os_str, get_path_from_bytes}; @@ -25,6 +25,8 @@ repo: Result<&Repo, &NoRepoInCwdError>, config: &Config, ) -> Result<(), CommandError> { + check_extensions(config)?; + let app = App::new("rhg") .global_setting(AppSettings::AllowInvalidUtf8) .setting(AppSettings::SubcommandRequired) @@ -352,3 +354,25 @@ } } } + +const SUPPORTED_EXTENSIONS: &[&[u8]] = &[b"blackbox", b"share"]; + +fn check_extensions(config: &Config) -> Result<(), CommandError> { + let enabled = config.get_section_keys(b"extensions"); + + let mut unsupported = enabled; + for supported in SUPPORTED_EXTENSIONS { + unsupported.remove(supported); + } + + if unsupported.is_empty() { + Ok(()) + } else { + Err(CommandError::UnsupportedFeature { + message: format_bytes!( + b"extensions: {}", + join(unsupported, b", ") + ), + }) + } +}