fn resolve_targets()

in focus/operations/src/index.rs [64:137]


fn resolve_targets(
    app: Arc<App>,
    sparse_repo_path: &Path,
    targets: HashSet<Target>,
    break_on_missing_keys: bool,
) -> anyhow::Result<Result<ResolveTargetResult, ExitCode>> {
    let dep_keys: HashSet<DependencyKey> = targets
        .iter()
        .map(|target| DependencyKey::from(target.clone()))
        .collect();

    let repo = git2::Repository::open(sparse_repo_path).context("opening sparse repo")?;
    let head_commit = git_helper::get_head_commit(&repo).context("Resolving head commit")?;
    let tree = head_commit.tree().context("Resolving tree")?;
    let ctx = HashContext::new(&repo, &tree)?;
    let odb = RocksDBCache::new(&repo);

    let borrowed_odb = odb.borrow();
    let materialize_result = get_files_to_materialize(&ctx, borrowed_odb, dep_keys.clone())?;
    match materialize_result {
        PathsToMaterializeResult::Ok { seen_keys, paths } => {
            Ok(Ok(ResolveTargetResult { seen_keys, paths }))
        }

        PathsToMaterializeResult::MissingKeys {
            seen_keys: _,
            missing_keys,
        } => {
            println!("Missing keys:");
            for (key, hash) in missing_keys {
                println!("{} {}", hash, dep_key_to_target(&key));
            }

            let repo = Repo::open(repo.path(), app.clone())?;
            let (pattern_count, _checked_out) = repo.sync(
                head_commit.id(),
                &targets,
                true,
                app.clone(),
                Some(borrowed_odb),
                None,
            )?;
            println!("Pattern count: {}", pattern_count);

            match get_files_to_materialize(&ctx, borrowed_odb, dep_keys)? {
                PathsToMaterializeResult::Ok { seen_keys, paths } => Ok(Ok(ResolveTargetResult {
                    seen_keys,
                    paths: paths.into_iter().collect(),
                })),

                PathsToMaterializeResult::MissingKeys {
                    seen_keys: _,
                    missing_keys,
                } => {
                    println!("Keys STILL missing, this is a bug:");
                    for (key, hash) in missing_keys {
                        println!("{} {}", hash, dep_key_to_target(&key));
                    }

                    if break_on_missing_keys {
                        println!("Breaking for debugging...");
                        println!("Sandbox path: {}", app.sandbox().path().display());
                        drop(odb);
                        loop {
                            std::thread::sleep(Duration::from_secs(1));
                        }
                    }

                    Ok(Err(ExitCode(1)))
                }
            }
        }
    }
}