Unified · Split
| @@ -61,6 +61,9 @@ comfort = ["gix-features/progress-unit-bytes", "gix-features/progress-unit-human · 60 unmodified lines | ||
| 61 | 61 | #! A component is a distinct feature which may be comprised of one or more methods around a particular topic. |
| 62 | 62 | #! Providers of libraries should only activate the components they need. |
| 63 | 63 | |
| 64 | +## Provide a top-level `command` module that helps with spawning commands similarly to `git`. | |
| 65 | +command = ["dep:gix-command"] | |
| 66 | + | |
| 64 | 67 | ## Obtain information similar to `git status`. |
| 65 | 68 | status = ["gix-status"] |
| 66 | 69 | |
| @@ -81,7 +84,7 @@ worktree-mutation = ["attributes", "dep:gix-worktree-state"] · 14 unmodified lines | ||
| 81 | 84 | excludes = ["dep:gix-ignore", "dep:gix-worktree", "index"] |
| 82 | 85 | |
| 83 | 86 | ## Query attributes and excludes. Enables access to pathspecs, worktree checkouts, filter-pipelines and submodules. |
| 84 | −attributes = ["excludes", "dep:gix-filter", "dep:gix-pathspec", "dep:gix-attributes", "dep:gix-submodule", "gix-worktree?/attributes", "dep:gix-command"] | |
| 87 | +attributes = ["excludes", "dep:gix-filter", "dep:gix-pathspec", "dep:gix-attributes", "dep:gix-submodule", "gix-worktree?/attributes", "command"] | |
| 85 | 88 | |
| 86 | 89 | ## Add support for mailmaps, as way of determining the final name of commmiters and authors. |
| 87 | 90 | mailmap = ["dep:gix-mailmap", "revision"] |
| @@ -1,5 +1,6 @@ | ||
| 1 | 1 | #![allow(clippy::result_large_err)] |
| 2 | 2 | use std::borrow::Cow; |
| 3 | +use std::ffi::OsStr; | |
| 3 | 4 | |
| 4 | 5 | use gix_features::threading::OwnShared; |
| 5 | 6 | use gix_macros::momo; |
| @@ -68,6 +69,21 @@ impl<'repo> Snapshot<'repo> { · 62 unmodified lines | ||
| 68 | 69 | .config |
| 69 | 70 | .trusted_file_path(key.section_name, key.subsection_name, key.value_name) |
| 70 | 71 | } |
| 72 | + | |
| 73 | + /// Return the trusted string at `key` for launching using [command::prepare()](gix_command::prepare()), | |
| 74 | + /// or `None` if there is no such value or if no value was found in a trusted file. | |
| 75 | + #[momo] | |
| 76 | + pub fn trusted_program<'a>(&self, key: impl Into<&'a BStr>) -> Option<Cow<'repo, OsStr>> { | |
| 77 | + let value = self | |
| 78 | + .repo | |
| 79 | + .config | |
| 80 | + .resolved | |
| 81 | + .string_filter_by_key(key, &mut self.repo.config.filter_config_section.clone())?; | |
| 82 | + Some(match gix_path::from_bstr(value) { | |
| 83 | + Cow::Borrowed(v) => Cow::Borrowed(v.as_os_str()), | |
| 84 | + Cow::Owned(v) => Cow::Owned(v.into_os_string()), | |
| 85 | + }) | |
| 86 | + } | |
| 71 | 87 | } |
| 72 | 88 | |
| 73 | 89 | /// Utilities and additional access |
| @@ -165,9 +165,19 @@ pub type RemoteName = Any<validate::RemoteName>; · 164 unmodified lines | ||
| 165 | 165 | pub type Boolean = Any<validate::Boolean>; |
| 166 | 166 | |
| 167 | 167 | /// A key that represents an executable program, shell script or shell commands. |
| 168 | +/// | |
| 169 | +/// Once obtained with [trusted_program()](crate::config::Snapshot::trusted_program()) | |
| 170 | +/// one can run it with [command::prepare()](gix_command::prepare), possibly after | |
| 171 | +/// [obtaining](crate::Repository::command_context) and [setting](gix_command::Prepare::with_context) | |
| 172 | +/// a git [command context](gix_command::Context) (depending on the commands needs). | |
| 168 | 173 | pub type Program = Any<validate::Program>; |
| 169 | 174 | |
| 170 | 175 | /// A key that represents an executable program as identified by name or path. |
| 176 | +/// | |
| 177 | +/// Once obtained with [trusted_program()](crate::config::Snapshot::trusted_program()) | |
| 178 | +/// one can run it with [command::prepare()](gix_command::prepare), possibly after | |
| 179 | +/// [obtaining](crate::Repository::command_context) and [setting](gix_command::Prepare::with_context) | |
| 180 | +/// a git [command context](gix_command::Context) (depending on the commands needs). | |
| 171 | 181 | pub type Executable = Any<validate::Executable>; |
| 172 | 182 | |
| 173 | 183 | /// A key that represents a path (to a resource). |
| @@ -22,6 +22,8 @@ impl Core { · 21 unmodified lines | ||
| 22 | 22 | /// The `core.disambiguate` key. |
| 23 | 23 | pub const DISAMBIGUATE: Disambiguate = |
| 24 | 24 | Disambiguate::new_with_validate("disambiguate", &config::Tree::CORE, validate::Disambiguate); |
| 25 | + /// The `core.editor` key. | |
| 26 | + pub const EDITOR: keys::Program = keys::Program::new_program("editor", &config::Tree::CORE); | |
| 25 | 27 | /// The `core.fileMode` key. |
| 26 | 28 | pub const FILE_MODE: keys::Boolean = keys::Boolean::new_boolean("fileMode", &config::Tree::CORE); |
| 27 | 29 | /// The `core.ignoreCase` key. |
| @@ -58,10 +60,10 @@ impl Core { · 30 unmodified lines | ||
| 58 | 60 | .with_environment_override("GIT_ASKPASS") |
| 59 | 61 | .with_note("fallback is 'SSH_ASKPASS'"); |
| 60 | 62 | /// The `core.excludesFile` key. |
| 61 | − pub const EXCLUDES_FILE: keys::Executable = keys::Executable::new_executable("excludesFile", &config::Tree::CORE); | |
| 63 | + pub const EXCLUDES_FILE: keys::Path = keys::Path::new_path("excludesFile", &config::Tree::CORE); | |
| 62 | 64 | /// The `core.attributesFile` key. |
| 63 | − pub const ATTRIBUTES_FILE: keys::Executable = | |
| 64 | − keys::Executable::new_executable("attributesFile", &config::Tree::CORE) | |
| 65 | + pub const ATTRIBUTES_FILE: keys::Path = | |
| 66 | + keys::Path::new_path("attributesFile", &config::Tree::CORE) | |
| 65 | 67 | .with_deviation("for checkout - it's already queried but needs building of attributes group, and of course support during checkout"); |
| 66 | 68 | /// The `core.sshCommand` key. |
| 67 | 69 | pub const SSH_COMMAND: keys::Executable = keys::Executable::new_executable("sshCommand", &config::Tree::CORE) |
| @@ -102,6 +104,7 @@ impl Section for Core { · 34 unmodified lines | ||
| 102 | 104 | &Self::CHECK_STAT, |
| 103 | 105 | &Self::DELTA_BASE_CACHE_LIMIT, |
| 104 | 106 | &Self::DISAMBIGUATE, |
| 107 | + &Self::EDITOR, | |
| 105 | 108 | &Self::FILE_MODE, |
| 106 | 109 | &Self::IGNORE_CASE, |
| 107 | 110 | &Self::FILES_REF_LOCK_TIMEOUT, |
| @@ -19,10 +19,10 @@ impl Diff { · 18 unmodified lines | ||
| 19 | 19 | pub const RENAMES: Renames = Renames::new_renames("renames", &config::Tree::DIFF); |
| 20 | 20 | |
| 21 | 21 | /// The `diff.<driver>.command` key. |
| 22 | − pub const DRIVER_COMMAND: keys::String = keys::String::new_string("command", &config::Tree::DIFF) | |
| 22 | + pub const DRIVER_COMMAND: keys::Program = keys::Program::new_program("command", &config::Tree::DIFF) | |
| 23 | 23 | .with_subsection_requirement(Some(SubSectionRequirement::Parameter("driver"))); |
| 24 | 24 | /// The `diff.<driver>.textconv` key. |
| 25 | − pub const DRIVER_TEXTCONV: keys::String = keys::String::new_string("textconv", &config::Tree::DIFF) | |
| 25 | + pub const DRIVER_TEXTCONV: keys::Program = keys::Program::new_program("textconv", &config::Tree::DIFF) | |
| 26 | 26 | .with_subsection_requirement(Some(SubSectionRequirement::Parameter("driver"))); |
| 27 | 27 | /// The `diff.<driver>.algorithm` key. |
| 28 | 28 | pub const DRIVER_ALGORITHM: Algorithm = |
| @@ -95,6 +95,8 @@ · 94 unmodified lines | ||
| 95 | 95 | pub use gix_actor as actor; |
| 96 | 96 | #[cfg(feature = "attributes")] |
| 97 | 97 | pub use gix_attributes as attrs; |
| 98 | +#[cfg(feature = "command")] | |
| 99 | +pub use gix_command as command; | |
| 98 | 100 | pub use gix_commitgraph as commitgraph; |
| 99 | 101 | #[cfg(feature = "credentials")] |
| 100 | 102 | pub use gix_credentials as credentials; |