Skip to content

Commit c7295bb

Browse files
authored
feat(gitignore): handle ignoring from workdir root (#1150)
Omni already handles the global gitignore on top of the local gitignore, but when a subdirectory of a workdir is a git repository, the gitignore ends-up being checked from the most specific git repository, and not necessarily the one corresponding to the omni workdir. This fixes that by passing down the workdir root path to be used as git-base, if in a git workdir. Closes #1143
1 parent 7923946 commit c7295bb

File tree

7 files changed

+666
-21
lines changed

7 files changed

+666
-21
lines changed

.omni.yaml

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ up:
88

99
commands:
1010
create-tag:
11+
argparser: true
1112
desc: Create a new version tag for omni
1213
run: |
1314
set -e
@@ -45,6 +46,7 @@ commands:
4546
echo "Created tag: $new_tag"
4647
4748
website-dev:
49+
argparser: true
4850
desc: |
4951
Starts a local development server for the website
5052
@@ -55,6 +57,7 @@ commands:
5557
yarn start
5658
5759
cargo-package:
60+
argparser: true
5861
desc: Runs cargo package after overriding the version
5962
run: |
6063
# Check if git is dirty
@@ -81,6 +84,7 @@ commands:
8184
git checkout Cargo.toml
8285
8386
lint:
87+
argparser: true
8488
desc: Runs the linter
8589
aliases:
8690
- clippy
@@ -89,18 +93,46 @@ commands:
8993
cargo clippy --all-features
9094
9195
test:
92-
desc: Runs the tests
96+
argparser: true
97+
desc: Runs all tests
98+
syntax:
99+
parameters:
100+
- name: --unit
101+
type: flag
102+
desc: Select the unit tests
103+
- name: --integration
104+
type: flag
105+
desc: Select the integration tests
93106
run: |
94107
set -e
95-
cargo test
96-
GENERATE_FIXTURES=false bats tests/
108+
109+
run_unit=${OMNI_ARG_UNIT_VALUE:-false}
110+
run_integration=${OMNI_ARG_INTEGRATION_VALUE:-false}
111+
112+
if [[ "$run_unit" == "false" && "$run_integration" == "false" ]]; then
113+
run_unit=true
114+
run_integration=true
115+
fi
116+
117+
if [[ "$run_unit" == "true" ]]; then
118+
echo >&2 -e "\033[1;34mRunning unit tests...\033[0m"
119+
cargo test
120+
fi
121+
122+
if [[ "$run_integration" == "true" ]]; then
123+
echo >&2 -e "\033[1;34mRunning integration tests...\033[0m"
124+
GENERATE_FIXTURES=false bats tests/
125+
fi
126+
97127
subcommands:
98128
generate:
129+
argparser: true
99130
desc: Generates the fixtures for the tests
100131
run: |
101132
GENERATE_FIXTURES=true bats --filter-tags generate tests/ "$@"
102133
103134
renumber:
135+
argparser: true
104136
desc: Renumber the bats tests
105137
run: |
106138
set -e
@@ -126,6 +158,7 @@ commands:
126158
done
127159
128160
fix:
161+
argparser: true
129162
desc: Fixes the code
130163
run: |
131164
set -e

src/internal/cache/up_environments_test.rs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -465,21 +465,23 @@ mod up_environment {
465465

466466
#[test]
467467
fn test_paths() {
468-
let mut env = UpEnvironment::new();
469-
let data_home_path = PathBuf::from(data_home()).join("test");
470-
let regular_path = PathBuf::from("/usr/local/bin");
468+
run_with_env(&[], || {
469+
let mut env = UpEnvironment::new();
470+
let data_home_path = PathBuf::from(data_home()).join("test");
471+
let regular_path = PathBuf::from("/usr/local/bin");
471472

472-
// Test adding single path
473-
assert!(env.add_path(regular_path.clone()));
474-
assert_eq!(env.paths.len(), 1);
473+
// Test adding single path
474+
assert!(env.add_path(regular_path.clone()));
475+
assert_eq!(env.paths.len(), 1);
475476

476-
// Test data_home path gets prepended
477-
assert!(env.add_path(data_home_path.clone()));
478-
assert_eq!(env.paths[0], data_home_path);
477+
// Test data_home path gets prepended
478+
assert!(env.add_path(data_home_path.clone()));
479+
assert_eq!(env.paths[0], data_home_path);
479480

480-
// Test adding multiple paths
481-
assert!(env.add_paths(vec![PathBuf::from("/path1"), PathBuf::from("/path2")]));
482-
assert_eq!(env.paths.len(), 4);
481+
// Test adding multiple paths
482+
assert!(env.add_paths(vec![PathBuf::from("/path1"), PathBuf::from("/path2")]));
483+
assert_eq!(env.paths.len(), 4);
484+
});
483485
}
484486

485487
#[test]

src/internal/config/up/mise.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ use crate::internal::env::cache_home;
4747
use crate::internal::env::current_dir;
4848
use crate::internal::env::data_home;
4949
use crate::internal::env::state_home;
50-
use crate::internal::git::is_path_gitignored;
50+
use crate::internal::git::is_path_gitignored_from;
5151
use crate::internal::git_env;
5252
use crate::internal::user_interface::StringColor;
5353
use crate::internal::workdir;
@@ -1537,6 +1537,8 @@ impl UpConfigMise {
15371537
detect_version_funcs.push(detect_version_from_tool_version_file);
15381538

15391539
let in_repo = git_env(".").in_repo();
1540+
let wd = workdir(".");
1541+
let wd_root = wd.root();
15401542
for search_dir in search_dirs.iter() {
15411543
// For safety, we remove any leading slashes from the search directory,
15421544
// as we only want to search in the workdir
@@ -1577,7 +1579,9 @@ impl UpConfigMise {
15771579
{
15781580
// Check if the entry is .gitignore'd, we do this now for now as it
15791581
// seems less costly than evaluating all files ahead of time
1580-
if in_repo && matches!(is_path_gitignored(entry.path()), Ok(true)) {
1582+
if in_repo
1583+
&& matches!(is_path_gitignored_from(entry.path(), wd_root), Ok(true))
1584+
{
15811585
continue;
15821586
}
15831587

src/internal/git/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ pub(crate) use utils::format_path_with_template;
88
pub(crate) use utils::full_git_url_parse;
99
pub(crate) use utils::id_from_git_url;
1010
pub(crate) use utils::is_path_gitignored;
11+
pub(crate) use utils::is_path_gitignored_from;
1112
pub(crate) use utils::package_path_from_git_url;
1213
pub(crate) use utils::package_path_from_handle;
1314
pub(crate) use utils::package_root_path;

src/internal/git/utils.rs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,21 +182,28 @@ pub fn path_entry_config<T: AsRef<str>>(path: T) -> PathEntryConfig {
182182
///
183183
/// # Arguments
184184
/// * `file_path` - The path to the file to check
185+
/// * `root` - Optional root directory to be used as the git repository root. If None, the function
186+
/// will search for the repository from the file's directory.
185187
///
186188
/// # Returns
187189
/// * `Ok(bool)` - True if the file is ignored, false otherwise
188190
/// * `Err(Box<dyn Error>)` - If there's an error accessing the repository or the path
189191
///
190192
/// # Example
191193
/// ```rust
192-
/// let is_ignored = is_path_gitignored("src/temp.log")?;
194+
/// let is_ignored = is_path_gitignored_from("src/temp.log", "path/to/repo").unwrap();
193195
/// println!("Is file ignored: {}", is_ignored);
194196
/// ```
195-
pub fn is_path_gitignored<P: AsRef<Path>>(path: P) -> Result<bool, Box<dyn std::error::Error>> {
197+
pub fn is_path_gitignored_from<P1: AsRef<Path>, P2: AsRef<Path>>(
198+
path: P1,
199+
root: Option<P2>,
200+
) -> Result<bool, Box<dyn std::error::Error>> {
196201
let path = path.as_ref();
197202

198203
// Find the directory to start the repository search from
199-
let search_dir = if path.is_dir() {
204+
let search_dir = if let Some(root) = root {
205+
root.as_ref().to_path_buf()
206+
} else if path.is_dir() {
200207
path.to_path_buf()
201208
} else {
202209
// If it's a file or doesn't exist, use its parent directory
@@ -238,3 +245,15 @@ pub fn is_path_gitignored<P: AsRef<Path>>(path: P) -> Result<bool, Box<dyn std::
238245
}
239246
}
240247
}
248+
249+
/// Checks if a given file path is ignored by Git according to .gitignore rules
250+
///
251+
/// This is a convenience wrapper around `is_path_gitignored_from` that does not require
252+
/// a root directory. It will search for the Git repository starting from the file's directory.
253+
pub fn is_path_gitignored<P: AsRef<Path>>(path: P) -> Result<bool, Box<dyn std::error::Error>> {
254+
is_path_gitignored_from(path, None::<&Path>)
255+
}
256+
257+
#[cfg(test)]
258+
#[path = "utils_test.rs"]
259+
mod test;

0 commit comments

Comments
 (0)