Files
next.js/turbopack/crates/turbo-tasks-fs/examples/hash_glob.rs
Luke SandbergandGitHub a05035f3c7 Delete some dead turbo task functions (#92596)
Removes a handful of dead code discovered while exploring deletion of the `ValueDefault` trait. That larger change turned out not to be worth it from a binary size perspective, so it was backed out — but the dead code found along the way is worth keeping.

**Removed:**
- `impl ValueDefault for VersionedContentMap` (not tagged with `#[turbo_tasks::value_impl]`, never a turbo-tasks singleton)
- `impl ValueDefault for Body` in `turbopack-dev-server` (same — plain Rust impl, no callers via `Vc::default()`)
- `EmotionTransformConfig::default_private()` and `impl ValueDefault for EmotionTransformConfig` (unused)
- `StyledComponentsTransformConfig::default_private()` and `impl ValueDefault for StyledComponentsTransformConfig` (unused)
- `EmittedEvaluatePoolAssetsWithEffects` struct in `evaluate.rs` (defined but never referenced)
- `OutputAsset::size_bytes()` default trait method (no call sites)

<!-- NEXT_JS_LLM_PR -->
2026-04-11 18:55:18 -07:00

121 lines
3.6 KiB
Rust

#![feature(trivial_bounds)]
#![allow(clippy::needless_return)] // clippy false positive
use std::{
collections::BTreeMap,
env::current_dir,
io::Read,
time::{Duration, Instant},
};
use anyhow::Result;
use sha2::{Digest, Sha256};
use turbo_rcstr::{RcStr, rcstr};
use turbo_tasks::{ReadConsistency, TurboTasks, UpdateInfo, Vc, util::FormatDuration};
use turbo_tasks_backend::{BackendOptions, TurboTasksBackend, noop_backing_storage};
use turbo_tasks_fs::{
DirectoryEntry, DiskFileSystem, FileContent, FileSystem, FileSystemPath, ReadGlobResult,
glob::{Glob, GlobOptions},
};
#[tokio::main]
async fn main() -> Result<()> {
let tt = TurboTasks::new(TurboTasksBackend::new(
BackendOptions::default(),
noop_backing_storage(),
));
let start = Instant::now();
let task = tt.spawn_root_task(|| {
Box::pin(async {
let root = RcStr::from(current_dir().unwrap().to_str().unwrap());
let disk_fs = DiskFileSystem::new(rcstr!("project"), Vc::cell(root));
disk_fs.await?.start_watching(None).await?;
// Smart Pointer cast
let fs: Vc<Box<dyn FileSystem>> = Vc::upcast(disk_fs);
let input = fs.root().await?.join("crates")?;
let glob = Glob::new(rcstr!("**/*.rs"), GlobOptions::default());
let glob_result = input.read_glob(glob);
let dir_hash = hash_glob_result(glob_result);
print_hash(dir_hash).await?;
Ok::<Vc<()>, _>(Default::default())
})
});
tt.wait_task_completion(task, ReadConsistency::Strong)
.await
.unwrap();
println!("done in {}", FormatDuration(start.elapsed()));
loop {
let UpdateInfo {
duration, tasks, ..
} = tt
.get_or_wait_aggregated_update_info(Duration::from_millis(100))
.await;
println!("updated {} tasks in {}", tasks, FormatDuration(duration));
}
}
#[turbo_tasks::function]
pub fn empty_string() -> Vc<RcStr> {
Vc::cell(Default::default())
}
#[turbo_tasks::function]
async fn print_hash(dir_hash: Vc<RcStr>) -> Result<()> {
println!("DIR HASH: {}", dir_hash.await?.as_str());
Ok(())
}
#[turbo_tasks::function]
async fn hash_glob_result(result: Vc<ReadGlobResult>) -> Result<Vc<RcStr>> {
let result = result.await?;
let mut hashes = BTreeMap::new();
for (name, entry) in result.results.iter() {
if let DirectoryEntry::File(path) = entry {
hashes.insert(name, hash_file(path.clone()).owned().await?);
}
}
for (name, result) in result.inner.iter() {
let hash = hash_glob_result(**result).owned().await?;
if !hash.is_empty() {
hashes.insert(name, hash);
}
}
if hashes.is_empty() {
return Ok(empty_string());
}
let hash = hash_content(
&mut hashes
.into_values()
.collect::<Vec<RcStr>>()
.join(",")
.as_bytes(),
);
Ok(hash)
}
#[turbo_tasks::function]
async fn hash_file(file_path: FileSystemPath) -> Result<Vc<RcStr>> {
let content = file_path.read().await?;
Ok(match &*content {
FileContent::Content(file) => hash_content(&mut file.read()),
FileContent::NotFound => {
// report error
Vc::cell(Default::default())
}
})
}
fn hash_content<R: Read>(content: &mut R) -> Vc<RcStr> {
let mut hasher = Sha256::new();
let mut buf = [0; 1024];
while let Ok(size) = content.read(&mut buf) {
hasher.update(&buf[0..size]);
}
let result = format!("{:x}", hasher.finalize());
Vc::cell(result.into())
}