create_walker() — tailwindcss Function Reference
Architecture documentation for the create_walker() function in mod.rs from the tailwindcss codebase.
Entity Profile
Dependency Diagram
graph TD f8682733_9224_5872_cde2_2e9fbb1e34a0["create_walker()"] 4db59ffb_dcea_b3bb_bddb_1c20bbe5b635["new()"] 4db59ffb_dcea_b3bb_bddb_1c20bbe5b635 -->|calls| f8682733_9224_5872_cde2_2e9fbb1e34a0 style f8682733_9224_5872_cde2_2e9fbb1e34a0 fill:#6366f1,stroke:#818cf8,color:#fff
Relationship Graph
Source Code
crates/oxide/src/scanner/mod.rs lines 571–792
fn create_walker(sources: Sources) -> Option<WalkBuilder> {
let mtimes: Arc<Mutex<FxHashMap<PathBuf, SystemTime>>> = Default::default();
let mut other_roots: FxHashSet<&PathBuf> = FxHashSet::default();
let mut first_root: Option<&PathBuf> = None;
let mut ignores: BTreeMap<&PathBuf, BTreeSet<String>> = Default::default();
for source in sources.iter() {
match source {
SourceEntry::Auto { base } => {
if first_root.is_none() {
first_root = Some(base);
} else {
other_roots.insert(base);
}
}
SourceEntry::Pattern { base, pattern } => {
let mut pattern = pattern.to_string();
if first_root.is_none() {
first_root = Some(base);
} else {
other_roots.insert(base);
}
if !pattern.contains("**") {
// Ensure that the pattern is pinned to the base path.
if !pattern.starts_with("/") {
pattern = format!("/{pattern}");
}
// Specific patterns should take precedence even over git-ignored files:
ignores
.entry(base)
.or_default()
.insert(format!("!{}", pattern));
} else {
// Assumption: the pattern we receive will already be brace expanded. So
// `*.{html,jsx}` will result in two separate patterns: `*.html` and `*.jsx`.
if let Some(extension) = Path::new(&pattern).extension() {
// Extend auto source detection to include the extension
ignores
.entry(base)
.or_default()
.insert(format!("!*.{}", extension.to_string_lossy()));
}
}
}
SourceEntry::Ignored { base, pattern } => {
let mut pattern = pattern.to_string();
// Ensure that the pattern is pinned to the base path.
if !pattern.starts_with("/") {
pattern = format!("/{pattern}");
}
ignores.entry(base).or_default().insert(pattern);
}
SourceEntry::External { base } => {
if first_root.is_none() {
first_root = Some(base);
} else {
other_roots.insert(base);
}
// External sources should take precedence even over git-ignored files:
ignores
.entry(base)
.or_default()
.insert(format!("!{}", "/**/*"));
// External sources should still disallow binary extensions:
ignores
.entry(base)
.or_default()
.insert(BINARY_EXTENSIONS_GLOB.clone());
}
}
}
let mut builder = WalkBuilder::new(first_root?);
// We have to follow symlinks
builder.follow_links(true);
// Scan hidden files / directories
builder.hidden(false);
// Don't respect global gitignore files
builder.git_global(false);
// By default, allow .gitignore files to be used regardless of whether or not
// a .git directory is present. This is an optimization for when projects
// are first created and may not be in a git repo yet.
builder.require_git(false);
// If we are in a git repo then require it to ensure that only rules within
// the repo are used. For example, we don't want to consider a .gitignore file
// in the user's home folder if we're in a git repo.
//
// The alternative is using a call like `.parents(false)` but that will
// prevent looking at parent directories for .gitignore files from within
// the repo and that's not what we want.
//
// For example, in a project with this structure:
//
// home
// .gitignore
// my-project
// .gitignore
// apps
// .gitignore
// web
// {root}
//
// We do want to consider all .gitignore files listed:
// - home/.gitignore
// - my-project/.gitignore
// - my-project/apps/.gitignore
//
// However, if a repo is initialized inside my-project then only the following
// make sense for consideration:
// - my-project/.gitignore
// - my-project/apps/.gitignore
//
// Setting the require_git(true) flag conditionally allows us to do this.
for parent in first_root?.ancestors() {
if parent.join(".git").exists() {
builder.require_git(true);
break;
}
}
for root in other_roots {
builder.add(root);
}
// Setup auto source detection rules
for ignore in auto_source_detection::RULES.iter() {
builder.add_gitignore(ignore.clone());
}
// Setup ignores based on `@source` definitions
for (base, patterns) in ignores {
let mut ignore_builder = GitignoreBuilder::new(base);
for pattern in patterns {
ignore_builder.add_line(None, &pattern).unwrap();
}
let ignore = ignore_builder.build().unwrap();
builder.add_gitignore(ignore);
}
builder.filter_entry({
move |entry| {
let path = entry.path();
// Ensure the entries are matching any of the provided source patterns (this is
// necessary for manual-patterns that can filter the file extension)
if path.is_file() {
let mut matches = false;
for source in sources.iter() {
match source {
SourceEntry::Auto { base } | SourceEntry::External { base } => {
if path.starts_with(base) {
matches = true;
break;
}
}
SourceEntry::Pattern { base, pattern } => {
let mut pattern = pattern.to_string();
// Ensure that the pattern is pinned to the base path.
if !pattern.starts_with("/") {
pattern = format!("/{pattern}");
}
// Check if path starts with base, if so, remove the prefix and check the remainder against the pattern
let remainder = path.strip_prefix(base);
if remainder.is_ok_and(|remainder| {
let mut path_str = remainder.to_string_lossy().to_string();
if !path_str.starts_with("/") {
path_str = format!("/{path_str}");
}
glob_match(pattern, path_str.as_bytes())
}) {
matches = true;
break;
}
}
_ => {}
}
}
if !matches {
return false;
}
}
let mut mtimes = mtimes.lock().unwrap();
let current_time = match entry.metadata() {
Ok(metadata) if metadata.is_file() => {
if let Ok(time) = metadata.modified() {
Some(time)
} else {
None
}
}
_ => None,
};
let previous_time =
current_time.and_then(|time| mtimes.insert(entry.clone().into_path(), time));
match (current_time, previous_time) {
(Some(current), Some(prev)) if prev == current => false,
_ => {
event!(tracing::Level::INFO, "Discovering {:?}", path);
true
}
}
}
});
Some(builder)
}
Domain
Subdomains
Called By
Source
Frequently Asked Questions
What does create_walker() do?
create_walker() is a function in the tailwindcss codebase.
What calls create_walker()?
create_walker() is called by 1 function(s): new.
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free